#include #include #include #include #include "global_defs.h" /* * 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 ((indx < seq->offset) || (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 ((indx < seq->offset) && (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; j < width; j++) seq->c_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; j < seq->seqmaxlen; 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) < seq->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; j < one->seqlen; j++) two->c_elem[j] = one->c_elem[j]; for (j = 0; j < one->commentslen; 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_width < len) && (c_elem[shift_width] == '-'); shift_width++) ; for (j = 0; j < len - shift_width; j++) c_elem[j] = c_elem[j + shift_width]; seq->seqlen -= 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; j < seq->seqlen; 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; }