/* Output from p2c 1.21alpha-07.Dec.93, the Pascal-to-C translator */ /* From input file "rawbk.p" */ #include /* rawbk: make a raw sequence into a book Dr. Thomas D. Schneider National Cancer Institute Laboratory of Experimental and Computational Biology Frederick, Maryland 21702-1201 toms@ncifcrf.gov permanent email: toms@alum.mit.edu http://www.lecb.ncifcrf.gov/~toms/ module libraries required: delman, prgmods, delmods */ /* begin module version */ #define version 3.22 /* of rawbk.p 2004 Mar 8 2004 Mar 8 3.22 accept upper case letters. 2000 Feb 18 3.21 upgrade dates 1999 Jan 18 3.20 previous changes origin before 1982 june 26 */ /* end module version */ /* begin module describe.rawbk */ /* name rawbk: make a raw sequence into a book synopsis rawbk(raw: in, rawchanges: out, book: out, input: intty, output: out) files raw: a file with a sequence on it, that is only the letters a,c,g,t, or u, with any spacing and carriage returns. A,C,G,T, and U, are also accepted now. rawchanges: Delila programs cannot handle sequences that have ambiguities because Delila was designed on the assumption that people would finish their sequences. Unfortunately this is not true, and the databases contain bases other than acgt to indicate ambiguity. These are converted to "a" and the cases are reported in this file. NOTE: "u" is converted to "t". book: a file which contains the sequence in the book form such that it will interface with the delila system programs. input: the interactive input from the keyboard. rawbk needs to get some information from the user to name the sequence. output: where error messages will appear. description The purpose of this program is to allow one to rapidly create a book from a raw sequence. rawbk will take a 'raw' sequence and put it into the standard form of a book so that the delila system programs can be used on the sequence. The user is asked for one name, which will become the name of all things in the book (title, organism, chromosome and piece). The program reads thru 'raw', keeping track of characters and lines. It will flag any letters other than 'a','c','g','t', or 'u', that appear in the file and note their locations. it will count the bases. if any characters were flagged, or any other error occurs, rawbk will put 'halt' into the book, in the same form the librarian does, to prevent further use of the book. Otherwise, the book is constructed to contain one piece of sequence. The coordinates begin with base 1. see also dbbk.p, makebk.p, lister.p author Thomas D. Schneider bugs The program should use book writing routines from delmods, but it has not been updated yet. */ /* end module describe.rawbk */ /* begin module interact.const */ /* begin module string.const */ #define maxstring 150 /* the maximum string */ /* end module string.const version = 4.39; (@ of prgmod.p 1999 November 28 */ /* end module interact.const version = 7.62; {of delmod.p 2003 Jan 13} */ /* begin module book.const */ /* constants needed for book manipulations */ #define dnamax 1024 /* length of dna arrays */ #define namelength 100 /* maximum key name length */ #define linelength 80 /* maximum line readable in book */ /* end module book.const version = 7.62; {of delmod.p 2003 Jan 13} */ /* begin module datetime.const */ #define datetimearraylength 19 /* length of dataarray for dates, It is just long enough to include the 4 digit year - solving the year 2000 problem: 1980/06/09 18:49:11 123456789 123456789 1 2 */ /* end module datetime.const version = 'cdatemod.p 1.19 1999Dec13'; */ /* begin module datetime.type */ /* array for dates */ typedef Char datetimearray[datetimearraylength]; /* end module datetime.type version = 'cdatemod.p 1.19 1999Dec13'; */ /* begin module interact.type */ /* begin module string.type */ /* pointer to a string */ typedef struct string { /* a string of characters */ Char letters[maxstring]; /* the letters in the string */ long length; /* the number of characters in the string */ long current; /* the letter we are working on */ Char *next; /* the next string in a series */ } string; /* end module string.type version = 4.39; (@ of prgmod.p 1999 November 28 */ /* end module interact.type version = 7.62; {of delmod.p 2003 Jan 13} */ /* begin module book.type */ /* types needed for book manipulations */ typedef long chset[5]; /* types defined in book definition */ typedef Char alpha[namelength]; /* this is not alfa */ /* name is a left justified string with blanks following the characters */ typedef struct name { alpha letters; /* zero means an unspecified structure */ char length; } name; typedef struct line { /* a line of characters */ Char letters[linelength]; char length; struct line *next; } line; typedef enum { plus, minus, dircomplement, dirhomologous } direction; typedef enum { linear, circular } configuration; typedef enum { on, off } state; typedef struct header { /* header of key */ name keynam; /* key name of structure */ line *fulnam; /* full name of structure */ /* note key */ line *note; } header; /* begin module base.type */ /* define the four nucleotide bases */ typedef enum { a, c, g, t } base; /* end module base.type version = 7.62; {of delmod.p 2003 Jan 13} */ /* sequence types */ typedef short dnarange; /* p2c: rawbk.p, line 162: * Note: Field width for seq assumes enum base has 4 elements [105] */ typedef uchar seq[(dnamax + 3) / 4]; typedef struct dnastring { seq part; dnarange length; struct dnastring *next; } dnastring; typedef struct orgkey { /* organism key */ header hea; /* genetic map units */ line *mapunit; } orgkey; typedef struct chrkey { /* chromosome key */ header hea; double mapbeg; /* number of genetic map beginning */ /* number of genetic map ending */ double mapend; } chrkey; typedef struct piekey { /* piece key */ header hea; double mapbeg; /* genetic map beginning */ configuration coocon; /* configruation (circular/linear) */ direction coodir; /* direction (+/-) relative to genetic map */ long coobeg; /* beginning nucleotide */ long cooend; /* ending nucleotide */ configuration piecon; /* configruation (circular/linear) */ direction piedir; /* direction (+/-) relative to coordinates */ long piebeg; /* beginning nucleotide */ long pieend; /* ending nucleotide */ } piekey; typedef struct piece { piekey key; dnastring *dna; } piece; typedef struct reference { name pienam; /* name of piece referred to */ double mapbeg; /* genetic map beginning */ direction refdir; /* direction relative to coordinates */ long refbeg; /* beginning nucleotide */ long refend; /* ending nucleotide */ } reference; typedef struct genkey { /* gene key */ header hea; reference ref; } genkey; typedef struct trakey { /* transcript key */ header hea; reference ref; } trakey; typedef struct markey { /* marker key */ header hea; reference ref; state sta; line *phenotype; struct marker *next; } markey; typedef struct marker { markey key; dnastring *dna; } marker; /* end module book.type version = 7.62; {of delmod.p 2003 Jan 13} */ Static _TEXT raw; /* the raw sequence */ Static _TEXT rawchanges; /* changes */ /* the book made from raw */ Static _TEXT book; Static long length_; /* of the sequence */ Static boolean error; /* true if raw is bad in some way */ Static alpha thename; /* the name of the seqeuence */ /* begin module getdatetime */ Static Void getdatetime(adatetime) Char *adatetime; { /* Get the date and time into a single array from the system clock. adatetime contains the date: 1980/06/09 18:49:11 ye mo da ho mi se (year, month, day, hour, minute, second) This version works after translation of the pascal by p2c to C and then compiling with gcc. */ Char adate[11], atime[11]; /* adate, atime: alfa; (* ie, packed array[1..10] of char; *) This old method won't work, since the last digit gets cut off! */ Char month[3]; long index; /* index for times */ /* 1 12345678901 adate[13-DEC-1999] atime[17:39:44.00] */ VAXdate(adate); VAXtime(atime); /* writeln(output,'br: adate[',adate,'] atime[',atime,']'); */ /* transfer the year */ for (index = 1; index <= 4; index++) adatetime[index-1] = adate[index+6]; adatetime[4] = '/'; for (index = 4; index <= 6; index++) month[index-4] = adate[index-1]; if (!strncmp(month, "JAN", 3)) { adatetime[5] = '0'; adatetime[6] = '1'; } else if (!strncmp(month, "FEB", 3)) { adatetime[5] = '0'; adatetime[6] = '2'; } else if (!strncmp(month, "MAR", 3)) { adatetime[5] = '0'; adatetime[6] = '3'; } else if (!strncmp(month, "APR", 3)) { adatetime[5] = '0'; adatetime[6] = '4'; } else if (!strncmp(month, "MAY", 3)) { adatetime[5] = '0'; adatetime[6] = '5'; } else if (!strncmp(month, "JUN", 3)) { adatetime[5] = '0'; adatetime[6] = '6'; } else if (!strncmp(month, "JUL", 3)) { adatetime[5] = '0'; adatetime[6] = '7'; } else if (!strncmp(month, "AUG", 3)) { adatetime[5] = '0'; adatetime[6] = '8'; } else if (!strncmp(month, "SEP", 3)) { adatetime[5] = '0'; adatetime[6] = '9'; } else if (!strncmp(month, "OCT", 3)) { adatetime[5] = '1'; adatetime[6] = '0'; } else if (!strncmp(month, "NOV", 3)) { adatetime[5] = '1'; adatetime[6] = '1'; } else if (!strncmp(month, "DEC", 3)) { adatetime[5] = '1'; adatetime[6] = '2'; } adatetime[7] = '/'; for (index = 7; index <= 8; index++) adatetime[index+1] = adate[index-7]; /* replace blanks with spaces in dates */ if (adatetime[5] == ' ') adatetime[5] = '0'; if (adatetime[8] == ' ') adatetime[8] = '0'; adatetime[10] = ' '; for (index = 10; index <= 17; index++) adatetime[index+1] = atime[index-10]; for (index = 19; index <= datetimearraylength + 1; index++) adatetime[index] = ' '; } /* end module getdatetime version = 'cdatemod.p 1.19 1999Dec13'; */ /* begin module writedatetime */ Static Void writedatetime(thefile, adatetime) _TEXT *thefile; Char *adatetime; { /* expand the date and time out and print in the file */ long index; /* index of datetime */ for (index = 0; index < datetimearraylength; index++) putc(adatetime[index], thefile->f); } /* end module writedatetime version = 'cdatemod.p 1.19 1999Dec13'; */ /* begin module package.interact */ /* ************************************************************************ */ /* begin module interact.prompt */ Static Void prompt(afile) _TEXT *afile; { /* prompt a file. the prompt is sent to the output file, and a line is read into the pascal line buffer. (for the cyber system this means to readln afile.) guarantee no bomb */ if (BUFEOF(afile->f)) { if (*afile->name != '\0') { if (afile->f != NULL) afile->f = freopen(afile->name, "r", afile->f); else afile->f = fopen(afile->name, "r"); } else rewind(afile->f); if (afile->f == NULL) _EscIO2(FileNotFound, afile->name); RESETBUF(afile->f, Char); } fscanf(afile->f, "%*[^\n]"); getc(afile->f); } /* prompt */ /* end module interact.prompt version = 4.59; (@ of prgmod.p 2003 Jul 31 */ /* begin module interact.readchar */ Static Void readchar(afile, ch) _TEXT *afile; Char *ch; { /* read a character from afile, guarantee no bomb */ if (BUFEOF(afile->f)) prompt(afile); *ch = getc(afile->f); /*writeln(output,'"',ch,'"') */ if (*ch == '\n') *ch = ' '; } /* readchar */ /* end module interact.readchar version = 4.59; (@ of prgmod.p 2003 Jul 31 */ /* begin module clearstring */ Static Void clearstring(ribbon) string *ribbon; { /* empty the string */ long index; /* to the ribbon */ for (index = 0; index < maxstring; index++) ribbon->letters[index] = ' '; ribbon->length = 0; ribbon->current = 0; } /* clearstring */ Static Void initializestring(ribbon) string *ribbon; { /* start the string with a nil pointer. This routine should be called before doing linked list work. This allows the standard string routines to clear the string without killing the pointer. */ clearstring(ribbon); ribbon->next = NULL; } /* initializestring */ /* end module clearstring version = 4.59; (@ of prgmod.p 2003 Jul 31 */ /* begin module interact.readstring */ Static Void readstring(afile, line_) _TEXT *afile; string *line_; { /* read in a string from afile, protect against bombing */ long index; /* for line */ Char cha; /* a character read in */ boolean done; /* used for removing trailing blanks from the line */ boolean acceptable; /* was the line typed short enough? */ do { clearstring(line_); prompt(afile); index = 0; /* we now count characters */ while (!P_eoln(afile->f) && index < maxstring) { index++; readchar(afile, &cha); line_->letters[index-1] = cha; } if (!P_eoln(afile->f)) { printf("type lines shorter than %ld characters. please retype the line...\n", maxstring + 1L); acceptable = false; } else acceptable = true; } while (!acceptable); line_->length = index; if (line_->length > 0) { done = false; do { /* remove blanks from the line. note that a while loop can not be used because one must avoid letters[0], since that position does not exist... */ if (line_->letters[line_->length - 1] == ' ') line_->length--; else done = true; if (line_->length == 0) done = true; } while (!done); } if (line_->length > 0) line_->current = 1; else line_->current = 0; } /* readstring */ /* Local variables for figurestring: */ struct LOC_figurestring { string *line_; long power; /* of 10 representing a place value in the number */ } ; Local long figureinteger(first, last, LINK) long first, last; struct LOC_figurestring *LINK; { /* figure the integer in the token */ long i; /* index */ long sum = 0; long increment; LINK->power = 1; /* start at ones place */ /* start sum at zero */ for (i = last - 1; i >= first - 1; i--) { switch (LINK->line_->letters[i]) { case '0': increment = 0; break; case '1': increment = 1; break; case '2': increment = 2; break; case '3': increment = 3; break; case '4': increment = 4; break; case '5': increment = 5; break; case '6': increment = 6; break; case '7': increment = 7; break; case '8': increment = 8; break; case '9': increment = 9; break; } sum += LINK->power * increment; LINK->power *= 10; } return sum; } /* figureinteger */ /* end module interact.readstring version = 4.59; (@ of prgmod.p 2003 Jul 31 */ /* begin module interact.figurestring */ Static Void figurestring(line__, first, last, whzat, c_, i, r) string *line__; long *first, *last; Char *whzat, *c_; long *i; double *r; { /* a string of characters to figure out */ /* first found non-blank character in the line */ /* last character before a blank after first */ /* what the token is */ /* the first character of the token */ /* integer value of token if it is integer; or 0 */ /* the real value if it is real; or 0.0 */ /* figurestring figures out the tokens in a string. it recognizes words, integers, reals and poorly formed numbers. you can easily use it to parse lines. our goal is to figure out what thing is on a string. start looking at the current place on the line. first and last are the first 'token' in line after start. the current place is updated to the letter after last. the thing found is described by the value of whzat: 'c': character (when the token does not begin with a digit, '+', or '-') 'i': integer 'r': real ' ': blank line 'g': garbage, cannot figure it out and the value of the thing found is the appropriate variable */ struct LOC_figurestring V; long numbers[3]; long sign; /* sign of a number */ long numberstart; /* the point a number starts, beyond its sign, if any */ long point = 0; /* location of decimal point */ long l; /* an index for dissecting numbers */ string *WITH; long FORLIM; V.line_ = line__; P_addset(P_expset(numbers, 0L), '0'); P_addset(numbers, '1'); P_addset(numbers, '2'); P_addset(numbers, '3'); P_addset(numbers, '4'); P_addset(numbers, '5'); P_addset(numbers, '6'); P_addset(numbers, '7'); P_addset(numbers, '8'); P_addset(numbers, '9'); /* c:=' '; i:=0; r:=0.0; do not affect these variables unless necessary */ *whzat = '.'; /* assume that we have someting to work on */ /* now to see if that is true: */ WITH = V.line_; if (WITH->length == 0 || WITH->current < 1 || WITH->current > WITH->length) *whzat = ' '; else { /* figure out where the first token is in the line */ *first = V.line_->current; while (V.line_->letters[*first - 1] == ' ' && *first < V.line_->length) (*first)++; if (*first == V.line_->length && V.line_->letters[*first - 1] == ' ') *whzat = ' '; } if (*whzat == ' ') return; *last = *first; while (V.line_->letters[*last - 1] != ' ' && *last < V.line_->length) (*last)++; if (V.line_->letters[*last - 1] == ' ') (*last)--; /* the token is between inclusive first and last */ *c_ = V.line_->letters[*first - 1]; if (P_inset(*c_, numbers) || *c_ == '-' || *c_ == '+') { if (*c_ == '-' || *c_ == '+') { switch (*c_) { case '+': sign = 1; break; case '-': sign = -1; break; } numberstart = *first + 1; } else { sign = 1; numberstart = *first; } *whzat = 'i'; FORLIM = *last; for (l = numberstart; l <= FORLIM; l++) { if (!P_inset(V.line_->letters[l-1], numbers)) { if (V.line_->letters[l-1] == '.') { /* we found a period */ if (*whzat == 'i') { /* if so far it is numbers */ *whzat = 'r'; /* it is actually real */ point = l; } else *whzat = 'g'; /* it is a second '.', ie garbage */ } else *whzat = 'g'; /* it is garbage */ } } /* if it is only numbers, it is integer */ /* build number */ /* if it ends in a period, it is integer */ if (*whzat == 'r' && point == *last) *whzat = 'i'; if (*whzat == 'i') { if (point == *last) /* had an ending decimal point */ *i = sign * figureinteger(numberstart, *last - 1, &V); else *i = sign * figureinteger(numberstart, *last, &V); *r = *i; } else if (*whzat == 'r') { *i = figureinteger(numberstart, point - 1, &V); *r = sign * (*i + (double)figureinteger(point + 1, *last, &V) / V.power); *i *= sign; } } else *whzat = 'c'; /* move the start to just beyond the last character of the token */ V.line_->current = *last + 1; } /* figurestring */ /* end module interact.figurestring version = 4.59; (@ of prgmod.p 2003 Jul 31 */ /* ************************************************************************ */ /* end module package.interact version = 4.59; (@ of prgmod.p 2003 Jul 31 */ /* begin module skipblanks */ Static Void skipblanks(thefile) _TEXT *thefile; { /* skip over blanks until a non-blank, or end of line, is found */ while ((P_peek(thefile->f) == ' ') & (!P_eoln(thefile->f))) getc(thefile->f); } Static Void skipnonblanks(thefile) _TEXT *thefile; { /* skip over nonblanks until a blank, or end of line, is found */ while ((P_peek(thefile->f) != ' ') & (!P_eoln(thefile->f))) getc(thefile->f); } Static Void skipcolumn(thefile) _TEXT *thefile; { /* skip over a data column */ skipblanks(thefile); skipnonblanks(thefile); } /* end module skipblanks version = 7.62; {of delmod.p 2003 Jan 13} */ /* begin module onetoken */ Static Void onetoken(afile, buffer, gotten) _TEXT *afile; string *buffer; boolean *gotten; { /* Get a string from a file not using string calls. This lets one obtain lines from a file without interactive prompts. if end of file is found, gotten is false. */ long index = 0; /* of buffer */ boolean done = false; skipblanks(afile); clearstring(buffer); if (BUFEOF(afile->f)) { *gotten = false; return; } while (!P_eoln(afile->f) && index < maxstring && !done) { index++; buffer->letters[index-1] = getc(afile->f); if (buffer->letters[index-1] == '\n') buffer->letters[index-1] = ' '; if (buffer->letters[index-1] == ' ') { done = true; index--; } } buffer->length = index; buffer->current = 1; *gotten = true; } /* end module onetoken version = 4.59; (@ of prgmod.p 2003 Jul 31 */ /* begin module interact.getstring */ Static Void getstring(afile, buffer, gotten) _TEXT *afile; string *buffer; boolean *gotten; { /* get a line (as a string) from a file not using string calls. this lets one obtain lines from a file without interactive prompts */ long index = 0; /* of buffer */ clearstring(buffer); if (BUFEOF(afile->f)) { *gotten = false; return; } while (!P_eoln(afile->f) && index < maxstring) { index++; buffer->letters[index-1] = getc(afile->f); if (buffer->letters[index-1] == '\n') buffer->letters[index-1] = ' '; } if (!P_eoln(afile->f)) { printf(" getstring: a line exceeds maximum string size (%ld)\n", (long)maxstring); _Escape(0); } buffer->length = index; buffer->current = 1; fscanf(afile->f, "%*[^\n]"); getc(afile->f); *gotten = true; } /* getstring */ /* end module interact.getstring version = 4.59; (@ of prgmod.p 2003 Jul 31 */ /* begin module decapitalize */ Static Char decapitalize(c_) Char c_; { /* convert the character c to lower case */ long n = c_; /* c is the n'th letter of the alphabet */ if (n >= 'A' && n <= 'Z') c_ = _tolower(n); else c_ = (Char)n; return c_; } /* end module decapitalize version = 4.59; (@ of prgmod.p 2003 Jul 31 */ Static Void getname(thename) Char *thename; { /* get thename from the user (interactive) */ /* for figure */ string line_; long first, last; Char whzat, c_; long i; double r; /* i also serves as an index */ boolean done = false; boolean gotten; _TEXT TEMP; printf("type a name for the sequence\n"); do { TEMP.f = stdin; *TEMP.name = '\0'; /* zzz readstring(input,line); */ getstring(&TEMP, &line_, &gotten); if (gotten) { figurestring(&line_, &first, &last, &whzat, &c_, &i, &r); switch (whzat) { case 'c': case 'g': if (last - first <= namelength - 2) { /* use i as an index */ for (i = 0; i < namelength; i++) thename[i] = ' '; for (i = first; i <= last; i++) thename[i - first] = line_.letters[i-1]; done = true; } else printf("use a name shorter than %ld characters\n", (long)namelength); break; case 'i': case 'r': printf("do not type a number\n"); break; case ' ': printf("type a name please\n"); break; } } } while (!done); } Static Void bwritestartline(book) _TEXT *book; { /* write the start of the book line */ fprintf(book->f, "* "); } Static Void writealpha(afile, thename) _TEXT *afile; Char *thename; { /* write out thename with no extra blanks */ long i = 1; while (i < namelength && thename[i-1] != ' ') { putc(thename[i-1], afile->f); i++; } } Static Void bwritealpha(afile, thealpha) _TEXT *afile; Char *thealpha; { bwritestartline(afile); writealpha(afile, thealpha); putc('\n', afile->f); } Static Void title(book, thename) _TEXT *book; Char *thename; { /* make the book title */ datetimearray adatetime; bwritestartline(book); getdatetime(adatetime); writedatetime(book, adatetime); fprintf(book->f, ", "); writedatetime(book, adatetime); fprintf(book->f, ", "); writealpha(book, thename); putc('\n', book->f); } Static Void ocbeg(book, thename, length) _TEXT *book; Char *thename; long length; { /* write organism and chromosome part of the book */ fprintf(book->f, "organism\n"); bwritealpha(book, thename); bwritealpha(book, thename); bwritestartline(book); fprintf(book->f, "bases\n"); fprintf(book->f, "chromosome\n"); bwritealpha(book, thename); bwritealpha(book, thename); bwritestartline(book); fprintf(book->f, "%d\n", 1); bwritestartline(book); fprintf(book->f, "%ld\n", length); } #define dnalinelength 60 /* maximum number of bases per line */ Static Void sequence(raw, book) _TEXT *raw, *book; { /* copy the raw sequence into the book */ long basenumber = 0; /* current number of base */ long charpos = 1; /* current number of bases per line */ Char ch; /* a base */ if (*raw->name != '\0') { if (raw->f != NULL) raw->f = freopen(raw->name, "r", raw->f); else raw->f = fopen(raw->name, "r"); } else rewind(raw->f); if (raw->f == NULL) _EscIO2(FileNotFound, raw->name); RESETBUF(raw->f, Char); bwritestartline(book); while (!BUFEOF(raw->f)) { if (P_eoln(raw->f)) { fscanf(raw->f, "%*[^\n]"); getc(raw->f); continue; } ch = getc(raw->f); if (ch == '\n') ch = ' '; /* if ch in ['a','c','g','t','u'] then begin */ /* accept non acgt characters but alter them */ if (ch == ' ') continue; if (charpos > dnalinelength) { charpos = 1; putc('\n', book->f); bwritestartline(book); } ch = decapitalize(ch); if (ch == 'u') ch = 't'; basenumber++; if (ch != 'u' && ch != 't' && ch != 'g' && ch != 'c' && ch != 'a') { fprintf(rawchanges.f, "@ "); writealpha(&rawchanges, thename); fprintf(rawchanges.f, " %6ld.0 +1 \"", basenumber); writealpha(&rawchanges, thename); fprintf(rawchanges.f, " change:\" \"was %c\"\n", ch); ch = 'a'; /* smash it */ } putc(ch, book->f); charpos++; } putc('\n', book->f); } #undef dnalinelength Static Void p(book, raw, thename, length) _TEXT *book, *raw; Char *thename; long length; { /* write the piece out to the book */ fprintf(book->f, "piece\n"); bwritealpha(book, thename); bwritealpha(book, thename); fprintf(book->f, "note\n"); bwritestartline(book); fprintf(book->f, "# 1\n"); fprintf(book->f, "note\n"); bwritestartline(book); fprintf(book->f, "%d\n", 1); bwritestartline(book); fprintf(book->f, "linear\n"); bwritestartline(book); fprintf(book->f, "+\n"); bwritestartline(book); fprintf(book->f, "%d\n", 1); bwritestartline(book); fprintf(book->f, "%ld\n", length); bwritestartline(book); fprintf(book->f, "linear\n"); bwritestartline(book); fprintf(book->f, "+\n"); bwritestartline(book); fprintf(book->f, "%d\n", 1); bwritestartline(book); fprintf(book->f, "%ld\n", length); fprintf(book->f, "dna\n"); sequence(raw, book); fprintf(book->f, "dna\n"); fprintf(book->f, "piece\n"); } Static Void coend(book) _TEXT *book; { /* write the end of the organism and chromosome out */ fprintf(book->f, "chromosome\n"); fprintf(book->f, "organism\n"); } Static Void check(raw, length, error) _TEXT *raw; long *length; boolean *error; { /* check the raw sequence for non acgtu characters and find its length. errors are noted to output. note: check accepts acgt and u. */ long line_ = 1; long character; /* location in the file */ Char ch; /* a character in raw */ if (*raw->name != '\0') { if (raw->f != NULL) raw->f = freopen(raw->name, "r", raw->f); else raw->f = fopen(raw->name, "r"); } else rewind(raw->f); if (raw->f == NULL) _EscIO2(FileNotFound, raw->name); RESETBUF(raw->f, Char); *length = 0; *error = false; while (!BUFEOF(raw->f)) { character = 0; while (!P_eoln(raw->f)) { ch = getc(raw->f); if (ch == '\n') ch = ' '; character++; if (ch != ' ') (*length)++; ch = decapitalize(ch); if (ch != ' ' && ch != 'u' && ch != 't' && ch != 'g' && ch != 'c' && ch != 'a') { printf(" unacceptable sequence character at line %ld character %ld:\"%c\"\n", line_, character, ch); *error = true; } /* else if (ch <> ' ') then length:=succ(length) */ } fscanf(raw->f, "%*[^\n]"); getc(raw->f); line_++; } if (*length == 0) *error = true; printf(" number of bases: %ld\n", *length); if (*error) { printf(" odd characters in raw file, see rawchanges file\n"); /* if error then writeln(output,' error in raw file, no book made.') */ } } Static Void wreck(book) _TEXT *book; { /* destroy the book: produce the error messages that the librarian uses */ if (*book->name != '\0') { if (book->f != NULL) book->f = freopen(book->name, "w", book->f); else book->f = fopen(book->name, "w"); } else { if (book->f != NULL) rewind(book->f); else book->f = tmpfile(); } if (book->f == NULL) _EscIO2(FileNotFound, book->name); SETUPBUF(book->f, Char); fprintf(book->f, "halt: error in raw sequence\n"); } Static Void build(raw, length, thename, book) _TEXT *raw; long length; Char *thename; _TEXT *book; { /* build a book from the raw sequences of the name and length. note: u is converted to t. */ if (*book->name != '\0') { if (book->f != NULL) book->f = freopen(book->name, "w", book->f); else book->f = fopen(book->name, "w"); } else { if (book->f != NULL) rewind(book->f); else book->f = tmpfile(); } if (book->f == NULL) _EscIO2(FileNotFound, book->name); SETUPBUF(book->f, Char); if (*rawchanges.name != '\0') { if (rawchanges.f != NULL) rawchanges.f = freopen(rawchanges.name, "w", rawchanges.f); else rawchanges.f = fopen(rawchanges.name, "w"); } else { if (rawchanges.f != NULL) rewind(rawchanges.f); else rawchanges.f = tmpfile(); } if (rawchanges.f == NULL) _EscIO2(FileNotFound, rawchanges.name); SETUPBUF(rawchanges.f, Char); if (error) { if (*rawchanges.name != '\0') { if (rawchanges.f != NULL) rawchanges.f = freopen(rawchanges.name, "w", rawchanges.f); else rawchanges.f = fopen(rawchanges.name, "w"); } else { if (rawchanges.f != NULL) rewind(rawchanges.f); else rawchanges.f = tmpfile(); } if (rawchanges.f == NULL) _EscIO2(FileNotFound, rawchanges.name); SETUPBUF(rawchanges.f, Char); fprintf(rawchanges.f, "* version %4.2f of rawbk\n", version); } /* define the changes */ fprintf(rawchanges.f, "define \""); writealpha(&rawchanges, thename); fprintf(rawchanges.f, " change:\" \" \" \"^\" \"^\" 0\n"); /* construct the book */ title(book, thename); ocbeg(book, thename, length); p(book, raw, thename, length); coend(book); } main(argc, argv) int argc; Char *argv[]; { _TEXT TEMP; PASCAL_MAIN(argc, argv); book.f = NULL; strcpy(book.name, "book"); rawchanges.f = NULL; strcpy(rawchanges.name, "rawchanges"); raw.f = NULL; strcpy(raw.name, "raw"); printf(" rawbk %4.2f\n", version); /* check(raw,length,error); if error then wreck(book) else begin getname(thename); build(raw,length,thename,book) end; */ check(&raw, &length_, &error); getname(thename); printf("The name will be \""); TEMP.f = stdout; *TEMP.name = '\0'; writealpha(&TEMP, thename); printf("\".\n"); build(&raw, length_, thename, &book); if (raw.f != NULL) fclose(raw.f); if (rawchanges.f != NULL) fclose(rawchanges.f); if (book.f != NULL) fclose(book.f); exit(EXIT_SUCCESS); } /* rawbk */ /* End. */