staden-lg/src/staden/tagU2.c

707 lines
16 KiB
C

#include "contigEditor.h"
#include <stdio.h>
#include <stdlib.h>
#include "tagUtils.h"
#include "fort.h"
#define COMMENT_HEAD_ID (1)
#define TAG_HEAD_ID (devils_.idbsiz)
int read_tag(tag_id n, tagRecord *t)
{
readtg_(&devils_.idevt,&n,&t->position,&t->length,&t->comment,&t->type.i,&t->next);
return 0;
}
int write_tag(tag_id n, tagRecord t)
{
writtg_(&devils_.idevt,&n,&t.position,&t.length,&t.comment,&t.type.i,&t.next);
return 0;
}
int read_comment(comment_id n, int *cnt, commentStruct *c)
{
readcc_(&devils_.idevc,&n,cnt,&c->next,&c->comment[0],40);
return 0;
}
int write_comment(comment_id n, int cnt, commentStruct c)
{
writcc_(&devils_.idevc,&n,&cnt,&c.next,&c.comment[0],40);
return 0;
}
/* comment interface */
tag_id get_free_tag()
{
tagRecord head;
tagRecord freerec;
tag_id free_id;
(void) read_tag(TAG_HEAD_ID,&head);
if (head.next != 0) {
/*
** if a free slot somewhere, use it
*/
free_id = head.next;
(void) read_tag(free_id,&freerec);
head.next = freerec.next;
(void) write_tag(TAG_HEAD_ID,head);
} else {
/*
** extend comment list file
*/
free_id = ++head.position;
(void) write_tag(TAG_HEAD_ID,head);
(void) write_tag(free_id,freerec);
}
return free_id;
}
void delete_comment (comment_id cp)
{
int dummy;
commentStruct head;
commentStruct freerec;
comment_id free_id;
if (!cp) return;
free_id = cp;
(void) read_comment(free_id,&dummy,&freerec);
while (freerec.next) {
free_id = freerec.next;
(void) read_comment(free_id,&dummy,&freerec);
}
(void) read_comment(COMMENT_HEAD_ID,&dummy,&head);
freerec.next = head.next;
(void) write_comment(free_id,dummy,freerec);
head.next = cp;
(void) write_comment(COMMENT_HEAD_ID,dummy,head);
}
void blank_tag_rec(tag_id t)
/*
** Blank out fields in tag record t
*/
{
tagRecord r;
(void) read_tag(t, &r);
r.position = 0;
r.length = 0;
r.type.i = 0x20202020;
r.comment = 0;
r.next = 0;
(void) write_tag(t, r);
}
void delete_tag_rec(tag_id t)
/*
** remove t from file, discarding comment if necessary
*/
{
tagRecord head;
tagRecord freerec;
(void) read_tag(t,&freerec);
if (freerec.comment)
delete_comment(freerec.comment);
(void) read_tag(TAG_HEAD_ID,&head);
freerec.next = head.next;
(void) write_tag(t,freerec);
head.next = t;
(void) write_tag(TAG_HEAD_ID,head);
}
static comment_id get_free_comment()
{
commentStruct head;
commentStruct freerec;
comment_id free_id;
int count;
(void) read_comment(COMMENT_HEAD_ID,&count,&head);
if (head.next != 0) {
/*
** if a free slot somewhere, use it
*/
free_id = head.next;
(void) read_comment(free_id,&count,&freerec);
head.next = freerec.next;
(void) write_comment(COMMENT_HEAD_ID,count,head);
} else {
/*
** extend comment list file
*/
free_id = ++count;
(void) write_comment(COMMENT_HEAD_ID,free_id,head);
(void) write_comment(free_id,0,freerec);
}
return free_id;
}
comment_id put_comment(char *c)
{
commentStruct com;
comment_id cur,next,this_comment;
size_t clen = strlen(c);
size_t piece;
/* write out first block of COMMENT_LENGTH */
this_comment=cur=get_free_comment();
if (clen>COMMENT_LENGTH)
piece = COMMENT_LENGTH;
else
piece = clen;
{int i; for(i=0;i<COMMENT_LENGTH;i++)com.comment[i]=' ';}
strncpy(com.comment,c,piece);
c+= piece;
clen -= piece;
while (clen > 0) {
next = get_free_comment();
com.next = next;
write_comment(cur,0,com);
cur = next;
if (clen<COMMENT_LENGTH)
piece = clen;
{int i; for(i=0;i<COMMENT_LENGTH;i++)com.comment[i]=' ';}
strncpy(com.comment,c,piece);
c+= piece;
clen -= piece;
}
com.next = 0;
if (piece!=COMMENT_LENGTH)
com.comment[piece]='\0';
write_comment(cur,0,com);
return this_comment;
}
static void add_RD_comment(tag_id t_id, char *comment)
{
tagRecord t;
readtg_(&devils_.idevt,&t_id,&t.position,&t.length,&t.comment,&t.type.i,&t.next);
t.comment = put_comment(comment);
writtg_(&devils_.idevt,&t_id,&t.position,&t.length,&t.comment,&t.type.i,&t.next);
}
static void insert_CUT_tags(tag_id t_id, int pos, int length, char *type, char *comment)
{
tagRecord t,new_t;
tag_id next_id,new_id;
new_t.length = 1;
strncpy(new_t.type.c,type,4);
new_t.comment = put_comment(comment);
readtg_(&devils_.idevt,&t_id,&t.position,&t.length,&t.comment,&t.type.i,&t.next);
next_id = t.next;
new_id = get_free_tag();
new_t.position = pos;
new_t.next = next_id;
writtg_(&devils_.idevt,&new_id,&new_t.position,&new_t.length,&new_t.comment,&new_t.type.i,&new_t.next);
next_id = new_id;
t.next=next_id;
writtg_(&devils_.idevt,&t_id,&t.position,&t.length,&t.comment,&t.type.i,&t.next);
}
static void insert_INS_tags(tag_id t_id, int pos, int length)
{
tagRecord t,new_t;
tag_id next_id,new_id;
int i;
new_t.length = 1;
strncpy(new_t.type.c,TAG_TYPE_INSERT,3);
new_t.type.c[3]='*';
new_t.comment = 0;
readtg_(&devils_.idevt,&t_id,&t.position,&t.length,&t.comment,&t.type.i,&t.next);
next_id = t.next;
for (i=length-1;i>=0;i--) {
new_id = get_free_tag();
new_t.position = pos+i;
new_t.next = next_id;
writtg_(&devils_.idevt,&new_id,&new_t.position,&new_t.length,&new_t.comment,&new_t.type.i,&new_t.next);
next_id = new_id;
}
t.next=next_id;
writtg_(&devils_.idevt,&t_id,&t.position,&t.length,&t.comment,&t.type.i,&t.next);
}
static void myFstr2Cstr(char *Fstr, int_fl Flen,
char *Cstr, int_fl Clen)
/*
Copy the significant characters of a blank padded Fortran string
to a '\0' terminated C string, ignoring excess characters.
This function works if the strings are distinct or coincident, but
not if they overlap in any other way.
*/
{ int_fl FsigLen, i;
/* Find the significant length of Fstr */
FsigLen=Flen;
while ((FsigLen > 0) && (Fstr[FsigLen-1] == ' '))
{ FsigLen--;
}
/* Copy up to (Clen-1) significant characters */
i=0;
while ((i < FsigLen) && (i < (Clen-1)))
{ Cstr[i] = Fstr[i];
i++;
}
Cstr[i] = '\0';
}
/* C version of ENTRD */
void entrd_(int_f *IDEVG,int_f *IDEVT,int_f *IDEVC,char *NAMARC,int_f *NGEL,
int_f *IOK, int_fl l_NAMARC)
{
/*
char NAMFIL[FILE_NAME_LENGTH], MTYPE[4];
char namfil[FILE_NAME_LENGTH+1], mtype[5];
*/
int LENR,LCUT,LENW;
int RCUT;
#define fn_len 100
char fn[fn_len];
#define l_line 100
char line[l_line];
char *result;
char *cutbuff,*cb,*l;
FILE *fp;
/* blank tag rec */
blank_tag_rec((tag_id) *NGEL);
myFstr2Cstr(NAMARC,l_NAMARC,fn,(int_fl)fn_len);
*IOK = 0;
/* don't need this anymore
saveState.idevt = &devils_.idevt;
saveState.idevc = &devils_.idevc;
saveState.idbsiz = &devils_.idbsiz;
*/
/* Enters raw data info into database */
if ( (fp = fopen(fn,"r")) != NULL ) {
result = fgets(line,l_line,fp);
if (result != NULL && line[0] == ';') {
/* process header */
sscanf(line,";%6d%6d%6d%*s\n",&LENR,&LCUT,&LENW);
RCUT = LENR - LCUT - LENW;
add_RD_comment(*NGEL, &line[1]);
result = fgets(line,l_line,fp);
}
if (result != NULL && strlen(line)>1 && strncmp(line,";<",2)==0) {
/* process left cut off */
/* starting with this line we need to read LCUT ditties */
cutbuff = (char *) TAG_MALLOC(LCUT+1);
cb = cutbuff;
while (result!=NULL && strlen(line)>1 && strncmp(line,";<",2)==0){
for(l=&line[2];*l;l++)if(strchr(" \n\t",*l)==NULL)*cb++=*l;
result = fgets(line,l_line,fp);
}
*cb='\0';
insert_CUT_tags(*NGEL, 0, 0, TAG_TYPE_LCUT, cutbuff);
TAG_FREE(cutbuff);
}
if (result != NULL && strlen(line)>1 && strncmp(line,";>",2)==0) {
/* process right cut off */
/* starting with this line we need to read RCUT ditties */
cutbuff = (char *) TAG_MALLOC(RCUT+1);
cb = cutbuff;
while (result != NULL && strlen(line)>1 && strncmp(line,";>",2)==0) {
for(l=&line[2];*l;l++)if(strchr(" \n\t",*l)==NULL)*cb++=*l;
result = fgets(line,l_line,fp);
}
*cb='\0';
insert_CUT_tags(*NGEL, 0, 0, TAG_TYPE_RCUT, cutbuff);
TAG_FREE(cutbuff);
}
fclose(fp);
}
}
int_f freecc_ (int_f *IDEVC)
{
return get_free_comment();
}
void padtag_(int_f *llino_, int_f *k_, int_f *nc_, int_f *lngthg_)
/*
** Play around with tags when auto assembling
*/
{
int seq;
int pos;
int length;
int seq_length;
tagRecord t;
tag_id last,next;
int last_pos;
if (devils_.idevt>0) {
/* fudge */
/* don't need this anymore
saveState.idevt = &devils_.idevt;
saveState.idbsiz = &devils_.idbsiz;
*/
seq = *llino_;
length = *nc_;
if (*lngthg_ < 0) {
seq_length = - *lngthg_;
pos = seq_length - *k_ - *nc_ + 2;
} else {
seq_length = *lngthg_;
pos = *k_;
}
next = seq;
last = 0;
last_pos = 0;
while (next) {
readtg_(&devils_.idevt,&next,&t.position,&t.length,&t.comment,&t.type.i,&t.next);
/*
** Move tags accordingly
*/
if (t.position >= pos)
{
t.position+=length;
writtg_(&devils_.idevt,&next,&t.position,&t.length,&t.comment,&t.type.i,&t.next);
}
else if (t.position + t.length > pos)
{
t.length+=length;
writtg_(&devils_.idevt,&next,&t.position,&t.length,&t.comment,&t.type.i,&t.next);
}
/*
** Insert *INS tags
*/
if (last_pos < pos && t.position >= pos)
/*
** Insert after last `length' tags
*/
insert_INS_tags(last,pos,length);
else if (t.position < pos && t.next==0)
/*
** Insert after next `length' tags
*/
insert_INS_tags(next,pos,length);
last = next;
last_pos = t.position;
next = t.next;
}
}
}
void taggel_(int_f *ngels_, int_f *lngthg_, char *gel_, int_fl gel_length)
{
int_f length = abs(*lngthg_);
int_f one=1;
int_f i,j;
if (*lngthg_ > 0) {
for (i=0,j=1; i<length; i++,j++)
if (gel_[i]=='*')
padtag_(ngels_,&j,&one,lngthg_);
} else {
for (i=length-1,j=length; i>=0; i--,j--)
if (gel_[i]=='*')
padtag_(ngels_,&j,&one,lngthg_);
}
}
void movtag_ (int_f *from, int_f *to )
/*
** Move tag information of gel ``from'' to gel ``to'',
** and perform garbage collection on old gel ``to''
*/
{
tagRecord freerec;
tag_id this,next;
/* don't do anything if tag files aren't open */
if ( devils_.idevc < 0 || devils_.idevt < 0 ) return;
/* Throw away ``to'' tag records */
(void) read_tag((tag_id) *to,&freerec);
if (freerec.comment)
delete_comment(freerec.comment);
next = freerec.next;
while ( next ) {
this = next;
(void) read_tag( this , &freerec );
next = freerec.next;
delete_tag_rec (this);
}
/* copy ``from'' record to ``to'' record */
(void) read_tag((tag_id) *from,&freerec);
(void) write_tag((tag_id) *to,freerec);
/* blank out old tag rec */
blank_tag_rec(*from);
}
char *get_comment(comment_id cp)
{
int dummy;
commentStruct c;
int count;
comment_id nc;
char *com,*comptr;
if (!cp) return NULL;
/* determine how long string is */
count = 1;
nc=cp;
read_comment(nc, &dummy, &c);
while (c.next != 0) {
nc = c.next;
count++;
read_comment(nc, &dummy, &c);
}
com = comptr = (char *)TAG_MALLOC(count * COMMENT_LENGTH+1);
nc=cp;
read_comment(nc, &dummy, &c);
strncpy(com,c.comment,COMMENT_LENGTH); com+=COMMENT_LENGTH;
while (c.next != 0) {
nc = c.next;
count++;
read_comment(nc, &dummy, &c);
strncpy(com,c.comment,COMMENT_LENGTH); com+=COMMENT_LENGTH;
}
*com = '\0';
return comptr;
}
void getext_(int_f *gel, char *cutoff, int_f *lcutoff, int_f *ok,
int_fl l_cutoff)
/*
** Get right cutoff for lowly Fortran Users
*/
{
tagRecord rec;
tag_id next;
(void) read_tag((tag_id) *gel,&rec);
next = rec.next;
while ( next && ! rec.position ) {
(void) read_tag( next , &rec );
next = rec.next;
if (strncmp(rec.type.c,TAG_TYPE_RCUT,4) == 0) {
if (rec.comment) {
char *c;
int i;
/* use this */
c = get_comment(rec.comment);
/* copy to fortran array */
for (i=0; i<*lcutoff && c[i]; i++) cutoff[i] = c[i];
/* set length of returned string */
*lcutoff = i;
for (; i<*lcutoff; i++) cutoff[i] = ' ';
/* rec temporary string space */
TAG_FREE(c);
*ok = 0;
return;
} else {
*ok = 1;
return;
}
}
}
*ok = 1;
}
/*************************************************************/
/** Routines for Rodger's pad shuffling */
/*************************************************************/
static void insert_edit_tag(tag_id t_id, int pos, char base, char *type)
{
tagRecord t,new_t;
tag_id new_id;
/* read previous tag */
readtg_(&devils_.idevt,&t_id,&t.position,&t.length,&t.comment,
&t.type.i,&t.next);
/* set up new record */
strncpy(new_t.type.c,type,3);
new_t.type.c[3]=base;
new_t.length = 1;
new_t.comment = 0;
new_t.position = pos;
new_t.next = t.next;
/* write new record */
new_id = get_free_tag();
writtg_(&devils_.idevt,&new_id,&new_t.position,&new_t.length,&new_t.comment,&new_t.type.i,&new_t.next);
/* update previous tag */
t.next=new_id;
writtg_(&devils_.idevt,&t_id,&t.position,&t.length,&t.comment,&t.type.i,&t.next);
}
void insedt_(int_f *seq_, int_f *pos_, char *base_, int_fl base_l)
/*
** Insert a tag for a base at position pos in gel
*/
{
int seq;
int pos;
char base;
tagRecord t;
tag_id last,next;
if (devils_.idevt>0) {
seq = (int) *seq_;
pos = (int) *pos_;
base = base_[0];
/* skip over header */
last = next = seq;
readtg_(&devils_.idevt,&next,&t.position,&t.length,&t.comment,&t.type.i,&t.next);
next = t.next;
if (next) readtg_(&devils_.idevt,&next,&t.position,&t.length,&t.comment,&t.type.i,&t.next);
/* adjust lengths of all tags staring before pos */
while (next && t.position < pos) {
if (t.position + t.length - 1 >= pos &&
t.type.c[0] != '*') {
t.length++;
writtg_(&devils_.idevt,&next,&t.position,&t.length,&t.comment,&t.type.i,&t.next);
}
last = next;
next = t.next;
if (next) readtg_(&devils_.idevt,&next,&t.position,&t.length,&t.comment,&t.type.i,&t.next);
}
/* insert a tag after last and before next */
insert_edit_tag(last,pos,base,TAG_TYPE_INSERT);
/* shift everything else right */
while (next) {
t.position++;
writtg_(&devils_.idevt,&next,&t.position,&t.length,&t.comment,&t.type.i,&t.next);
next = t.next;
if (next) readtg_(&devils_.idevt,&next,&t.position,&t.length,&t.comment,&t.type.i,&t.next);
}
}
}
void deledt_(int_f *seq_, int_f *pos_, char *base_, int_fl base_l)
/*
** Delete a base at position pos in gel
*/
{
int_f seq;
int_f pos;
char base;
tagRecord t;
tag_id last,next;
if (devils_.idevt>0) {
seq = *seq_;
pos = *pos_;
base = base_[0];
/* skip over header */
last = next = (tag_id)seq;
readtg_(&devils_.idevt,&next,&t.position,&t.length,&t.comment,&t.type.i,&t.next);
next = t.next;
if (next) readtg_(&devils_.idevt,&next,&t.position,&t.length,&t.comment,&t.type.i,&t.next);
/* adjust lengths of all tags staring before pos */
while (next && t.position <= pos) {
if (t.position + t.length - 1 >= pos &&
t.type.c[0] != '*') {
t.length--;
writtg_(&devils_.idevt,&next,&t.position,&t.length,&t.comment,&t.type.i,&t.next);
}
last = next;
next = t.next;
if (next) readtg_(&devils_.idevt,&next,&t.position,&t.length,&t.comment,&t.type.i,&t.next);
}
/* insert a tag after last and before next */
insert_edit_tag(last,pos,base,TAG_TYPE_DELETE);
/* shift everything else right */
while (next) {
t.position--;
writtg_(&devils_.idevt,&next,&t.position,&t.length,&t.comment,&t.type.i,&t.next);
next = t.next;
if (next) readtg_(&devils_.idevt,&next,&t.position,&t.length,&t.comment,&t.type.i,&t.next);
}
}
}