/* Output from p2c 1.21alpha-07.Dec.93, the Pascal-to-C translator */ /* From input file "makebk.p" */ #include /* makebk: make a book from a file of raw sequences. by Gary Stormo modified by Tom Schneider Dr. Thomas D. Schneider National Cancer Institute Laboratory of Experimental and Computational Biology Molecular Information Theory Group Frederick, Maryland 21702-1201 toms@ncifcrf.gov permanent email: toms@alum.mit.edu (use only if first address fails) http://www.lecb.ncifcrf.gov/~toms/ modules libraries needed: delman, delmods, prgmods */ /* end of program */ /* begin module version */ #define version 2.59 /* of makebk.p 2005 Feb 7 2005 Feb 7, 2.59: allow piece names to be listed in automatic 2005 Jan 19, 2.58: cleanup 2005 Jan 19, 2.57: bug: numberdigit changed, must account for here! 2004 Dec 15, 2.56: cleanup 2004 Dec 15, 2.55: bug: number in book not produced after # symbol 2004 Sep 8, 2.54: upgrade for compiling by gpcc 2002 Nov 1, 2.53: tweek documentation 2000 Jun 29, 2.52: accept lower or upper case sequence 2000 Jun 28, 2.51: upgrade documentation 1999 Dec 13, 2.50: 2yk and delila upgrade 1999 Jul 22: z command allows one to set the zero coordinate 1998 dec 18: allow other characters in book, create changes file. origin before 1983 april 21 */ /* end module version */ /* begin module describe.makebk */ /* name makebk: make a book from a file of sequences. synopsis makebk(sequ: in, book: out, changes: out, output: out, input: intty) files sequ: file of raw sequences, each ending in a '.'; no characters are allowed in this file except the bases (a,c,g,t,u) and period and blank. Characters other than these will be converted to 'a' and the change will be noted in the changes file. The bases can also be in capital letters. book: the output file containing the sequences and the necessary information for it to be a proper book. the user types in the required information after prompts from the program. changes: 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". output: for messages and queries to the user input: interactive input. Type a carriage return to start; this is (unfortunately) ignored. Then the program asks: Is this an insertion module (m), an independent book (b), or an automatically generated book (a, z), using default values? Chose the kind of output you want. An 'a' will give you an automatically generated book, while 'z' will do the same but it will first ask you which base is to be the zero coordinate of each sequence. This allows one to shift the alignment. If you do not chose the automatic route, you will be prompted for all the parts of the book. New as of 2005 Feb 7: In the automatic route, names of pieces may follow the title. On each line: The key name is given. a space is given the rest of the line is the long name. description Makebk takes a file of raw sequences (sequ) separated by periods (.) and converts that into a proper delila book format, getting the required information from the user. The user may also have makebk fill in the piece information automatically, using default values. see also {Another program to convert a single sequence to a Delila book:} rawbk.p {A program to list the contents of your new book:} lister.p {This program evolved as an interactive one, but can be used under Unix as if it had a parameter file. To do this, execute it in this form: makebk <} makebkp {where} makebkp {is an example parameter file that will read all sequences and give a simple title. It consists of three or more lines: this line is ignored. a this line triggers automatic book generation title This is the title name1 first sequence name name2 second sequence name } author Gary Stormo bugs The delila system requires complete sequence. To handle sequences with unknown bases, they are replaced with constant chreplace. technical notes The constant chreplace replaces all unidentified characters in the sequence. */ /* end module describe.makebk */ /* begin module makebk.const */ #define chreplace 'a' /* replaces all unidentified characters */ /* end module makebk.const */ /* 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 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.66; {of delmod.p 2004 Aug 4} */ /* begin module interact.const */ /* begin module string.const */ #define maxstring 2000 /* the maximum string */ /* end module string.const version = 5.11; (@ of prgmod.p 2005 Jan 19 */ /* end module interact.const version = 5.11; (@ of prgmod.p 2005 Jan 19 */ /* begin module datetime.type */ /* array for dates */ typedef Char datetimearray[datetimearraylength]; /* end module datetime.type version = 'cdatemod.p 1.19 1999Dec13'; */ /* 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.66; {of delmod.p 2004 Aug 4} */ /* sequence types */ typedef short dnarange; /* p2c: makebk.p, line 205: * 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.66; {of delmod.p 2004 Aug 4} */ /* 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 = 5.11; (@ of prgmod.p 2005 Jan 19 */ /* end module interact.type version = 5.11; (@ of prgmod.p 2005 Jan 19 */ /* begin module book.var */ /* ************************************************************************ */ /* global variables needed for book manipulations */ /* free storage: */ Static line *freeline; /* unused lines */ Static dnastring *freedna; /* unused dnas */ Static boolean readnumber; /* whether to read a number from the notes, or to read in the notes */ Static long number; /* the number of the item just read */ Static boolean numbered; /* true when the item just read is numbered */ Static boolean skipunnum; /* a control variable to allow skipping of un-numbered items in the book */ /* ************************************************************************ */ /* end module book.var version = 7.66; {of delmod.p 2004 Aug 4} */ Static _TEXT book; /* the output book */ Static _TEXT changes; /* changes for the lister program */ Static _TEXT sequ; /* the file with the dna sequence for the book */ Static long genenum; /* number of genes for this piece */ Static long transnum; /* number of transcripts for this piece */ Static long marknum; /* number of markers for this piece */ Static long index_; /* an index for transnum, genenum and marknum */ Static long i; /* an index */ Static Char ch; /* for reading user response */ Static piece *pie; /* pointer to the piece being used */ Static dnastring *d; /* for calculating piece length */ Static long seqnum; /* the number of the present sequence */ Static long length_; /* of the piece being used */ Static boolean numberpieces; /* true if pieces are to be numbered */ Static boolean truebook; /* true if this is an independent book */ Static boolean autobook; /* true if defaults are used for piece info */ Static boolean orgopen; /* true if we have opened an organism and not closed it */ Static boolean chropen; /* true if a chromosome is open */ Static boolean gotten; /* when a string has been gotten from input */ Static string aline; /* read from input */ Static datetimearray adatetime; /* for dating the book */ Static long zerobase; /* the position that is to be the zero base in the book */ Static jmp_buf _JL1; /* begin module package.primitive */ /* ************************************************************************ */ /* begin module halt */ Static Void halt() { /* stop the program. the procedure performs a goto to the end of the program. you must have a label: label 1; declared, and also the end of the program must have this label: 1: end. examples are in the module libraries. this is the only goto in the delila system. */ printf(" program halt.\n"); longjmp(_JL1, 1); } /* end module halt version = 7.66; {of delmod.p 2004 Aug 4} */ /* begin module copyaline */ Static Void copyaline(fin, fout) _TEXT *fin, *fout; { /* copy a line from file fin to file fout */ while (!P_eoln(fin->f)) { putc(P_peek(fin->f), fout->f); getc(fin->f); } fscanf(fin->f, "%*[^\n]"); getc(fin->f); putc('\n', fout->f); } /* copyaline */ /* end module copyaline version = 7.66; {of delmod.p 2004 Aug 4} */ /* begin module copylines */ Static long copylines(fin, fout, n) _TEXT *fin, *fout; long n; { /* copy n lines of file fin to file fout. the actual number of lines copied is returned. */ long index = 0; /* the current line number */ while (!BUFEOF(fin->f) && index < n) { copyaline(fin, fout); index++; } return index; } /* copylines */ /* end module copylines version = 7.66; {of delmod.p 2004 Aug 4} */ /* ************************************************************************ */ /* end module package.primitive version = 7.66; {of delmod.p 2004 Aug 4} */ /* 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 readdatetime */ Static Void readdatetime(thefile, adatetime) _TEXT *thefile; Char *adatetime; { /* read the date and time from the file */ long index; /* to the udatetime */ /* the following is an unpacked date time array, to avoid reading into a packed array. reading into a packed array is not transportable */ Char udatetime[datetimearraylength]; for (index = 0; index < datetimearraylength; index++) { udatetime[index] = getc(thefile->f); if (udatetime[index] == '\n') udatetime[index] = ' '; } memcpy(adatetime, udatetime, sizeof(datetimearray)); if (adatetime[2] == '/' && adatetime[11] == ':') printf(" old datetime (only 2 year digits) read: %.*s\n", datetimearraylength, adatetime); /* p2c: makebk.p, line 459: Note: * Format for packed-array-of-char will work only if width < length [321] */ /* if (adatetime[3]<>'/') or (adatetime[12]<>':') then begin writeln(output,' bad date time read: ',adatetime:1); halt end; for index:=18 to datetimearraylength do adatetime[index]:=' ' */ } /* end module readdatetime 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 = 5.11; (@ of prgmod.p 2005 Jan 19 */ /* 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 = 5.11; (@ of prgmod.p 2005 Jan 19 */ /* 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; ribbon->next = NULL; } /* 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 = 5.11; (@ of prgmod.p 2005 Jan 19 */ /* 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 = 5.11; (@ of prgmod.p 2005 Jan 19 */ /* 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 */ /* Local variables for nostring: */ struct LOC_nostring { string *buffer; boolean answer; /* the answer returned */ } ; Local Void kill(LINK) struct LOC_nostring *LINK; { /* destroy the line */ LINK->answer = true; /* blood and gore */ /* total death */ clearstring(LINK->buffer); } /* kill */ /* end module interact.figurestring version = 5.11; (@ of prgmod.p 2005 Jan 19 */ /* ************************************************************************ */ /* end module package.interact version = 5.11; (@ of prgmod.p 2005 Jan 19 */ /* begin module package.interact.gets */ /* ************************************************************************ */ /* begin module interact.nostring */ Static boolean nostring(buffer_) string *buffer_; { /* true if there are no characters in the rest of the buffer; false if there are characters. also, if there is no buffer, then buffer.length is set to 0 */ struct LOC_nostring V; string *WITH; V.buffer = buffer_; WITH = V.buffer; if (WITH->length <= 0) { kill(&V); return V.answer; } if (WITH->length < maxstring) { while (WITH->letters[WITH->current - 1] == ' ' && WITH->current < WITH->length) WITH->current++; } if (WITH->current > maxstring) { kill(&V); return V.answer; } if (WITH->letters[WITH->current - 1] == ' ') kill(&V); else V.answer = false; return V.answer; } /* nostring */ /* end module interact.nostring version = 5.11; (@ of prgmod.p 2005 Jan 19 */ /* begin module writestring */ Static Void writestring(tofile, s) _TEXT *tofile; string *s; { /* write the string s to file tofile, no writeln */ long i; /* index to s */ long FORLIM; FORLIM = s->length; for (i = 0; i < FORLIM; i++) putc(s->letters[i], tofile->f); } /* writestring */ /* end module writestring version = 5.11; (@ of prgmod.p 2005 Jan 19 */ /* begin module interact.flagstring */ Static Void flagstring(afile, buffer) _TEXT *afile; string *buffer; { /* flag an error in the buffer at the current place, and clear the buffer */ /* chop off the rest of the buffer */ buffer->length = buffer->current; writestring(afile, buffer); /* show the buffer */ fprintf(afile->f, "? "); clearstring(buffer); } /* flagstring */ /* end module interact.flagstring version = 5.11; (@ of prgmod.p 2005 Jan 19 */ /* begin module interact.getchar */ Static Void getchar_(afile, buffer, cha, gotten) _TEXT *afile; string *buffer; Char *cha; boolean *gotten; { /* get a character from the buffer, or refill the buffer and let the calling program figure out whether the buffer has non blank characters in it. */ /* variables for calling figurestring: */ long first, last; Char what; long int_; double rea; if (buffer->length == 0) { *gotten = false; readstring(afile, buffer); } else { figurestring(buffer, &first, &last, &what, cha, &int_, &rea); *gotten = (what != ' '); } } /* getchar */ /* end module interact.getchar version = 5.11; (@ of prgmod.p 2005 Jan 19 */ /* begin module interact.getinteger */ Static Void getinteger(afile, buffer, int_, gotten) _TEXT *afile; string *buffer; long *int_; boolean *gotten; { /* get the integer int from the buffer or interactive file afile */ /* variables for calling figurestring: */ long first, last; Char what, cha; double rea; _TEXT TEMP; if (buffer->length == 0) { *gotten = false; readstring(afile, buffer); return; } figurestring(buffer, &first, &last, &what, &cha, int_, &rea); if (what == 'i') { *gotten = true; return; } TEMP.f = stdout; *TEMP.name = '\0'; flagstring(&TEMP, buffer); printf(" please type an integer\n"); *gotten = false; } /* getinteger */ /* end module interact.getinteger version = 5.11; (@ of prgmod.p 2005 Jan 19 */ /* begin module interact.getreal */ Static Void getreal(afile, buffer, rea, gotten) _TEXT *afile; string *buffer; double *rea; boolean *gotten; { /* get the real rea from the buffer or interactive file afile integer values are also accepted. */ /* variables for calling figurestring: */ long first, last; Char what, cha; long int_; _TEXT TEMP; if (buffer->length == 0) { *gotten = false; readstring(afile, buffer); } else { figurestring(buffer, &first, &last, &what, &cha, &int_, rea); if (what != 'i' && what != 'r') { TEMP.f = stdout; *TEMP.name = '\0'; flagstring(&TEMP, buffer); printf(" please type a real number\n"); *gotten = false; } else *gotten = true; } /* handle integers */ if (what == 'i') *rea = int_; } /* getreal */ /* end module interact.getreal version = 5.11; (@ of prgmod.p 2005 Jan 19 */ /* begin module interact.token */ Static Void token(buffer, atoken, gotten) string *buffer, *atoken; boolean *gotten; { /* get a token from the buffer */ /* variables for calling figurestring: */ long first, last; Char what, cha; long int_; double rea; long index; /* to the buffer */ figurestring(buffer, &first, &last, &what, &cha, &int_, &rea); if (what == ' ') { *gotten = false; return; } clearstring(atoken); for (index = first; index <= last; index++) atoken->letters[index - first] = buffer->letters[index-1]; atoken->length = last - first + 1; atoken->current = 1; *gotten = true; } /* end module interact.token version = 5.11; (@ of prgmod.p 2005 Jan 19 */ /* begin module interact.gettoken */ Static Void gettoken(afile, buffer, atoken, gotten) _TEXT *afile; string *buffer, *atoken; boolean *gotten; { /* get a token from the buffer or interactive file afile */ if (buffer->length == 0) { *gotten = false; readstring(afile, buffer); } else token(buffer, atoken, gotten); } /* gettoken */ #define ln10 2.30259 /* natural log of 10 - for conversion to log base 10 */ #define epsilon 0.00001 /* a small number to correct log base 10 errors */ /* end module interact.gettoken version = 5.11; (@ of prgmod.p 2005 Jan 19 */ /* ************************************************************************ */ /* end module package.interact.gets version = 5.11; (@ of prgmod.p 2005 Jan 19 */ /* begin module numbersize */ Static long numbersize(n) long n; { /* calculate amount of space to be reserved for the integer n */ long size; /* intermediate result */ if (n == 0) return 1; else { /* account for minus sign */ size = (long)(log((double)labs(n)) / ln10 + epsilon) + 1; /* the 1 is for the last digit */ /* the epsilon assures that we do not lose a place due to roundoff. eg, sometimes log base 10 of 10 would be 0.9999 instead of 1, and we would not do it right... note: this will fail for very large numbers on the order of 1/epsilon. */ if (n < 0) size++; return size; } } /* numbersize */ #undef ln10 #undef epsilon /* Local variables for numberdigit: */ struct LOC_numberdigit { long number, place; /* the exponent of logplace */ long myabsolute; /* the absolute value of number */ Char acharacter; /* the character to be returned */ } ; Local Void digit(LINK) struct LOC_numberdigit *LINK; { /* extract a digit at the place position */ long tenplace; /* ten times place */ long z; /* an intermediate value */ long d; /* the digit extracted */ tenplace = LINK->place * 10; z = LINK->myabsolute - LINK->myabsolute / tenplace * tenplace; if (LINK->place == 1) d = z; else d = z / LINK->place; switch (d) { case 0: LINK->acharacter = '0'; break; case 1: LINK->acharacter = '1'; break; case 2: LINK->acharacter = '2'; break; case 3: LINK->acharacter = '3'; break; case 4: LINK->acharacter = '4'; break; case 5: LINK->acharacter = '5'; break; case 6: LINK->acharacter = '6'; break; case 7: LINK->acharacter = '7'; break; case 8: LINK->acharacter = '8'; break; case 9: LINK->acharacter = '9'; break; } } /* digit */ Local Void sign(LINK) struct LOC_numberdigit *LINK; { /* put a negative sign out or a positive sign */ if (LINK->number < 0) LINK->acharacter = '-'; else LINK->acharacter = '+'; } /* sign */ /* end module numbersize version = 5.11; (@ of prgmod.p 2005 Jan 19 */ /* begin module numberdigit */ Static Char numberdigit(number_, logplace) long number_, logplace; { /* return the digit at the place value ('logplace') position of number. example: numberdigit(13625, 3) = 3 numberdigit(13625, 4) = 1 2000 July 30 'myabsolute' replaced 'absolute', which is apparently a keyword for GPC. The name is kept to keep the code looking similar to its origin. */ struct LOC_numberdigit V; long count; /* used to make place */ V.number = number_; V.place = 1; for (count = 1; count <= logplace; count++) V.place *= 10; if (V.number == 0) { if (V.place == 1) V.acharacter = '0'; else V.acharacter = ' '; return V.acharacter; } V.myabsolute = labs(V.number); if (V.myabsolute < V.place / 10) { V.acharacter = ' '; return V.acharacter; } if (V.myabsolute >= V.place) digit(&V); else sign(&V); return V.acharacter; } /* numberdigit */ /* end module numberdigit version = 5.11; (@ of prgmod.p 2005 Jan 19 */ /* begin module book.basis */ /* procedures needed for book manipulations */ /* get procedures should be used for all linked lists of records */ Static Void getline(l) line **l; { /* obtain a line from the free line list or by making a new one */ if (freeline != NULL) { *l = freeline; freeline = freeline->next; } else *l = (line *)Malloc(sizeof(line)); (*l)->length = 0; (*l)->next = NULL; } Static Void getdna(l) dnastring **l; { if (freedna != NULL) { *l = freedna; freedna = freedna->next; } else *l = (dnastring *)Malloc(sizeof(dnastring)); (*l)->length = 0; (*l)->next = NULL; } /* clear procedures should be called each time the records are no longer needed failure to do this may result in a stack overflow. */ Static Void clearline(l) line **l; { /* return a line to the free line list */ line *lptr; if (*l == NULL) return; lptr = *l; *l = (*l)->next; lptr->next = freeline; freeline = lptr; } Static Void writeline(afile, l, carriagereturn) _TEXT *afile; line *l; boolean carriagereturn; { /* write a line to a file, with carriage return if carriagereturn is true. */ long index; /* index to characters in l */ long FORLIM; FORLIM = l->length; for (index = 0; index < FORLIM; index++) putc(l->letters[index], afile->f); if (carriagereturn) putc('\n', afile->f); } Static Void showfreedna() { /* show the freedna list */ long counter = 0; /* count of freedna list */ dnastring *l; /* pointer into freedna list */ l = freedna; while (l != NULL) { counter++; printf("%ld", counter); printf(", length = %d\n", l->length); /* This is illegal according to gpc because one cannot write a pointer to a text file. It can be unearthed for debugging. write(output, ', pointer id: ',l:1); */ l = l->next; } } Static Void cleardna(l) dnastring **l; { /* clear the dna strutures to the free list */ dnastring *lptr; if (*l == NULL) return; lptr = *l; *l = (*l)->next; lptr->next = freedna; freedna = lptr; } Static Void clearheader(h) header *h; { /* clear the header h (remove lines to free storage) */ clearline(&h->fulnam); while (h->note != NULL) clearline(&h->note); } Static Void clearpiece(p) piece **p; { /* clear the dna of the piece */ while ((*p)->dna != NULL) cleardna(&(*p)->dna); clearheader(&(*p)->key.hea); } Static base chartobase(ch) Char ch; { /* convert a character into a base */ base Result; switch (ch) { case 'a': Result = a; break; case 'c': Result = c; break; case 'g': Result = g; break; case 't': Result = t; break; } return Result; } Static Char basetochar(ba) base ba; { /* convert a base into a character */ Char Result; switch (ba) { case a: Result = 'a'; break; case c: Result = 'c'; break; case g: Result = 'g'; break; case t: Result = 't'; break; } return Result; } Static base complement(ba) base ba; { /* take the complement of ba */ base Result; switch (ba) { case a: Result = t; break; case c: Result = g; break; case g: Result = c; break; case t: Result = a; break; } return Result; } Static Char chomplement(b) Char b; { /* create the character complement of base b. I must be getting hungry! */ return (basetochar(complement(chartobase(b)))); } Static long pietoint(p, pie) long p; piece *pie; { /* p is a coordinate on the piece. we want to transform p into a number from 1 to n: an internal coordinate system for easy manipulation of piece coordinates */ /* Note: the dirhomologous and dircomplement are treated as plus and minus directions, which MIGHT NOT BE RIGHT! */ long i; /* an intermediate value */ piekey *WITH; WITH = &pie->key; switch (WITH->piedir) { case dirhomologous: case plus: if (p >= WITH->piebeg) i = p - WITH->piebeg + 1; else i = p - WITH->coobeg + WITH->cooend - WITH->piebeg + 2; break; case dircomplement: case minus: if (p <= WITH->piebeg) i = WITH->piebeg - p + 1; else i = WITH->cooend - p + WITH->piebeg - WITH->coobeg + 2; break; } return i; } Static long inttopie(i, pie) long i; piece *pie; { /* i is in the range 1 to some maximum. it is an internal coordinate system for the program. we want to do a coordinate transformation to obtain a value in the range of the piece called pie: i=1 corresponds to piebeg and i=its maximum corresponds to pieend */ /* Note: the dirhomologous and dircomplement are treated as plus and minus directions, which MIGHT NOT BE RIGHT! */ long p; /* an intermediate value */ piekey *WITH; WITH = &pie->key; switch (WITH->piedir) { case dirhomologous: case plus: p = WITH->piebeg + i - 1; if (p > WITH->cooend) { if (WITH->coocon == circular) p += WITH->coobeg - WITH->cooend - 1; } break; case dircomplement: case minus: p = WITH->piebeg - i + 1; if (p < WITH->coobeg) { if (WITH->coocon == circular) p += WITH->cooend - WITH->coobeg + 1; } break; } return p; } Static long piecelength(pie) piece *pie; { /* return the length of the dna in pie */ return (pietoint(pie->key.pieend, pie)); } /* end module book.basis version = 7.66; {of delmod.p 2004 Aug 4} */ /* begin module package.bwrite */ /****************************************************************************/ /* this is a package of procedures for writing books, by gary stormo, aug 17, 1982 */ /* begin module book.bwbasics */ Static Void bwstartline(book) _TEXT *book; { /* start a line of output to the book */ fprintf(book->f, "* "); } Static Void bwline(book, l) _TEXT *book; line *l; { /* write a line to the book */ long i, FORLIM; if (l == NULL) return; bwstartline(book); if (l->length != 0) { FORLIM = l->length; for (i = 0; i < FORLIM; i++) putc(l->letters[i], book->f); } putc('\n', book->f); } Static Void bwtext(book, lines) _TEXT *book; line *lines; { /* write a set of lines to the book */ line *l = lines; while (l != NULL) { bwline(book, l); l = l->next; } } Static Void bwnote(book, note) _TEXT *book; line *note; { /* writes the notes pointed to by 'note' to 'book' */ if (note == NULL) return; fprintf(book->f, "note\n"); bwtext(book, note); fprintf(book->f, "note\n"); } Static Void bwnumber(book, num) _TEXT *book; long num; { /* write a number to the book */ bwstartline(book); fprintf(book->f, "%ld\n", num); /* pascal will expand the field as far as needed */ } Static Void bwreanum(book, reanum) _TEXT *book; double reanum; { /* write a real number to the book */ bwstartline(book); fprintf(book->f, "%1.2f\n", reanum); /* pascal will expand the field */ } Static Void bwstate(book, sta) _TEXT *book; state sta; { /* write a state to the book */ bwstartline(book); switch (sta) { case on: fprintf(book->f, "on\n"); break; case off: fprintf(book->f, "off\n"); break; } } Static Void bwname(book, nam) _TEXT *book; name nam; { /* write a name to the book */ long i; bwstartline(book); for (i = 0; i < nam.length; i++) putc(nam.letters[i], book->f); putc('\n', book->f); } Static Void bwdirect(book, direct) _TEXT *book; direction direct; { /* write a direction to the book */ bwstartline(book); switch (direct) { case dirhomologous: case plus: /* handle case, may not be right */ fprintf(book->f, "+\n"); break; case dircomplement: case minus: /* handle case, may not be right */ fprintf(book->f, "-\n"); break; } } Static Void bwconfig(book, config) _TEXT *book; configuration config; { /* write a configuration to the book */ bwstartline(book); switch (config) { case linear: fprintf(book->f, "linear\n"); break; case circular: fprintf(book->f, "circular\n"); break; } } Static Void bwheader(book, hea) _TEXT *book; header hea; { /* write a key header to the book */ bwname(book, hea.keynam); bwline(book, hea.fulnam); bwnote(book, hea.note); } Static Void bworgkey(book, org) _TEXT *book; orgkey org; { /* write the organism key */ bwheader(book, org.hea); bwline(book, org.mapunit); } Static Void bwchrkey(book, chr) _TEXT *book; chrkey chr; { /* write the chromosome key */ bwheader(book, chr.hea); bwreanum(book, chr.mapbeg); bwreanum(book, chr.mapend); } /* end module book.bwbasics version = 7.66; {of delmod.p 2004 Aug 4} */ /* begin module book.bworg */ Static Void bworg(thefile, org, chropen, orgopen) _TEXT *thefile; orgkey org; boolean *chropen, *orgopen; { /* this writes the organism key 'org' to 'thefile', and returns 'orgopen' as true. if there is already a chromosome or organism open they are closed. */ if (*chropen) { fprintf(thefile->f, "chromosome\n"); *chropen = false; } if (*orgopen) fprintf(thefile->f, "organism\n"); fprintf(thefile->f, "organism\n"); bworgkey(thefile, org); *orgopen = true; } /* end module book.bworg version = 7.66; {of delmod.p 2004 Aug 4} */ /* begin module book.bwchr */ Static Void bwchr(thefile, chr, chropen) _TEXT *thefile; chrkey chr; boolean *chropen; { /* write the chromosome key 'chr' to 'thefile' and return chropen as true. if a chromosome is already open it is closed. */ if (*chropen) fprintf(thefile->f, "chromosome\n"); fprintf(thefile->f, "chromosome\n"); bwchrkey(thefile, chr); *chropen = true; } /* end module book.bwchr version = 7.66; {of delmod.p 2004 Aug 4} */ /* begin module book.bwdna */ Static Void bwdna(thefile, d) _TEXT *thefile; dnastring *d; { /* write the dna pointed to by 'd' to 'thefile' */ long i; /* index to the sequence */ long l; /* index to the number of bases on the line */ boolean newline = true; /* true when a new line should be started */ long FORLIM; fprintf(thefile->f, "dna\n"); while (d != NULL) { FORLIM = d->length; for (i = 1; i <= FORLIM; i++) { if (newline) { bwstartline(thefile); l = 0; newline = false; } fputc(basetochar((base)P_getbits_UB(d->part, i - 1, 1, 3)), thefile->f); l++; if (l % 60 == 0 || i == d->length && d->next == NULL) { /* end of line */ putc('\n', thefile->f); newline = true; } /* p2c: makebk.p, line 1397: * Note: Using % for possibly-negative arguments [317] */ /* last base */ } d = d->next; } if (!newline) /* last base */ putc('\n', thefile->f); fprintf(thefile->f, "dna\n"); } /* end module book.bwdna version = 7.66; {of delmod.p 2004 Aug 4} */ /* begin module book.bwpie */ Static Void bwpie(thefile, pie) _TEXT *thefile; piece *pie; { /* writes the information pointed to by 'pie' to 'thefile' */ fprintf(thefile->f, "piece\n"); bwheader(thefile, pie->key.hea); bwstartline(thefile); fprintf(thefile->f, "%1.2f\n", pie->key.mapbeg); bwstartline(thefile); if (pie->key.coocon == circular) fprintf(thefile->f, "circular\n"); else fprintf(thefile->f, "linear\n"); bwstartline(thefile); if (pie->key.coodir == plus) fprintf(thefile->f, "+\n"); else fprintf(thefile->f, "-\n"); bwstartline(thefile); fprintf(thefile->f, "%ld\n", pie->key.coobeg); bwstartline(thefile); fprintf(thefile->f, "%ld\n", pie->key.cooend); bwstartline(thefile); if (pie->key.piecon == circular) fprintf(thefile->f, "circular\n"); else fprintf(thefile->f, "linear\n"); bwstartline(thefile); if (pie->key.piedir == plus) fprintf(thefile->f, "+\n"); else fprintf(thefile->f, "-\n"); bwstartline(thefile); fprintf(thefile->f, "%ld\n", pie->key.piebeg); bwstartline(thefile); fprintf(thefile->f, "%ld\n", pie->key.pieend); bwdna(thefile, pie->dna); fprintf(thefile->f, "piece\n"); } /* end module book.bwpie version = 7.66; {of delmod.p 2004 Aug 4} */ /* begin module book.bwref */ Static Void bwref(book, ref) _TEXT *book; reference ref; { /* write a key reference to the book */ bwname(book, ref.pienam); bwreanum(book, ref.mapbeg); bwdirect(book, ref.refdir); bwnumber(book, ref.refbeg); bwnumber(book, ref.refend); } /* end module book.bwref version = 7.66; {of delmod.p 2004 Aug 4} */ /* begin module book.bwgen */ Static Void bwgen(thefile, gene) _TEXT *thefile; genkey gene; { /* this proecdure writes to 'thefile' the information in 'gene', properly formatted; */ fprintf(thefile->f, "gene\n"); bwheader(thefile, gene.hea); bwref(thefile, gene.ref); fprintf(thefile->f, "gene\n"); } /* end module book.bwgen version = 7.66; {of delmod.p 2004 Aug 4} */ /* begin module book.bwtra */ Static Void bwtra(thefile, trans) _TEXT *thefile; trakey trans; { /* this proecdure writes to 'thefile' the information in 'trans', properly formatted; */ fprintf(thefile->f, "transcript\n"); bwheader(thefile, trans.hea); bwref(thefile, trans.ref); fprintf(thefile->f, "transcript\n"); } /* end module book.bwtra version = 7.66; {of delmod.p 2004 Aug 4} */ /* begin module book.bwmar */ Static Void bwmar(thefile, mark) _TEXT *thefile; marker mark; { /* this proecdure writes to 'thefile' the information in 'mark', properly formatted; */ long i, FORLIM; fprintf(thefile->f, "marker\n"); bwheader(thefile, mark.key.hea); bwref(thefile, mark.key.ref); bwstate(thefile, mark.key.sta); bwstartline(thefile); FORLIM = mark.key.phenotype->length; for (i = 0; i < FORLIM; i++) putc(mark.key.phenotype->letters[i], thefile->f); putc('\n', thefile->f); bwdna(thefile, mark.dna); fprintf(thefile->f, "marker\n"); } /* end module book.bwmar version = 7.66; {of delmod.p 2004 Aug 4} */ /****************************************************************************/ /* end module package.bwrite version = 7.66; {of delmod.p 2004 Aug 4} */ /* begin module checkcoordinates */ Static long checkcoordinates(piedir, piebeg, pieend, coobeg, cooend) direction piedir; long piebeg, pieend, coobeg, cooend; { /* calculate the length of a piece with the input piecekey values. the function was derived from the standard piecelength and pietoint functions in delmods. */ long length; /* temporary answer */ switch (piedir) { case dirhomologous: case plus: if (pieend >= piebeg) length = pieend - piebeg + 1; else length = pieend - coobeg + cooend - piebeg + 2; break; case dircomplement: case minus: if (pieend <= piebeg) length = piebeg - pieend + 1; else length = cooend - pieend + piebeg - coobeg + 2; break; } return length; } /* checkcoordinates */ /* end module checkcoordinates */ /* 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 = 5.11; (@ of prgmod.p 2005 Jan 19 */ Static Void readseq(thefile, d) _TEXT *thefile; dnastring **d; { /* takes the sequence in 'thefile' and puts it into the dnastring pointed to by 'd'. the input sequence must have no characters other than a,c,g,t,u, period and blank. the period is used to separate different sequences within the file. */ long i = 0; Char ch = ' '; dnastring *newd; /* new dna pointer */ dnastring *lastd; /* pointer to previous dna */ long coordinate = 0; /* coordinate of the base */ seqnum++; getdna(d); newd = *d; while (!BUFEOF(thefile->f) && ch != '.') { if (P_eoln(thefile->f)) { fscanf(thefile->f, "%*[^\n]"); getc(thefile->f); continue; } ch = getc(thefile->f); if (ch == '\n') ch = ' '; if (ch == ' ' || ch == '.') continue; /* if eoln(thefile) then begin writeln(output,'BUBBA'); halt; end; */ coordinate++; i++; if (i > dnamax) { newd->length = dnamax; lastd = newd; getdna(&newd); lastd->next = newd; i = 1; } ch = decapitalize(ch); if (ch != 'u' && ch != 't' && ch != 'g' && ch != 'c' && ch != 'a') { printf("nonbase (%c) found in sequence %ld at %ld", ch, seqnum, coordinate); /* halt; */ printf(": converted to %c and noted in changes file\n", chreplace); /* write the changes */ fprintf(changes.f, "@ "); fprintf(changes.f, "p%ld", seqnum); fprintf(changes.f, " %6ld.0 +1 \"", coordinate); fprintf(changes.f, "change:\" \"was %c", ch); ch = chreplace; /* smash it */ fprintf(changes.f, " is now %c\"\n", ch); } if (ch == 'u') ch = 't'; P_clrbits_B(newd->part, i - 1, 1, 3); P_putbits_UB(newd->part, i - 1, (int)chartobase(ch), 1, 3); } newd->length = i; newd->next = NULL; } /* readseq */ Static Void okstring(thefile, aline) _TEXT *thefile; string *aline; { /* read in and check a line from the user. insist that it be short enough to fit into the line type */ boolean acceptable; /* is this line acceptable? */ do { readstring(thefile, aline); acceptable = (aline->length <= linelength - 2); /* the -2 accounts for the '* ' at the beginning of each line */ if (!acceptable) printf("line too long, please retype\n"); } while (!acceptable); } /* okstring */ Static Void readnotes(thefile, notes) _TEXT *thefile; line **notes; { /* this takes the lines printed to 'thefile' and makes notes from them until a blank line is typed. */ long i; string aline; /* read from input */ line *newline; /* the newline of notes */ line *last; /* last note line in a string of note lines */ _TEXT TEMP; long FORLIM; getline(notes); newline = *notes; printf("write the notes (<= %ld characters per line) terminated by a blank line.\n", linelength - 2L); TEMP.f = stdin; *TEMP.name = '\0'; okstring(&TEMP, &aline); while (aline.length > 0) { newline->length = aline.length; FORLIM = newline->length; for (i = 0; i < FORLIM; i++) newline->letters[i] = aline.letters[i]; okstring(thefile, &aline); last = newline; getline(&newline); last->next = newline; } newline = NULL; clearstring(&aline); } Static Void readname(thefile, keyname) _TEXT *thefile; name *keyname; { /* gets the key name from 'thefile' and puts it into 'keyname' */ long i; string aline; /* from the user input */ string token; /* a name from aline */ boolean acceptable; /* is this name acceptable? */ boolean gotten; /* was a token gotten? */ long FORLIM; do { readstring(thefile, &aline); if (!nostring(&aline)) { gettoken(thefile, &aline, &token, &gotten); acceptable = (token.length <= namelength); if (!acceptable) printf("the name must be no longer than %ld characters. please retype.\n", (long)namelength); else { keyname->length = token.length; FORLIM = keyname->length; for (i = 0; i < FORLIM; i++) keyname->letters[i] = token.letters[i]; } } else { printf("blank lines are not allowed\n"); acceptable = false; } } while (!acceptable); } /* readname */ Static Void readline(thefile, linep) _TEXT *thefile; line **linep; { /* gets a line from 'thefile' and points to it with 'linep' */ long i; string aline; /* from the user input */ boolean acceptable; /* is the line acceptable? */ long FORLIM; do { okstring(thefile, &aline); if (!nostring(&aline)) { (*linep)->length = aline.length; FORLIM = (*linep)->length; for (i = 0; i < FORLIM; i++) (*linep)->letters[i] = aline.letters[i]; acceptable = true; } else { printf("blank lines not allowed\n"); acceptable = false; } } while (!acceptable); } Static Void writepiecoordinates(coord) piekey coord; { /* write the piece coordinates to the user for checking */ printf(" %4.2f", coord.mapbeg); if (coord.coocon == circular) printf(" c"); else printf(" l"); if (coord.coodir == plus) printf(" +"); else printf(" -"); printf(" %ld", coord.coobeg); printf(" %ld", coord.cooend); if (coord.piecon == circular) printf(" c"); else printf(" l"); if (coord.piedir == plus) printf(" +"); else printf(" -"); printf(" %ld", coord.piebeg); printf(" %ld\n", coord.pieend); } Static Void getpieceinfo() { /* gets the information about the sequence from the user */ string aline; /* from the user input */ Char c_; /* the first character on the string */ long i; /* the integer value in the string */ double r; /* the real value in the string */ boolean gotten; /* true when the desired string is gotten */ boolean acceptable; /* true when everything checks out */ /* variables for putting numbers (seqnum) in the piece notes */ line *numbernote; /* the note */ long d; /* index to the number in the note */ piekey *WITH; _TEXT TEMP; long FORLIM; WITH = &pie->key; printf("what is the key name of this piece?\n"); TEMP.f = stdin; *TEMP.name = '\0'; readname(&TEMP, &WITH->hea.keynam); printf("what is the full name of this piece?\n"); getline(&WITH->hea.fulnam); TEMP.f = stdin; *TEMP.name = '\0'; readline(&TEMP, &WITH->hea.fulnam); TEMP.f = stdin; *TEMP.name = '\0'; readnotes(&TEMP, &WITH->hea.note); /* insert a number into the notes */ if (numberpieces) { getline(&numbernote); /* obtain the line */ /* insert the number symbol and a space */ numbernote->letters[0] = '#'; numbernote->letters[1] = ' '; numbernote->length = numbersize(seqnum) - 1; /* length of the number */ FORLIM = numbernote->length; for (d = 1; d <= FORLIM; d++) numbernote->letters[d+1] = numberdigit(seqnum, numbernote->length - d); numbernote->length += 2; /* account for the two extra symbols */ /* string the note into the header */ numbernote->next = WITH->hea.note; WITH->hea.note = numbernote; } do { acceptable = true; clearstring(&aline); do { if (nostring(&aline)) printf("what is the map beginning?\n"); TEMP.f = stdin; *TEMP.name = '\0'; getreal(&TEMP, &aline, &r, &gotten); } while (!gotten); WITH->mapbeg = r; do { if (nostring(&aline)) printf("what is the coordinate configuration? (c/l)\n"); TEMP.f = stdin; *TEMP.name = '\0'; getchar_(&TEMP, &aline, &c_, &gotten); } while (!((c_ == 'l' || c_ == 'c') && gotten)); if (c_ == 'c') WITH->coocon = circular; else WITH->coocon = linear; do { if (nostring(&aline)) printf("what is the coordinate direction? (+/-)\n"); TEMP.f = stdin; *TEMP.name = '\0'; getchar_(&TEMP, &aline, &c_, &gotten); } while (!((c_ == '-' || c_ == '+') && gotten)); if (c_ == '+') WITH->coodir = plus; else WITH->coodir = minus; do { if (nostring(&aline)) printf("what is the coordinate beginning?\n"); TEMP.f = stdin; *TEMP.name = '\0'; getinteger(&TEMP, &aline, &i, &gotten); } while (!gotten); WITH->coobeg = i; do { if (nostring(&aline)) printf("what is the coordinate end?\n"); TEMP.f = stdin; *TEMP.name = '\0'; getinteger(&TEMP, &aline, &i, &gotten); } while (!gotten); WITH->cooend = i; do { if (nostring(&aline)) printf("what is the piece configuration? (c/l)\n"); TEMP.f = stdin; *TEMP.name = '\0'; getchar_(&TEMP, &aline, &c_, &gotten); } while (!((c_ == 'l' || c_ == 'c') && gotten)); if (c_ == 'c') WITH->piecon = circular; else WITH->piecon = linear; do { if (nostring(&aline)) printf("what is the piece direction? (+/-)\n"); TEMP.f = stdin; *TEMP.name = '\0'; getchar_(&TEMP, &aline, &c_, &gotten); } while (!((c_ == '-' || c_ == '+') && gotten)); if (c_ == '+') WITH->piedir = plus; else WITH->piedir = minus; do { if (nostring(&aline)) printf("what is the piece beginning?\n"); TEMP.f = stdin; *TEMP.name = '\0'; getinteger(&TEMP, &aline, &i, &gotten); } while (!gotten); WITH->piebeg = i; do { if (nostring(&aline)) printf("what is the piece end?\n"); TEMP.f = stdin; *TEMP.name = '\0'; getinteger(&TEMP, &aline, &i, &gotten); } while (!gotten); WITH->pieend = i; if (length_ != checkcoordinates(WITH->piedir, WITH->piebeg, WITH->pieend, WITH->coobeg, WITH->cooend)) { acceptable = false; printf("the number of bases (%ld) does not match the coordinates given:\n", length_); writepiecoordinates(pie->key); printf(" retype the coordinates.\n"); } else { do { if (nostring(&aline)) { printf("the piece coordinates are: "); writepiecoordinates(pie->key); printf("do you wish to correct any of these coordinates?\n"); } TEMP.f = stdin; *TEMP.name = '\0'; getchar_(&TEMP, &aline, &c_, &gotten); } while (!((c_ == 'n' || c_ == 'y') && gotten)); if (c_ == 'y') { acceptable = false; } } } while (!acceptable); } Static Void makeorg() { /* get the information about the organism from the user and write to book */ orgkey org; _TEXT TEMP; printf("what is the organism key name?\n"); TEMP.f = stdin; *TEMP.name = '\0'; readname(&TEMP, &org.hea.keynam); printf("what is the organism full name?\n"); getline(&org.hea.fulnam); TEMP.f = stdin; *TEMP.name = '\0'; readline(&TEMP, &org.hea.fulnam); TEMP.f = stdin; *TEMP.name = '\0'; readnotes(&TEMP, &org.hea.note); printf("what are the map units?\n"); getline(&org.mapunit); TEMP.f = stdin; *TEMP.name = '\0'; readline(&TEMP, &org.mapunit); bworg(&book, org, &chropen, &orgopen); clearline(&org.hea.fulnam); clearline(&org.mapunit); while (org.hea.note != NULL) clearline(&org.hea.note); } Static Void makechr() { /* get the chromosome informatin from the user and write to book */ chrkey chr; /* the chromosome key */ string aline; /* from the user */ double r; /* the values of mapbeg and mapend */ boolean gotten; /* true when the values are gotten */ _TEXT TEMP; printf("what is the chromosome key name?\n"); TEMP.f = stdin; *TEMP.name = '\0'; readname(&TEMP, &chr.hea.keynam); printf("what is the chromosome full name?\n"); getline(&chr.hea.fulnam); TEMP.f = stdin; *TEMP.name = '\0'; readline(&TEMP, &chr.hea.fulnam); TEMP.f = stdin; *TEMP.name = '\0'; readnotes(&TEMP, &chr.hea.note); clearstring(&aline); do { if (nostring(&aline)) printf("what is the chromosome map beginning?\n"); TEMP.f = stdin; *TEMP.name = '\0'; getreal(&TEMP, &aline, &r, &gotten); } while (!gotten); chr.mapbeg = r; do { if (nostring(&aline)) printf("what is the chromosome map end?\n"); TEMP.f = stdin; *TEMP.name = '\0'; getreal(&TEMP, &aline, &r, &gotten); } while (!gotten); chr.mapend = r; bwchr(&book, chr, &chropen); clearline(&chr.hea.fulnam); while (chr.hea.note != NULL) clearline(&chr.hea.note); } Static Void writerefcoordinates(coord) reference coord; { /* write the reference coordinates to the user for checking */ printf(" %4.2f", coord.mapbeg); if (coord.refdir == plus) printf(" +"); else printf(" -"); printf(" %ld", coord.refbeg); printf(" %ld\n", coord.refend); } Static Void maketrans() { /* get the transcript information and write it to 'thefile' */ trakey trans; string aline; /* from the user input */ Char c_; /* the first character on the string */ long i; /* the integer value in the string */ double r; /* the real value in the string */ boolean gotten; /* true when the string is gotten */ boolean acceptable; /* true when everything checks out */ _TEXT TEMP; long FORLIM; printf("for transcript %ld\n", index_); printf("what is the transcript key name?\n"); TEMP.f = stdin; *TEMP.name = '\0'; readname(&TEMP, &trans.hea.keynam); printf("what is the transcript full name?\n"); getline(&trans.hea.fulnam); TEMP.f = stdin; *TEMP.name = '\0'; readline(&TEMP, &trans.hea.fulnam); TEMP.f = stdin; *TEMP.name = '\0'; readnotes(&TEMP, &trans.hea.note); trans.ref.pienam.length = pie->key.hea.keynam.length; FORLIM = trans.ref.pienam.length; for (i = 0; i < FORLIM; i++) trans.ref.pienam.letters[i] = pie->key.hea.keynam.letters[i]; do { acceptable = true; clearstring(&aline); do { if (nostring(&aline)) printf("what is the transcript map beginning?\n"); TEMP.f = stdin; *TEMP.name = '\0'; getreal(&TEMP, &aline, &r, &gotten); } while (!gotten); trans.ref.mapbeg = r; do { if (nostring(&aline)) printf("what is the transcript direction? (+/-)\n"); TEMP.f = stdin; *TEMP.name = '\0'; getchar_(&TEMP, &aline, &c_, &gotten); } while (!((c_ == '-' || c_ == '+') && gotten)); if (c_ == '+') trans.ref.refdir = plus; else trans.ref.refdir = minus; do { if (nostring(&aline)) printf("what is the transcript beginning?\n"); TEMP.f = stdin; *TEMP.name = '\0'; getinteger(&TEMP, &aline, &i, &gotten); } while (!gotten); trans.ref.refbeg = i; do { if (nostring(&aline)) printf("what is the transcript end?\n"); TEMP.f = stdin; *TEMP.name = '\0'; getinteger(&TEMP, &aline, &i, &gotten); } while (!gotten); trans.ref.refend = i; do { if (nostring(&aline)) { printf("the transcript coordinates are: "); writerefcoordinates(trans.ref); printf("do you wish to correct any of these coordinates?\n"); } TEMP.f = stdin; *TEMP.name = '\0'; getchar_(&TEMP, &aline, &c_, &gotten); } while (!((c_ == 'n' || c_ == 'y') && gotten)); if (c_ == 'y') acceptable = false; } while (!acceptable); bwtra(&book, trans); clearline(&trans.hea.fulnam); while (trans.hea.note != NULL) clearline(&trans.hea.note); } Static Void makegene() { /* get the gene information and write it to 'thefile' */ genkey gene; string aline; /* from the user input */ Char c_; /* the first character on the string */ long i; /* the integer value in the string */ double r; /* the real value in the string */ boolean gotten; /* true when the string is gotten */ boolean acceptable; /* true when everything checks out */ _TEXT TEMP; long FORLIM; printf("for gene %ld\n", index_); printf("what is the gene key name?\n"); TEMP.f = stdin; *TEMP.name = '\0'; readname(&TEMP, &gene.hea.keynam); printf("what is the gene full name?\n"); getline(&gene.hea.fulnam); TEMP.f = stdin; *TEMP.name = '\0'; readline(&TEMP, &gene.hea.fulnam); TEMP.f = stdin; *TEMP.name = '\0'; readnotes(&TEMP, &gene.hea.note); gene.ref.pienam.length = pie->key.hea.keynam.length; FORLIM = gene.ref.pienam.length; for (i = 0; i < FORLIM; i++) gene.ref.pienam.letters[i] = pie->key.hea.keynam.letters[i]; do { acceptable = true; clearstring(&aline); do { if (nostring(&aline)) printf("what is the gene map beginning?\n"); TEMP.f = stdin; *TEMP.name = '\0'; getreal(&TEMP, &aline, &r, &gotten); } while (!gotten); gene.ref.mapbeg = r; do { if (nostring(&aline)) printf("what is the gene direction? (+/-)\n"); TEMP.f = stdin; *TEMP.name = '\0'; getchar_(&TEMP, &aline, &c_, &gotten); } while (!((c_ == '-' || c_ == '+') && gotten)); if (c_ == '+') gene.ref.refdir = plus; else gene.ref.refdir = minus; do { if (nostring(&aline)) printf("what is the gene beginning?\n"); TEMP.f = stdin; *TEMP.name = '\0'; getinteger(&TEMP, &aline, &i, &gotten); } while (!gotten); gene.ref.refbeg = i; do { if (nostring(&aline)) printf("what is the gene end?\n"); TEMP.f = stdin; *TEMP.name = '\0'; getinteger(&TEMP, &aline, &i, &gotten); } while (!gotten); gene.ref.refend = i; do { if (nostring(&aline)) { printf("the gene coordinates are: "); writerefcoordinates(gene.ref); printf("do you wish to correct any of these coordinates?\n"); } TEMP.f = stdin; *TEMP.name = '\0'; getchar_(&TEMP, &aline, &c_, &gotten); } while (!((c_ == 'n' || c_ == 'y') && gotten)); if (c_ == 'y') acceptable = false; } while (!acceptable); bwgen(&book, gene); clearline(&gene.hea.fulnam); while (gene.hea.note != NULL) clearline(&gene.hea.note); } Static Void makemark() { /* get the marker information and write it to 'thefile' */ /* the dna must be typed without a carriage return and not be longer than dnamax */ marker mark; string token; /* for the marker state */ string aline; /* from the user input */ Char c_; /* the first character on the string */ boolean gotten; /* true when the string is gotten */ boolean acceptable; /* true when everything checks out */ long j, k; /* indicies for reading marker dna */ _TEXT TEMP; long FORLIM; printf("for marker %ld\n", index_); printf("what is the marker key name?\n"); TEMP.f = stdin; *TEMP.name = '\0'; readname(&TEMP, &mark.key.hea.keynam); printf("what is the marker full name?\n"); getline(&mark.key.hea.fulnam); TEMP.f = stdin; *TEMP.name = '\0'; readline(&TEMP, &mark.key.hea.fulnam); TEMP.f = stdin; *TEMP.name = '\0'; readnotes(&TEMP, &mark.key.hea.note); mark.key.ref.pienam.length = pie->key.hea.keynam.length; FORLIM = mark.key.ref.pienam.length; for (j = 0; j < FORLIM; j++) mark.key.ref.pienam.letters[j] = pie->key.hea.keynam.letters[j]; do { acceptable = true; clearstring(&aline); do { if (nostring(&aline)) printf("what is the marker map beginning?\n"); TEMP.f = stdin; *TEMP.name = '\0'; getreal(&TEMP, &aline, &mark.key.ref.mapbeg, &gotten); } while (!gotten); do { if (nostring(&aline)) printf("what is the marker direction? (+/-)\n"); TEMP.f = stdin; *TEMP.name = '\0'; getchar_(&TEMP, &aline, &c_, &gotten); } while (!((c_ == '-' || c_ == '+') && gotten)); if (c_ == '+') mark.key.ref.refdir = plus; else mark.key.ref.refdir = minus; do { if (nostring(&aline)) printf("what is the marker beginning?\n"); TEMP.f = stdin; *TEMP.name = '\0'; getinteger(&TEMP, &aline, &mark.key.ref.refbeg, &gotten); } while (!gotten); do { if (nostring(&aline)) printf("what is the marker end?\n"); TEMP.f = stdin; *TEMP.name = '\0'; getinteger(&TEMP, &aline, &mark.key.ref.refend, &gotten); } while (!gotten); do { if (nostring(&aline)) { printf("the marker coordinates are: "); writerefcoordinates(mark.key.ref); printf("do you wish to correct any of these coordinates?\n"); } TEMP.f = stdin; *TEMP.name = '\0'; getchar_(&TEMP, &aline, &c_, &gotten); } while (!((c_ == 'n' || c_ == 'y') && gotten)); if (c_ == 'y') acceptable = false; } while (!acceptable); do { if (nostring(&aline)) printf("what is the state of the marker? (on/off)\n"); TEMP.f = stdin; *TEMP.name = '\0'; gettoken(&TEMP, &aline, &token, &gotten); } while (!(token.letters[0] == 'o' && (token.letters[1] == 'f' || token.letters[1] == 'n') && gotten)); if (token.letters[1] == 'n') mark.key.sta = on; else mark.key.sta = off; printf("what is the marker phenotype?\n"); getline(&mark.key.phenotype); TEMP.f = stdin; *TEMP.name = '\0'; readline(&TEMP, &mark.key.phenotype); printf("write the marker dna (<= 80 bases per line) terminated by a blank line\n"); getdna(&mark.dna); TEMP.f = stdin; *TEMP.name = '\0'; readstring(&TEMP, &aline); j = 0; while (aline.length > 0) { for (k = 0; k < aline.length; k++) { ch = aline.letters[k]; if (ch != ' ') { if (ch == 't' || ch == 'g' || ch == 'c' || ch == 'a') { j++; P_clrbits_B(mark.dna->part, j - 1, 1, 3); P_putbits_UB(mark.dna->part, j - 1, (int)chartobase(ch), 1, 3); } else { printf("nonbase (%c) found in marker sequence, rewrite entire marker dna\n", ch); j = 0; } } } TEMP.f = stdin; *TEMP.name = '\0'; readstring(&TEMP, &aline); } mark.dna->length = j; bwmar(&book, mark); clearline(&mark.key.hea.fulnam); clearline(&mark.key.phenotype); while (mark.key.hea.note != NULL) clearline(&mark.key.hea.note); cleardna(&mark.dna); } /* These next two procedures, autopiece and autoorgchr, use default values for all the necessary information so the user has to specify nothing */ Static Void autopiece() { /* name the piece by its number and make it linear, + and from 1 to length */ long l; /* the length of a number */ long d; /* an index */ piekey *WITH; name *WITH1; line *WITH2; /* writeln(output,'AUTOPIECE ----------------'); */ if (!P_eof(stdin)) { /* we were on the end of the previous line */ scanf("%*[^\n]"); getchar(); } l = numbersize(seqnum); WITH = &pie->key; if (P_eof(stdin)) { printf(" AUTOMATIC PIECE NAME BEING CREATED: "); printf("piece-%ld\n", seqnum); WITH1 = &WITH->hea.keynam; /* insert a number into the keyname */ WITH1->letters[0] = 'p'; WITH1->letters[1] = 'i'; WITH1->letters[2] = 'e'; WITH1->letters[3] = 'c'; WITH1->letters[4] = 'e'; WITH1->letters[5] = '-'; for (d = 1; d <= l; d++) WITH1->letters[d+5] = numberdigit(seqnum, l - d); WITH1->length = l + 6; /* 2005 Feb 7: TDS: retire the old method of p1, p2 ... renaming these was a pain. letters[1] := 'p'; for d := 1 to l do letters[d + 1] := numberdigit(seqnum, l - d); length := l + 1; (* account for the one extra symbol *) */ /*zzz*/ getline(&WITH->hea.fulnam); WITH2 = WITH->hea.fulnam; /* insert a number into the full name */ WITH2->letters[0] = 'p'; WITH2->letters[1] = 'i'; WITH2->letters[2] = 'e'; WITH2->letters[3] = 'c'; WITH2->letters[4] = 'e'; WITH2->letters[5] = '-'; for (d = 1; d <= l; d++) WITH2->letters[d+5] = numberdigit(seqnum, l - d); WITH2->length = l + 6; WITH2->next = NULL; } else { if (!P_eof(stdin)) { printf(" PIECE KEY NAME: "); WITH1 = &WITH->hea.keynam; /* insert a keyname */ WITH1->length = 0; while ((P_peek(stdin) != ' ') & (!P_eoln(stdin))) { WITH1->length++; WITH1->letters[WITH1->length - 1] = getchar(); if (WITH1->letters[WITH1->length - 1] == '\n') WITH1->letters[WITH1->length - 1] = ' '; putchar(WITH1->letters[WITH1->length - 1]); } putchar('\n'); if (!P_eoln(stdin)) { if (P_peek(stdin) == ' ') getc(stdin); } printf(" PIECE LONG NAME: "); if (!BUFEOF(stdin)) { getline(&WITH->hea.fulnam); WITH2 = WITH->hea.fulnam; /* insert a number into the full name */ WITH2->length = 0; while (!P_eoln(stdin)) { WITH2->length++; WITH2->letters[WITH2->length - 1] = getchar(); if (WITH2->letters[WITH2->length - 1] == '\n') WITH2->letters[WITH2->length - 1] = ' '; putchar(WITH2->letters[WITH2->length - 1]); } putchar('\n'); WITH2->next = NULL; } } } getline(&WITH->hea.note); WITH2 = WITH->hea.note; /* insert a number into the notes */ WITH2->letters[0] = '#'; WITH2->letters[1] = ' '; for (d = 1; d <= l; d++) WITH2->letters[d+1] = numberdigit(seqnum, l - d); WITH2->length = l + 2; WITH2->next = NULL; /* fill in the piece information */ WITH->mapbeg = 0.0; WITH->coocon = linear; WITH->coodir = plus; WITH->coobeg = 1 - zerobase; WITH->cooend = length_ - zerobase; WITH->piecon = linear; WITH->piedir = plus; WITH->piebeg = 1 - zerobase; WITH->pieend = length_ - zerobase; } Static Void autoorgchr() { /* make up names for the organism and chromosome and write them to the book */ orgkey org; /* the organism key */ chrkey chr; /* the chromosome key */ line *WITH; org.hea.keynam.letters[0] = 'o'; org.hea.keynam.letters[1] = 'r'; org.hea.keynam.letters[2] = 'g'; org.hea.keynam.length = 3; getline(&org.hea.fulnam); WITH = org.hea.fulnam; WITH->letters[0] = 'o'; WITH->letters[1] = 'r'; WITH->letters[2] = 'g'; WITH->length = 3; WITH->next = NULL; org.hea.note = NULL; getline(&org.mapunit); WITH = org.mapunit; WITH->letters[0] = 'n'; WITH->letters[1] = 'o'; WITH->letters[2] = 'n'; WITH->letters[3] = 'e'; WITH->length = 4; WITH->next = NULL; bworg(&book, org, &chropen, &orgopen); clearline(&org.hea.fulnam); clearline(&org.mapunit); chr.hea.keynam.letters[0] = 'c'; chr.hea.keynam.letters[1] = 'h'; chr.hea.keynam.letters[2] = 'r'; chr.hea.keynam.length = 3; getline(&chr.hea.fulnam); WITH = chr.hea.fulnam; WITH->letters[0] = 'c'; WITH->letters[1] = 'h'; WITH->letters[2] = 'r'; WITH->length = 3; WITH->next = NULL; chr.hea.note = NULL; chr.mapbeg = 0.0; chr.mapend = 1.0; bwchr(&book, chr, &chropen); clearline(&chr.hea.fulnam); } main(argc, argv) int argc; Char *argv[]; { _TEXT TEMP; long FORLIM; PASCAL_MAIN(argc, argv); if (setjmp(_JL1)) goto _L1; sequ.f = NULL; strcpy(sequ.name, "sequ"); changes.f = NULL; strcpy(changes.name, "changes"); book.f = NULL; strcpy(book.name, "book"); printf(" makebk %4.2f\n", version); /* required initializations */ if (*sequ.name != '\0') { if (sequ.f != NULL) sequ.f = freopen(sequ.name, "r", sequ.f); else sequ.f = fopen(sequ.name, "r"); } else rewind(sequ.f); if (sequ.f == NULL) _EscIO2(FileNotFound, sequ.name); RESETBUF(sequ.f, Char); if (BUFEOF(sequ.f)) { printf(" no sequence file provided\n"); halt(); } 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); pie = (piece *)Malloc(sizeof(piece)); pie->key.hea.fulnam = (line *)Malloc(sizeof(line)); pie->key.hea.note = (line *)Malloc(sizeof(line)); pie->key.hea.note->next = NULL; freeline = NULL; freedna = NULL; orgopen = false; chropen = false; autobook = false; if (*changes.name != '\0') { if (changes.f != NULL) changes.f = freopen(changes.name, "w", changes.f); else changes.f = fopen(changes.name, "w"); } else { if (changes.f != NULL) rewind(changes.f); else changes.f = tmpfile(); } if (changes.f == NULL) _EscIO2(FileNotFound, changes.name); SETUPBUF(changes.f, Char); fprintf(changes.f, "* makebk %4.2f\n", version); fprintf(changes.f, "define \"change:\" \"-\" \"^\" \"^\" 0\n"); do { if (nostring(&aline)) { printf("Is this an insertion module (m), an independent book (b), \n"); printf("or an automatically generated book (a, z), using default values?\n"); printf("(TYPE CARRIAGE RETURN AND THEN YOUR RESPONSE)\n"); } TEMP.f = stdin; *TEMP.name = '\0'; getchar_(&TEMP, &aline, &ch, &gotten); } while (!((ch == 'z' || ch == 'a' || ch == 'b' || ch == 'm') && gotten)); /*writeln(output,'the character ch is "',ch,'"'); writeln(output,'ch=b is ',(ch='b')); */ if (ch == 'b' || ch == 'a' || ch == 'z') { truebook = true; if (ch == 'a') autobook = true; if (ch == 'z') { autobook = true; do { if (nostring(&aline)) printf("give position that is to become zero coordinate:\n"); TEMP.f = stdin; *TEMP.name = '\0'; getinteger(&TEMP, &aline, &zerobase, &gotten); } while (!gotten); } else zerobase = 0; getdatetime(adatetime); bwstartline(&book); writedatetime(&book, adatetime); fprintf(book.f, ", "); writedatetime(&book, adatetime); fprintf(book.f, ", "); printf("type a title if you want\n"); TEMP.f = stdin; *TEMP.name = '\0'; readstring(&TEMP, &aline); FORLIM = aline.length; for (i = 1; i <= FORLIM; i++) putc(aline.letters[i-1], book.f); putc('\n', book.f); } else truebook = false; if (autobook) ch = 'y'; else { do { if (nostring(&aline)) printf("do you want the pieces numbered (y/n)?\n"); TEMP.f = stdin; *TEMP.name = '\0'; getchar_(&TEMP, &aline, &ch, &gotten); } while (!((ch == 'n' || ch == 'y') && gotten)); } numberpieces = (ch == 'y'); /* if numberpieces then writeln(output,'BUBBA numberpieces is true') else writeln(output,'BUBBA numberpieces is false'); */ if (autobook) autoorgchr(); seqnum = 0; readseq(&sequ, &pie->dna); while (pie->dna->length > 0) { length_ = 0; d = pie->dna; do { length_ += d->length; d = d->next; } while (d != NULL); printf("sequence %ld is %ld nucleotides long\n", seqnum, length_); clearstring(&aline); ch = ' '; if (!autobook) { if (truebook && !orgopen) makeorg(); else { do { if (nostring(&aline)) printf("is this a new organism?\n"); TEMP.f = stdin; *TEMP.name = '\0'; getchar_(&TEMP, &aline, &ch, &gotten); } while (!((ch == 'n' || ch == 'y') && gotten)); if (ch == 'y') makeorg(); } if (orgopen && !chropen) makechr(); else { do { if (nostring(&aline)) printf("is this a new chromosome?\n"); TEMP.f = stdin; *TEMP.name = '\0'; getchar_(&TEMP, &aline, &ch, &gotten); } while (!((ch == 'n' || ch == 'y') && gotten)); if (ch == 'y') makechr(); } } if (autobook) autopiece(); else { printf("this sequence is %ld nucleotides long\n", length_); getpieceinfo(); clearstring(&aline); do { if (nostring(&aline)) printf("how many transcripts are there?\n"); TEMP.f = stdin; *TEMP.name = '\0'; getinteger(&TEMP, &aline, &i, &gotten); } while (!gotten); transnum = i; FORLIM = transnum; for (index_ = 1; index_ <= FORLIM; index_++) maketrans(); do { if (nostring(&aline)) printf("how many genes are there?\n"); TEMP.f = stdin; *TEMP.name = '\0'; getinteger(&TEMP, &aline, &i, &gotten); } while (!gotten); genenum = i; FORLIM = genenum; for (index_ = 1; index_ <= FORLIM; index_++) makegene(); do { if (nostring(&aline)) printf("how many markers are there?\n"); TEMP.f = stdin; *TEMP.name = '\0'; getinteger(&TEMP, &aline, &i, &gotten); } while (!gotten); marknum = i; FORLIM = marknum; for (index_ = 1; index_ <= FORLIM; index_++) makemark(); } /* regive the piece length */ bwpie(&book, pie); /* clear the lines for reuse */ clearline(&pie->key.hea.fulnam); while (pie->key.hea.note != NULL) clearline(&pie->key.hea.note); cleardna(&pie->dna); /* clear the dna for reuse */ readseq(&sequ, &pie->dna); } if (chropen) fprintf(book.f, "chromosome\n"); if (orgopen) fprintf(book.f, "organism\n"); _L1: if (book.f != NULL) fclose(book.f); if (changes.f != NULL) fclose(changes.f); if (sequ.f != NULL) fclose(sequ.f); exit(EXIT_SUCCESS); } /* makebk */ /* End. */