#include #include "global_defs.h" #include /* * Alloc.c * Memory functions for Harvard Genome Laboratory. * Last revised 6/3/91 * * Print error message, and die */ void ErrorOut(code,string) int code; char *string; { if (code == 0) { fprintf(stderr,"Error:%s\n",string); exit(1); } return; } /* * Calloc count*size bytes with memory aligned to size. * Return pointer to new block. */ char *Calloc(count,size) int count,size; /*unsigned count,size;*/ { char *temp; temp = calloc(count,(unsigned)size); if(count*size == 0) fprintf(stderr,"Allocate ZERO blocks?\n"); ErrorOut(temp,"Cannot allocate memory"); return(temp); } /* * Reallocate memory at block, expand to size. * Return pointer to (possibly) new block. */ char *Realloc(block,size) char *block; unsigned size; { char *temp; temp=realloc(block,size); ErrorOut(temp,"Cannot change memory size"); return(temp); } /* * Free block Allocated by Calloc. * Return error code from free(). */ void Cfree(block) char* block; { extern void Warning(); if(block != NULL) { #ifdef SUN4 if(free(block) == 0) Warning("Error in Cfree..."); #endif } /* else Warning("Error in Cfree, NULL block"); */ return; } /* * Print Warning message to stderr. */ void Warning(s) char *s; { fprintf(stderr,"Warning:%s\n",s); return; } /* * Get array element from a sequence structure. The index * is relative to the alignment. */ char GetElem(seq,indx) Sequence *seq; /*Sequence to search*/ int indx; /*Index relative to the global offset*/ { if((indxoffset) || (indx >= seq->offset + seq->seqlen)) return('-'); else return((char)(seq->c_elem[indx-seq->offset])); } /* * Replace the array element at seq[indx] with elem. The index * is relative to the alignment. */ void ReplaceElem(seq,indx,elem) Sequence *seq; /*Sequence */ int indx; /*Position to overwrite (replace) */ unsigned char elem; /*Character to replace with */ { int j; extern char *Calloc(); int width; /* * If no c_elem has been allocated yet... */ /* if(index("abcdefghijklmnopqrstuvwxyz-0123456789",elem)==0) fprintf(stderr,"Warning (ReplaceElem) elem = %c\n",elem); */ width = seq->offset-indx; if(seq->seqlen == 0 && elem != '-') { if(seq->seqmaxlen == 0 || seq->c_elem == NULL) { seq->c_elem = Calloc(4,sizeof(char)); seq->offset = indx; seq->seqmaxlen = 4; } seq->seqlen = 1; seq->c_elem[0] = elem; seq->offset = indx; } /* * If inserting before the c_elem (< offset) */ else if((indxoffset) && (elem!='-')) { seq->seqmaxlen += width; seq->c_elem = Realloc(seq->c_elem,seq->seqmaxlen*sizeof(char)); for(j=seq->seqmaxlen-1;j>=width;j--) seq->c_elem[j] = seq->c_elem[j-width]; for(j=0;jc_elem[j] = '-'; seq->c_elem[0] = elem; seq->seqlen += width; seq->offset = indx; } /* * if inserting after c_elem (indx > offset + seqlen) */ else if((indx>=seq->offset+seq->seqlen) && (elem!='-')) { if(indx-seq->offset >= seq->seqmaxlen) { seq->seqmaxlen = indx-seq->offset+256; seq->c_elem = Realloc(seq->c_elem,seq->seqmaxlen* sizeof(char)); } for(j=seq->seqlen;jseqmaxlen;j++) seq->c_elem[j] = '-'; seq->c_elem[indx-seq->offset] = elem; seq->seqlen = indx-seq->offset+1; } else { if(indx-(seq->offset)>=0 && indx-(seq->offset)seqlen) seq->c_elem[indx-(seq->offset)] = elem; else if(elem!='-') fprintf(stderr,"%c better be a -\n",elem); } return; } /* * InsertElem is a modification of InsertElems, and should be * optimized. s.s.5/6/91 */ int InsertElem(a,b,ch) Sequence *a; /* Sequence */ int b; /*Position to insert BEFORE*/ char ch; /*element to insert */ { char c[2]; c[0]=ch; c[1] = '\0'; return (InsertElems(a,b,c)); } /* * Make a copy of Sequence one, place in Sequence two */ void SeqCopy(one,two) Sequence *one,*two; { int j; *two = *one; if(two->seqmaxlen) two->c_elem = Calloc(one->seqmaxlen,sizeof(char)); if(two->commentsmaxlen) two->comments = Calloc(one->commentsmaxlen,sizeof(char)); for(j=0;jseqlen;j++) two->c_elem[j] = one->c_elem[j]; for(j=0;jcommentslen;j++) two->comments[j] = one->comments[j]; return; } /* * Normalize seq (remove leading indels in the c_elem; */ void SeqNormal(seq) Sequence *seq; { int len,j,shift_width,trailer; char *c_elem; len = seq->seqlen; c_elem = seq->c_elem; if(len == 0) return; for(shift_width=0; (shift_widthseqlen -= shift_width; seq->offset += shift_width; for(trailer=seq->seqlen-1;(c_elem[trailer] =='-' || c_elem[trailer] == '\0') && trailer>=0; trailer--) c_elem[trailer] = '\0'; seq->seqlen = trailer+1; return; } void SeqRev(seq,min,max) Sequence *seq; int min,max; /* SeqRev will reverse a given sequence within a window from min to max (inclusive). The idea is to allow several sequences to be reversed in such a manner as to allow them to remain aligned. BEFORE AFTER min | | max min | |max aaaacccgggttt tttgggcccaaaa aaa-cccg-g ---g-gccc-aaa ----cccgggt --tgggccc */ { int j; char temp1,temp2; extern char GetElem(); extern void ReplaceElem(); for(j=0;j<= (max-min)/2;j++) { temp1 = GetElem(seq,min+j); temp2 = GetElem(seq,max-j); ReplaceElem(seq,min+j,(unsigned char)temp2); ReplaceElem(seq,max-j,(unsigned char)temp1); } seq->direction *= -1; SeqNormal(seq); return; } /* sequence complementing. */ void SeqComp(seq) Sequence *seq; { int j; unsigned char in,out,case_bit; char *c; static int tmatr[16] = {'-','a','c','m','g','r','s','v', 't','w','y','h','k','d','b','n'}; static int matr[128] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x00, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0x01,0x0e,0x02,0x0d,0,0,0x04,0x0b,0,0,0x0c,0,0x03,0x0f,0,0x05,0,0x05,0x06, 0x08,0x08,0x07,0x09,0x00,0x0a,0,0,0,0,0,0,0,0x01,0x0e,0x02,0x0d,0,0,0x04, 0x0b,0,0,0x0c,0,0x03,0x0f,0,0x05,0,0x05,0x06,0x08,0x08,0x07,0x09,0x00,0x0a, 0,0,0,0,0x00,0 }; c = seq->c_elem; for(j=0;jseqlen;j++) { /* * Save Case bit... */ case_bit = c[j] & 32; out = 0; in = matr[c[j]]; if(in&1) out|=8; if(in&2) out|=4; if(in&4) out|=2; if(in&8) out|=1; if(case_bit == 0) c[j] = toupper(tmatr[out]); else c[j] = tmatr[out]; } seq->direction *= -1; seq->strandedness = ( seq->strandedness == 2)?1: ( seq->strandedness == 1)?2: 0; return; }