home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / apps / science / readseq / ureadseq.c < prev    next >
C/C++ Source or Header  |  1993-07-17  |  55KB  |  1,874 lines

  1. /* File: ureadseq.c
  2.  *
  3.  * Reads and writes nucleic/protein sequence in various
  4.  * formats. Data files may have multiple sequences.
  5.  *
  6.  * Copyright 1990 by d.g.gilbert
  7.  * biology dept., indiana university, bloomington, in 47405
  8.  * e-mail: gilbertd@bio.indiana.edu
  9.  *
  10.  * This program may be freely copied and used by anyone.
  11.  * Developers are encourged to incorporate parts in their
  12.  * programs, rather than devise their own private sequence
  13.  * format.
  14.  *
  15.  * This should compile and run with any ANSI C compiler.
  16.  *
  17.  */
  18.  
  19.  
  20. #include <stdio.h>
  21. #include <stdlib.h>    /* for realloc(), atoi(), atol() */
  22. #include <ctype.h>
  23. #include <string.h>
  24.  
  25. #define UREADSEQ_G
  26. #include "ureadseq.h"
  27.  
  28. #pragma segment ureadseq
  29.  
  30.  
  31. int Strcasecmp(const char *a, const char *b)  /* from Nlm_StrICmp */
  32. {
  33.   int diff, done;
  34.   if (a == b)  return 0;
  35.   done = 0;
  36.   while (! done) {
  37.     diff = to_upper(*a) - to_upper(*b);
  38.     if (diff) return diff;
  39.     if (*a == '\0') done = 1;
  40.     else { a++; b++; }
  41.     }
  42.   return 0;
  43. }
  44.  
  45. int Strncasecmp(const char *a, const char *b, long maxn) /* from Nlm_StrNICmp */
  46. {
  47.   int diff, done;
  48.   if (a == b)  return 0;
  49.   done = 0;
  50.   while (! done) {
  51.     diff = to_upper(*a) - to_upper(*b);
  52.     if (diff) return diff;
  53.     if (*a == '\0') done = 1;
  54.     else {
  55.       a++; b++; maxn--;
  56.       if (! maxn) done = 1;
  57.       }
  58.     }
  59.   return 0;
  60. }
  61.  
  62.  
  63.  
  64.  
  65.  
  66. #ifndef Local
  67. # define Local      static    /* local functions */
  68. #endif
  69.  
  70. #define kStartLength  500
  71.  
  72. const char *aminos      = "ABCDEFGHIKLMNPQRSTVWXYZ*";
  73. const char *primenuc    = "ACGTU";
  74. const char *protonly    = "EFIPQZ";
  75.  
  76. const char kNocountsymbols[5]  = "_.-?";
  77. const char stdsymbols[6]  = "_.-*?";
  78. const char allsymbols[32] = "_.-*?<>{}[]()!@#$%^&=+;:'/|`~\"\\";
  79. static const char *seqsymbols   = allsymbols;
  80.  
  81. const char nummask[11]   = "0123456789";
  82. const char nonummask[11] = "~!@#$%^&*(";
  83.  
  84. /*
  85.     use general form of isseqchar -- all chars + symbols.
  86.     no formats except nbrf (?) use symbols in data area as
  87.     anything other than sequence chars.
  88. */
  89.  
  90.  
  91.  
  92.                           /* Local variables for readSeq: */
  93. struct ReadSeqVars {
  94.   short choice, err, nseq;
  95.   long  seqlen, maxseq, seqlencount;
  96.   short topnseq;
  97.   long  topseqlen;
  98.   const char *fname;
  99.   char *seq, *seqid, matchchar;
  100.   boolean allDone, done, filestart, addit;
  101.   FILE  *f;
  102.   long  linestart;
  103.   char  s[256], *sp;
  104.  
  105.   int (*isseqchar)();
  106.   /* int  (*isseqchar)(int c);  << sgi cc hates (int c) */
  107. };
  108.  
  109.  
  110.  
  111. int isSeqChar(int c)
  112. {
  113.   return (isalpha(c) || strchr(seqsymbols,c));
  114. }
  115.  
  116. int isSeqNumChar(int c)
  117. {
  118.   return (isalnum(c) || strchr(seqsymbols,c));
  119. }
  120.  
  121.  
  122. int isAnyChar(int c)
  123. {
  124.   return isascii(c); /* wrap in case isascii is macro */
  125. }
  126.  
  127. Local void readline(FILE *f, char *s, long *linestart)
  128. {
  129.   char  *cp;
  130.  
  131.   *linestart= ftell(f);
  132.   if (NULL == fgets(s, 256, f))
  133.     *s = 0;
  134.   else {
  135.     cp = strchr(s, '\n');
  136.     if (cp != NULL) *cp = 0;
  137.     }
  138. }
  139.  
  140. Local void getline(struct ReadSeqVars *V)
  141. {
  142.   readline(V->f, V->s, &V->linestart);
  143. }
  144.  
  145. Local void ungetline(struct ReadSeqVars *V)
  146. {
  147.   fseek(V->f, V->linestart, 0);
  148. }
  149.  
  150.  
  151. Local void addseq(char *s, struct ReadSeqVars *V)
  152. {
  153.   char  *ptr;
  154.  
  155.   if (V->addit) while (*s != 0) {
  156.     if ((V->isseqchar)(*s)) {
  157.       if (V->seqlen >= V->maxseq) {
  158.         V->maxseq += kStartLength;
  159.         ptr = (char*) realloc(V->seq, V->maxseq+1);
  160.         if (ptr==NULL) {
  161.           V->err = eMemFull;
  162.           return;
  163.           }
  164.         else V->seq = ptr;
  165.         }
  166.       V->seq[(V->seqlen)++] = *s;
  167.       }
  168.     s++;
  169.     }
  170. }
  171.  
  172. Local void countseq(char *s, struct ReadSeqVars *V)
  173.  /* this must count all valid seq chars, for some formats (paup-sequential) even
  174.     if we are skipping seq... */
  175. {
  176.   while (*s != 0) {
  177.     if ((V->isseqchar)(*s)) {
  178.       (V->seqlencount)++;
  179.       }
  180.     s++;
  181.     }
  182. }
  183.  
  184.  
  185. Local void addinfo(char *s, struct ReadSeqVars *V)
  186. {
  187.   char s2[256], *si;
  188.   boolean saveadd;
  189.  
  190.   si = s2;
  191.   while (*s == ' ') s++;
  192.   sprintf(si, " %d)  %s\n", V->nseq, s);
  193.  
  194.   saveadd = V->addit;
  195.   V->addit = true;
  196.   V->isseqchar = isAnyChar;
  197.   addseq( si, V);
  198.   V->addit = saveadd;
  199.   V->isseqchar = isSeqChar;
  200. }
  201.  
  202.  
  203.  
  204.  
  205. Local void readLoop(short margin, boolean addfirst,
  206.             boolean (*endTest)(boolean *addend, boolean *ungetend, struct ReadSeqVars *V),
  207.             struct ReadSeqVars *V)
  208. {
  209.   boolean addend = false;
  210.   boolean ungetend = false;
  211.  
  212.   V->nseq++;
  213.   if (V->choice == kListSequences) V->addit = false;
  214.   else V->addit = (V->nseq == V->choice);
  215.   if (V->addit) V->seqlen = 0;
  216.  
  217.   if (addfirst) addseq(V->s, V);
  218.   do {
  219.     getline(V);
  220.     V->done = feof(V->f);
  221.     V->done |= (*endTest)( &addend, &ungetend, V);
  222.     if (V->addit && (addend || !V->done) && (strlen(V->s) > margin)) {
  223.       addseq( (V->s)+margin, V);
  224.     }
  225.   } while (!V->done);
  226.  
  227.   if (V->choice == kListSequences) addinfo(V->seqid, V);
  228.   else {
  229.     V->allDone = (V->nseq >= V->choice);
  230.     if (V->allDone && ungetend) ungetline(V);
  231.     }
  232. }
  233.  
  234.  
  235.  
  236. Local boolean endIG( boolean *addend, boolean *ungetend, struct ReadSeqVars *V)
  237. {
  238.   *addend = true; /* 1 or 2 occur in line w/ bases */
  239.   *ungetend= false;
  240.   return((strchr(V->s,'1')!=NULL) || (strchr(V->s,'2')!=NULL));
  241. }
  242.  
  243. Local void readIG(struct ReadSeqVars *V)
  244. {
  245. /* 18Aug92: new IG format -- ^L between sequences in place of ";" */
  246.   char  *si;
  247.  
  248.   while (!V->allDone) {
  249.     do {
  250.       getline(V);
  251.       for (si= V->s; *si != 0 && *si < ' '; si++) *si= ' '; /* drop controls */
  252.       if (*si == 0) *V->s= 0; /* chop line to empty */
  253.     } while (! (feof(V->f) || ((*V->s != 0) && (*V->s != ';') ) ));
  254.     if (feof(V->f))
  255.       V->allDone = true;
  256.     else {
  257.       strcpy(V->seqid, V->s);
  258.       readLoop(0, false, endIG, V);
  259.       }
  260.   }
  261. }
  262.  
  263.  
  264.  
  265. Local boolean endStrider( boolean *addend, boolean *ungetend, struct ReadSeqVars *V)
  266. {
  267.   *addend = false;
  268.   *ungetend= false;
  269.   return (strstr( V->s, "//") != NULL);
  270. }
  271.  
  272. Local void readStrider(struct ReadSeqVars *V)
  273. { /* ? only 1 seq/file ? */
  274.  
  275.   while (!V->allDone) {
  276.     getline(V);
  277.     if (strstr(V->s,"; DNA sequence  ") == V->s)
  278.       strcpy(V->seqid, (V->s)+16);
  279.     else
  280.       strcpy(V->seqid, (V->s)+1);
  281.     while ((!feof(V->f)) && (*V->s == ';')) {
  282.       getline(V);
  283.       }
  284.     if (feof(V->f)) V->allDone = true;
  285.     else readLoop(0, true, endStrider, V);
  286.   }
  287. }
  288.  
  289.  
  290. Local boolean endPIR( boolean *addend, boolean *ungetend, struct ReadSeqVars *V)
  291. {
  292.   *addend = false;
  293.   *ungetend= (strstr(V->s,"ENTRY") == V->s);
  294.   return ((strstr(V->s,"///") != NULL) || *ungetend);
  295. }
  296.  
  297. Local void readPIR(struct ReadSeqVars *V)
  298. { /*PIR -- many seqs/file */
  299.  
  300.   while (!V->allDone) {
  301.     while (! (feof(V->f) || strstr(V->s,"ENTRY")  || strstr(V->s,"SEQUENCE")) )
  302.       getline(V);
  303.     strcpy(V->seqid, (V->s)+16);
  304.     while (! (feof(V->f) || strstr(V->s,"SEQUENCE") == V->s))
  305.       getline(V);
  306.     readLoop(0, false, endPIR, V);
  307.  
  308.     if (!V->allDone) {
  309.      while (! (feof(V->f) || ((*V->s != 0)
  310.        && (strstr( V->s,"ENTRY") == V->s))))
  311.         getline(V);
  312.       }
  313.     if (feof(V->f)) V->allDone = true;
  314.   }
  315. }
  316.  
  317.  
  318. Local boolean endGB( boolean *addend, boolean *ungetend, struct ReadSeqVars *V)
  319. {
  320.   *addend = false;
  321.   *ungetend= (strstr(V->s,"LOCUS") == V->s);
  322.   return ((strstr(V->s,"//") != NULL) || *ungetend);
  323. }
  324.  
  325. Local void readGenBank(struct ReadSeqVars *V)
  326. { /*GenBank -- many seqs/file */
  327.  
  328.   while (!V->allDone) {
  329.     strcpy(V->seqid, (V->s)+12);
  330.     while (! (feof(V->f) || strstr(V->s,"ORIGIN") == V->s))
  331.       getline(V);
  332.     readLoop(0, false, endGB, V);
  333.  
  334.     if (!V->allDone) {
  335.      while (! (feof(V->f) || ((*V->s != 0)
  336.        && (strstr( V->s,"LOCUS") == V->s))))
  337.         getline(V);
  338.       }
  339.     if (feof(V->f)) V->allDone = true;
  340.   }
  341. }
  342.  
  343.  
  344. Local boolean endNBRF( boolean *addend, boolean *ungetend, struct ReadSeqVars *V)
  345. {
  346.   char  *a;
  347.  
  348.   if ((a = strchr(V->s, '*')) != NULL) { /* end of 1st seq */
  349.     /* "*" can be valid base symbol, drop it here */
  350.     *a = 0;
  351.     *addend = true;
  352.     *ungetend= false;
  353.     return(true);
  354.     }
  355.   else if (*V->s == '>') { /* start of next seq */
  356.     *addend = false;
  357.     *ungetend= true;
  358.     return(true);
  359.     }
  360.   else
  361.     return(false);
  362. }
  363.  
  364. Local void readNBRF(struct ReadSeqVars *V)
  365. {
  366.   while (!V->allDone) {
  367.     strcpy(V->seqid, (V->s)+4);
  368.     getline(V);   /*skip title-junk line*/
  369.     readLoop(0, false, endNBRF, V);
  370.     if (!V->allDone) {
  371.      while (!(feof(V->f) || (*V->s != 0 && *V->s == '>')))
  372.         getline(V);
  373.       }
  374.     if (feof(V->f)) V->allDone = true;
  375.   }
  376. }
  377.  
  378.  
  379.  
  380. Local boolean endPearson( boolean *addend, boolean *ungetend, struct ReadSeqVars *V)
  381. {
  382.   *addend = false;
  383.   *ungetend= true;
  384.   return(*V->s == '>');
  385. }
  386.  
  387. Local void readPearson(struct ReadSeqVars *V)
  388. {
  389.   while (!V->allDone) {
  390.     strcpy(V->seqid, (V->s)+1);
  391.     readLoop(0, false, endPearson, V);
  392.     if (!V->allDone) {
  393.      while (!(feof(V->f) || ((*V->s != 0) && (*V->s == '>'))))
  394.         getline(V);
  395.       }
  396.     if (feof(V->f)) V->allDone = true;
  397.   }
  398. }
  399.  
  400.  
  401.  
  402. Local boolean endEMBL( boolean *addend, boolean *ungetend, struct ReadSeqVars *V)
  403. {
  404.   *addend = false;
  405.   *ungetend= (strstr(V->s,"ID   ") == V->s);
  406.   return ((strstr(V->s,"//") != NULL) || *ungetend);
  407. }
  408.  
  409. Local void readEMBL(struct ReadSeqVars *V)
  410. {
  411.   while (!V->allDone) {
  412.     strcpy(V->seqid, (V->s)+5);
  413.     do {
  414.       getline(V);
  415.     } while (!(feof(V->f) | (strstr(V->s,"SQ   ") == V->s)));
  416.  
  417.     readLoop(0, false, endEMBL, V);
  418.     if (!V->allDone) {
  419.       while (!(feof(V->f) |
  420.          ((*V->s != '\0') & (strstr(V->s,"ID   ") == V->s))))
  421.       getline(V);
  422.     }
  423.     if (feof(V->f)) V->allDone = true;
  424.   }
  425. }
  426.  
  427.  
  428.  
  429. Local boolean endZuker( boolean *addend, boolean *ungetend, struct ReadSeqVars *V)
  430. {
  431.   *addend = false;
  432.   *ungetend= true;
  433.   return( *V->s == '(' );
  434. }
  435.  
  436. Local void readZuker(struct ReadSeqVars *V)
  437. {
  438.   /*! 1st string is Zuker's Fortran format */
  439.  
  440.   while (!V->allDone) {
  441.     getline(V);  /*s == "seqLen seqid string..."*/
  442.     strcpy(V->seqid, (V->s)+6);
  443.     readLoop(0, false, endZuker, V);
  444.     if (!V->allDone) {
  445.       while (!(feof(V->f) |
  446.         ((*V->s != '\0') & (*V->s == '('))))
  447.           getline(V);
  448.       }
  449.     if (feof(V->f)) V->allDone = true;
  450.   }
  451. }
  452.  
  453.  
  454.  
  455. Local boolean endFitch( boolean *addend, boolean *ungetend, struct ReadSeqVars *V)
  456. {
  457.   /* this is a somewhat shaky end,
  458.     1st char of line is non-blank for seq. title
  459.   */
  460.   *addend = false;
  461.   *ungetend= true;
  462.   return( *V->s != ' ' );
  463. }
  464.  
  465. Local void readFitch(struct ReadSeqVars *V)
  466. {
  467.   boolean first;
  468.  
  469.   first = true;
  470.   while (!V->allDone) {
  471.     if (!first) strcpy(V->seqid, V->s);
  472.     readLoop(0, first, endFitch, V);
  473.     if (feof(V->f)) V->allDone = true;
  474.     first = false;
  475.     }
  476. }
  477.  
  478.  
  479. Local void readPlain(struct ReadSeqVars *V)
  480. {
  481.   V->nseq++;
  482.   V->addit = (V->choice > 0);
  483.   if (V->addit) V->seqlen = 0;
  484.   addseq(V->seqid, V);   /*from above..*/
  485.   if (V->fname!=NULL) sprintf(V->seqid, "%s  [Unknown form]", V->fname);
  486.   else sprintf(V->seqid, "  [Unknown form]");
  487.   do {
  488.     addseq(V->s, V);
  489.     V->done = feof(V->f);
  490.     getline(V);
  491.   } while (!V->done);
  492.   if (V->choice == kListSequences) addinfo(V->seqid, V);
  493.   V->allDone = true;
  494. }
  495.  
  496.  
  497. Local void readUWGCG(struct ReadSeqVars *V)
  498. {
  499. /*
  500. 10nov91: Reading GCG files casued duplication of last line when
  501.          EOF followed that line !!!
  502.     fix: getline now sets *V->s = 0
  503. */
  504.   char  *si;
  505.  
  506.   V->nseq++;
  507.   V->addit = (V->choice > 0);
  508.   if (V->addit) V->seqlen = 0;
  509.   strcpy(V->seqid, V->s);
  510.   /*writeseq: "    %s  Length: %d  (today)  Check: %d  ..\n" */
  511.   /*drop above or ".." from id*/
  512.   if (si = strstr(V->seqid,"  Length: ")) *si = 0;
  513.   else if (si = strstr(V->seqid,"..")) *si = 0;
  514.   do {
  515.     V->done = feof(V->f);
  516.     getline(V);
  517.     if (!V->done) addseq((V->s), V);
  518.   } while (!V->done);
  519.   if (V->choice == kListSequences) addinfo(V->seqid, V);
  520.   V->allDone = true;
  521. }
  522.  
  523.  
  524. Local void readOlsen(struct ReadSeqVars *V)
  525. { /* G. Olsen /print output from multiple sequence editor */
  526.  
  527.   char    *si, *sj, *sk, *sm, sid[40], snum[20];
  528.   boolean indata = false;
  529.   int snumlen;
  530.  
  531.   V->addit = (V->choice > 0);
  532.   if (V->addit) V->seqlen = 0;
  533.   rewind(V->f); V->nseq= 0;
  534.   do {
  535.     getline(V);
  536.     V->done = feof(V->f);
  537.  
  538.     if (V->done && !(*V->s)) break;
  539.     else if (indata) {
  540.       if ( (si= strstr(V->s, sid))
  541.         /* && (strstr(V->s, snum) == si - snumlen - 1) ) { */
  542.         && (sm= strstr(V->s, snum)) && (sm < si - snumlen) ) {
  543.  
  544.         /* Spaces are valid alignment data !! */
  545. /* 17Oct91: Error, the left margin is 21 not 22! */
  546. /* dropped some nucs up to now -- my example file was right shifted ! */
  547. /* variable right id margin, drop id-2 spaces at end */
  548. /*
  549.   VMS CC COMPILER (VAXC031) mess up:
  550.   -- Index of 21 is chopping 1st nuc on VMS systems Only!
  551.   Byte-for-byte same ame rnasep.olsen sequence file !
  552. */
  553.  
  554.         /* si = (V->s)+21; < was this before VMS CC wasted my time */
  555.         si += 10;  /* use strstr index plus offset to outfox VMS CC bug */
  556.  
  557.         if (sk = strstr(si, sid)) *(sk-2) = 0;
  558.         for (sk = si; *sk != 0; sk++) {
  559.            if (*sk == ' ') *sk = '.';
  560.            /* 18aug92: !! some olsen masks are NUMBERS !! which addseq eats */
  561.            else if (isdigit(*sk)) *sk= nonummask[*sk - '0'];
  562.            }
  563.  
  564.         addseq(si, V);
  565.         }
  566.       }
  567.  
  568.     else if (sk = strstr(V->s, "): ")) {  /* seq info header line */
  569.   /* 18aug92: correct for diff seqs w/ same name -- use number, e.g. */
  570.   /*   3 (Agr.tume):  agrobacterium.prna  18-JUN-1987 16:12 */
  571.   /* 328 (Agr.tume):  agrobacterium.prna XYZ  19-DEC-1992   */
  572.       (V->nseq)++;
  573.       si = 1 + strchr(V->s,'(');
  574.       *sk = ' ';
  575.       if (V->choice == kListSequences) addinfo( si, V);
  576.       else if (V->nseq == V->choice) {
  577.         strcpy(V->seqid, si);
  578.         sj = strchr(V->seqid, ':');
  579.         while (*(--sj) == ' ') ;
  580.         while (--sj != V->seqid) { if (*sj == ' ') *sj = '_'; }
  581.  
  582.         *sk = 0;
  583.         while (*(--sk) == ' ') *sk = 0;
  584.         strcpy(sid, si);
  585.  
  586.         si= V->s;
  587.         while ((*si <= ' ') && (*si != 0)) si++;
  588.         snumlen=0;
  589.         while (si[snumlen] > ' ' && snumlen<20)
  590.          { snum[snumlen]= si[snumlen]; snumlen++; }
  591.         snum[snumlen]= 0;
  592.         }
  593.  
  594.       }
  595.  
  596.     else if (strstr(V->s,"identity:   Data:")) {
  597.       indata = true;
  598.       if (V->choice == kListSequences) V->done = true;
  599.       }
  600.  
  601.   } while (!V->done);
  602.  
  603.   V->allDone = true;
  604. } /*readOlsen*/
  605.  
  606.  
  607. Local void readMSF(struct ReadSeqVars *V)
  608. { /* gcg's MSF, mult. sequence format, interleaved ! */
  609.  
  610.   char    *si, *sj, sid[128];
  611.   boolean indata = false;
  612.   int     atseq= 0, iline= 0;
  613.  
  614.   V->addit = (V->choice > 0);
  615.   if (V->addit) V->seqlen = 0;
  616.   rewind(V->f); V->nseq= 0;
  617.   do {
  618.     getline(V);
  619.     V->done = feof(V->f);
  620.  
  621.     if (V->done && !(*V->s)) break;
  622.     else if (indata) {
  623.       /*somename  ...gpvedai .......t.. aaigr..vad tvgtgptnse aipaltaaet */
  624.       /*       E  gvenae.kgv tentna.tad fvaqpvylpe .nqt...... kv.affynrs */
  625.  
  626.       si= V->s;
  627.       skipwhitespace(si);
  628.       /* for (sj= si; isalnum(*sj); sj++) ; bug -- cdelwiche uses "-", "_" and others in names*/
  629.       for (sj= si; *sj > ' '; sj++) ;
  630.       *sj= 0;
  631.       if ( *si ) {
  632.         if ( (0==strcmp(si, sid)) ) {
  633.           addseq(sj+1, V);
  634.           }
  635.         iline++;
  636.         }
  637.       }
  638.  
  639.     else if (NULL != (si = strstr(V->s, "Name: "))) {  /* seq info header line */
  640.       /* Name: somename      Len:   100  Check: 7009  Weight:  1.00 */
  641.  
  642.       (V->nseq)++;
  643.       si += 6;
  644.       if (V->choice == kListSequences) addinfo( si, V);
  645.       else if (V->nseq == V->choice) {
  646.         strcpy(V->seqid, si);
  647.         si = V->seqid;
  648.         skipwhitespace(si);
  649.         /* for (sj= si; isalnum(*sj); sj++) ; -- bug */
  650.         for (sj= si; *sj > ' '; sj++) ;
  651.         *sj= 0;
  652.         strcpy(sid, si);
  653.         }
  654.       }
  655.  
  656.     else if ( strstr(V->s,"//") /*== V->s*/ )  {
  657.       indata = true;
  658.       iline= 0;
  659.       if (V->choice == kListSequences) V->done = true;
  660.       }
  661.  
  662.   } while (!V->done);
  663.  
  664.  
  665.   V->allDone = true;
  666. } /*readMSF*/
  667.  
  668.  
  669.  
  670. Local void readPAUPinterleaved(struct ReadSeqVars *V)
  671. { /* PAUP mult. sequence format, interleaved or sequential! */
  672.  
  673.   char    *si, *sj, *send, sid[40], sid1[40], saveseq[255];
  674.   boolean first = true, indata = false, domatch;
  675.   int     atseq= 0, iline= 0, ifmc, saveseqlen=0;
  676.  
  677. #define fixmatchchar(s) { \
  678.   for (ifmc=0; ifmc<saveseqlen; ifmc++) \
  679.     if (s[ifmc] == V->matchchar) s[ifmc]= saveseq[ifmc]; }
  680.  
  681.   V->addit = (V->choice > 0);
  682.   V->seqlencount = 0;
  683.   if (V->addit) V->seqlen = 0;
  684.   /* rewind(V->f); V->nseq= 0;  << do in caller !*/
  685.   indata= true; /* call here after we find "matrix" */
  686.   domatch= (V->matchchar > 0);
  687.  
  688.   do {
  689.     getline(V);
  690.     V->done = feof(V->f);
  691.  
  692.     if (V->done && !(*V->s)) break;
  693.     else if (indata) {
  694.       /* [         1                    1                    1         ]*/
  695.       /* human     aagcttcaccggcgcagtca ttctcataatcgcccacggR cttacatcct*/
  696.       /* chimp     ................a.t. .c.................a ..........*/
  697.       /* !! need to correct for V->matchchar */
  698.       si= V->s;
  699.       skipwhitespace(si);
  700.       if (strchr(si,';')) indata= false;
  701.  
  702.       if (isalnum(*si))  {
  703.         /* valid data line starts w/ a left-justified seq name in columns [0..8] */
  704.         if (first) {
  705.           (V->nseq)++;
  706.           if (V->nseq >= V->topnseq) first= false;
  707.           for (sj = si; isalnum(*sj); sj++) ;
  708.           send= sj;
  709.           skipwhitespace(sj);
  710.           if (V->choice == kListSequences) {
  711.             *send= 0;
  712.             addinfo( si, V);
  713.             }
  714.           else if (V->nseq == V->choice) {
  715.             if (domatch) {
  716.               if (V->nseq == 1) { strcpy( saveseq, sj); saveseqlen= strlen(saveseq); }
  717.               else fixmatchchar( sj);
  718.               }
  719.             addseq(sj, V);
  720.             *send= 0;
  721.             strcpy(V->seqid, si);
  722.             strcpy(sid, si);
  723.             if (V->nseq == 1) strcpy(sid1, sid);
  724.             }
  725.           }
  726.  
  727.         else if ( (strstr(si, sid) == si) ){
  728.           while (isalnum(*si)) si++;
  729.           skipwhitespace(si);
  730.           if (domatch) {
  731.             if (V->nseq == 1) { strcpy( saveseq, si); saveseqlen= strlen(saveseq); }
  732.             else fixmatchchar( si);
  733.             }
  734.           addseq(si, V);
  735.           }
  736.  
  737.         else if (domatch && (strstr(si, sid1) == si)) {
  738.           strcpy( saveseq, si);
  739.           saveseqlen= strlen(saveseq);
  740.           }
  741.  
  742.         iline++;
  743.         }
  744.       }
  745.  
  746.     else if ( strstr(V->s,"matrix") )  {
  747.       indata = true;
  748.       iline= 0;
  749.       if (V->choice == kListSequences) V->done = true;
  750.       }
  751.  
  752.   } while (!V->done);
  753.  
  754.   V->allDone = true;
  755. } /*readPAUPinterleaved*/
  756.  
  757.  
  758.  
  759. Local void readPAUPsequential(struct ReadSeqVars *V)
  760. { /* PAUP mult. sequence format, interleaved or sequential! */
  761.   char    *si, *sj;
  762.   boolean atname = true, indata = false;
  763.  
  764.   V->addit = (V->choice > 0);
  765.   if (V->addit) V->seqlen = 0;
  766.   V->seqlencount = 0;
  767.   /* rewind(V->f); V->nseq= 0;  << do in caller !*/
  768.   indata= true; /* call here after we find "matrix" */
  769.   do {
  770.     getline(V);
  771.     V->done = feof(V->f);
  772.  
  773.     if (V->done && !(*V->s)) break;
  774.     else if (indata) {
  775.       /* [         1                    1                    1         ]*/
  776.       /* human     aagcttcaccggcgcagtca ttctcataatcgcccacggR cttacatcct*/
  777.       /*           aagcttcaccggcgcagtca ttctcataatcgcccacggR cttacatcct*/
  778.       /* chimp     ................a.t. .c.................a ..........*/
  779.       /*           ................a.t. .c.................a ..........*/
  780.  
  781.       si= V->s;
  782.       skipwhitespace(si);
  783.       if (strchr(si,';')) indata= false;
  784.       if (isalnum(*si))  {
  785.         /* valid data line starts w/ a left-justified seq name in columns [0..8] */
  786.         if (atname) {
  787.           (V->nseq)++;
  788.           V->seqlencount = 0;
  789.           atname= false;
  790.           sj= si+1;
  791.           while (isalnum(*sj)) sj++;
  792.           if (V->choice == kListSequences) {
  793.             /* !! we must count bases to know when topseqlen is reached ! */
  794.             countseq(sj, V);
  795.             if (V->seqlencount >= V->topseqlen) atname= true;
  796.             *sj= 0;
  797.             addinfo( si, V);
  798.             }
  799.           else if (V->nseq == V->choice) {
  800.             addseq(sj, V);
  801.             V->seqlencount= V->seqlen;
  802.             if (V->seqlencount >= V->topseqlen) atname= true;
  803.             *sj= 0;
  804.             strcpy(V->seqid, si);
  805.             }
  806.           else {
  807.             countseq(sj, V);
  808.             if (V->seqlencount >= V->topseqlen) atname= true;
  809.             }
  810.           }
  811.  
  812.         else if (V->nseq == V->choice) {
  813.           addseq(V->s, V);
  814.           V->seqlencount= V->seqlen;
  815.           if (V->seqlencount >= V->topseqlen) atname= true;
  816.           }
  817.         else {
  818.           countseq(V->s, V);
  819.           if (V->seqlencount >= V->topseqlen) atname= true;
  820.           }
  821.         }
  822.       }
  823.  
  824.     else if ( strstr(V->s,"matrix") )  {
  825.       indata = true;
  826.       atname= true;
  827.       if (V->choice == kListSequences) V->done = true;
  828.       }
  829.  
  830.   } while (!V->done);
  831.  
  832.   V->allDone = true;
  833. } /*readPAUPsequential*/
  834.  
  835.  
  836. Local void readPhylipInterleaved(struct ReadSeqVars *V)
  837. {
  838.   char    *si, *sj;
  839.   boolean first = true;
  840.   int     iline= 0;
  841.  
  842.   V->addit = (V->choice > 0);
  843.   if (V->addit) V->seqlen = 0;
  844.   V->seqlencount = 0;
  845.   /* sscanf( V->s, "%d%d", &V->topnseq, &V->topseqlen); << topnseq == 0 !!! bad scan !! */
  846.   si= V->s;
  847.   skipwhitespace(si);
  848.   V->topnseq= atoi(si);
  849.   while (isdigit(*si)) si++;
  850.   skipwhitespace(si);
  851.   V->topseqlen= atol(si);
  852.   /* fprintf(stderr,"Phylip-ileaf: topnseq=%d  topseqlen=%d\n",V->topnseq, V->topseqlen); */
  853.  
  854.   do {
  855.     getline(V);
  856.     V->done = feof(V->f);
  857.  
  858.     if (V->done && !(*V->s)) break;
  859.     si= V->s;
  860.     skipwhitespace(si);
  861.     if (*si != 0) {
  862.  
  863.       if (first) {  /* collect seq names + seq, as fprintf(outf,"%-10s  ",seqname); */
  864.         (V->nseq)++;
  865.         if (V->nseq >= V->topnseq) first= false;
  866.         sj= V->s+10;  /* past name, start of data */
  867.         if (V->choice == kListSequences) {
  868.           *sj= 0;
  869.           addinfo( si, V);
  870.           }
  871.         else if (V->nseq == V->choice) {
  872.           addseq(sj, V);
  873.           *sj= 0;
  874.           strcpy(V->seqid, si);
  875.           }
  876.         }
  877.       else if ( iline % V->nseq == V->choice -1 ) {
  878.         addseq(si, V);
  879.         }
  880.       iline++;
  881.     }
  882.   } while (!V->done);
  883.  
  884.   V->allDone = true;
  885. } /*readPhylipInterleaved*/
  886.  
  887.  
  888.  
  889. Local boolean endPhylipSequential( boolean *addend, boolean *ungetend, struct ReadSeqVars *V)
  890. {
  891.   *addend = false;
  892.   *ungetend= false;
  893.   countseq( V->s, V);
  894.   return V->seqlencount >= V->topseqlen;
  895. }
  896.  
  897. Local void readPhylipSequential(struct ReadSeqVars *V)
  898. {
  899.   short  i;
  900.   char  *si;
  901.   /* sscanf( V->s, "%d%d", &V->topnseq, &V->topseqlen); < ? bad sscan ? */
  902.   si= V->s;
  903.   skipwhitespace(si);
  904.   V->topnseq= atoi(si);
  905.   while (isdigit(*si)) si++;
  906.   skipwhitespace(si);
  907.   V->topseqlen= atol(si);
  908.   getline(V);
  909.   while (!V->allDone) {
  910.     V->seqlencount= 0;
  911.     strncpy(V->seqid, (V->s), 10);
  912.     V->seqid[10]= 0;
  913.     for (i=0; i<10 && V->s[i]; i++) V->s[i]= ' ';
  914.     readLoop(0, true, endPhylipSequential, V);
  915.     if (feof(V->f)) V->allDone = true;
  916.     }
  917. }
  918.  
  919.  
  920.  
  921.  
  922. Local void readSeqMain(
  923.       struct ReadSeqVars *V,
  924.       const long  skiplines_,
  925.       const short format_)
  926. {
  927. #define tolowerstr(s) { long Itlwr, Ntlwr= strlen(s); \
  928.   for (Itlwr=0; Itlwr<Ntlwr; Itlwr++) s[Itlwr]= to_lower(s[Itlwr]); }
  929.  
  930.   boolean gotuw;
  931.   long l;
  932.  
  933.   V->linestart= 0;
  934.   V->matchchar= 0;
  935.   if (V->f == NULL)
  936.     V->err = eFileNotFound;
  937.   else {
  938.  
  939.     for (l = skiplines_; l > 0; l--) getline( V);
  940.  
  941.     do {
  942.       getline( V);
  943.       for (l= strlen(V->s); (l > 0) && (V->s[l] == ' '); l--) ;
  944.     } while ((l == 0) && !feof(V->f));
  945.  
  946.     if (feof(V->f)) V->err = eNoData;
  947.  
  948.     else switch (format_) {
  949.       case kPlain : readPlain(V); break;
  950.       case kIG    : readIG(V); break;
  951.       case kStrider: readStrider(V); break;
  952.       case kGenBank: readGenBank(V); break;
  953.       case kPIR   : readPIR(V); break;
  954.       case kNBRF  : readNBRF(V); break;
  955.       case kPearson: readPearson(V); break;
  956.       case kEMBL  : readEMBL(V); break;
  957.       case kZuker : readZuker(V); break;
  958.       case kOlsen : readOlsen(V); break;
  959.       case kMSF   : readMSF(V); break;
  960.  
  961.       case kPAUP    : {
  962.         boolean done= false;
  963.         boolean interleaved= false;
  964.         char  *cp;
  965.         /* rewind(V->f); V->nseq= 0; ?? assume it is at top ?? skiplines ... */
  966.         while (!done) {
  967.           getline( V);
  968.           tolowerstr( V->s);
  969.           if (strstr( V->s, "matrix")) done= true;
  970.           if (strstr( V->s, "interleav")) interleaved= true;
  971.           if (NULL != (cp=strstr( V->s, "ntax=")) )  V->topnseq= atoi(cp+5);
  972.           if (NULL != (cp=strstr( V->s, "nchar=")) )  V->topseqlen= atoi(cp+6);
  973.           if (NULL != (cp=strstr( V->s, "matchchar=")) )  {
  974.             cp += 10;
  975.             if (*cp=='\'') cp++;
  976.             else if (*cp=='"') cp++;
  977.             V->matchchar= *cp;
  978.             }
  979.           }
  980.         if (interleaved) readPAUPinterleaved(V);
  981.         else readPAUPsequential(V);
  982.         }
  983.         break;
  984.  
  985.       /* kPhylip: ! can't determine in middle of file which type it is...*/
  986.       /* test for interleave or sequential and use Phylip4(ileave) or Phylip2 */
  987.       case kPhylip2:
  988.         readPhylipSequential(V);
  989.         break;
  990.       case kPhylip4: /* == kPhylip3 */
  991.         readPhylipInterleaved(V);
  992.         break;
  993.  
  994.       default:
  995.         V->err = eUnknownFormat;
  996.         break;
  997.  
  998.       case kFitch :
  999.         strcpy(V->seqid, V->s); getline(V);
  1000.         readFitch(V);
  1001.         break;
  1002.  
  1003.       case kGCG:
  1004.         do {
  1005.           gotuw = (strstr(V->s,"..") != NULL);
  1006.           if (gotuw) readUWGCG(V);
  1007.           getline(V);
  1008.         } while (!(feof(V->f) || V->allDone));
  1009.         break;
  1010.       }
  1011.     }
  1012.  
  1013.   V->filestart= false;
  1014.   V->seq[V->seqlen] = 0; /* stick a string terminator on it */
  1015. }
  1016.  
  1017.  
  1018. char *readSeqFp(
  1019.       const short whichEntry_,  /* index to sequence in file */
  1020.       FILE  *fp_,   /* pointer to open seq file */
  1021.       const long  skiplines_,
  1022.       const short format_,      /* sequence file format */
  1023.       long  *seqlen_,     /* return seq size */
  1024.       short *nseq_,       /* number of seqs in file, for listSeqs() */
  1025.       short *error_,      /* return error */
  1026.       char  *seqid_)      /* return seq name/info */
  1027. {
  1028.   struct ReadSeqVars V;
  1029.  
  1030.   if (format_ < kMinFormat || format_ > kMaxFormat) {
  1031.     *error_ = eUnknownFormat;
  1032.     *seqlen_ = 0;
  1033.     return NULL;
  1034.     }
  1035.  
  1036.   V.choice = whichEntry_;
  1037.   V.fname  = NULL;  /* don't know */
  1038.   V.seq    = (char*) calloc(1, kStartLength+1);
  1039.   V.maxseq = kStartLength;
  1040.   V.seqlen = 0;
  1041.   V.seqid  = seqid_;
  1042.  
  1043.   V.f = fp_;
  1044.   V.filestart= (ftell( fp_) == 0);
  1045.   /* !! in sequential read, must remove current seq position from choice/whichEntry_ counter !! ... */
  1046.   if (V.filestart)  V.nseq = 0;
  1047.   else V.nseq= *nseq_;  /* track where we are in file...*/
  1048.  
  1049.   *V.seqid = '\0';
  1050.   V.err = 0;
  1051.   V.nseq = 0;
  1052.   V.isseqchar = isSeqChar;
  1053.   if (V.choice == kListSequences) ; /* leave as is */
  1054.   else if (V.choice <= 0) V.choice = 1; /* default ?? */
  1055.   V.addit = (V.choice > 0);
  1056.   V.allDone = false;
  1057.  
  1058.   readSeqMain(&V, skiplines_, format_);
  1059.  
  1060.   *error_ = V.err;
  1061.   *seqlen_ = V.seqlen;
  1062.   *nseq_ = V.nseq;
  1063.   return V.seq;
  1064. }
  1065.  
  1066. char *readSeq(
  1067.       const short whichEntry_,  /* index to sequence in file */
  1068.       const char  *filename_,   /* file name */
  1069.       const long  skiplines_,
  1070.       const short format_,      /* sequence file format */
  1071.       long  *seqlen_,     /* return seq size */
  1072.       short *nseq_,       /* number of seqs in file, for listSeqs() */
  1073.       short *error_,      /* return error */
  1074.       char  *seqid_)      /* return seq name/info */
  1075. {
  1076.   struct ReadSeqVars V;
  1077.  
  1078.   if (format_ < kMinFormat || format_ > kMaxFormat) {
  1079.     *error_ = eUnknownFormat;
  1080.     *seqlen_ = 0;
  1081.     return NULL;
  1082.     }
  1083.  
  1084.   V.choice = whichEntry_;
  1085.   V.fname  = filename_;  /* don't need to copy string, just ptr to it */
  1086.   V.seq    = (char*) calloc(1, kStartLength+1);
  1087.   V.maxseq = kStartLength;
  1088.   V.seqlen = 0;
  1089.   V.seqid  = seqid_;
  1090.  
  1091.   V.f = NULL;
  1092.   *V.seqid = '\0';
  1093.   V.err = 0;
  1094.   V.nseq = 0;
  1095.   V.isseqchar = isSeqChar;
  1096.   if (V.choice == kListSequences) ; /* leave as is */
  1097.   else if (V.choice <= 0) V.choice = 1; /* default ?? */
  1098.   V.addit = (V.choice > 0);
  1099.   V.allDone = false;
  1100.  
  1101.   V.f = fopen(V.fname, "r");
  1102.   V.filestart= true;
  1103.  
  1104.   readSeqMain(&V, skiplines_, format_);
  1105.  
  1106.   if (V.f != NULL) fclose(V.f);
  1107.   *error_ = V.err;
  1108.   *seqlen_ = V.seqlen;
  1109.   *nseq_ = V.nseq;
  1110.   return V.seq;
  1111. }
  1112.  
  1113.  
  1114.  
  1115.  
  1116.  
  1117. char *listSeqs(
  1118.       const char  *filename_,   /* file name */
  1119.       const long skiplines_,
  1120.       const short format_,      /* sequence file format */
  1121.       short *nseq_,       /* number of seqs in file, for listSeqs() */
  1122.       short *error_)      /* return error */
  1123. {
  1124.   char  seqid[256];
  1125.   long  seqlen;
  1126.  
  1127.   return readSeq( kListSequences, filename_, skiplines_, format_,
  1128.                   &seqlen, nseq_, error_, seqid);
  1129. }
  1130.  
  1131.  
  1132.  
  1133.  
  1134. short seqFileFormat(    /* return sequence format number, see ureadseq.h */
  1135.     const char *filename,
  1136.     long  *skiplines,   /* return #lines to skip any junk like mail header */
  1137.     short *error)       /* return any error value or 0 */
  1138. {
  1139.   FILE      *fseq;
  1140.   short      format;
  1141.  
  1142.   fseq  = fopen(filename, "r");
  1143.   format= seqFileFormatFp( fseq, skiplines, error);
  1144.   if (fseq!=NULL) fclose(fseq);
  1145.   return format;
  1146. }
  1147.  
  1148. short seqFileFormatFp(
  1149.     FILE *fseq,
  1150.     long  *skiplines,   /* return #lines to skip any junk like mail header */
  1151.     short *error)       /* return any error value or 0 */
  1152. {
  1153.   boolean   foundDNA= false, foundIG= false, foundStrider= false,
  1154.             foundGB= false, foundPIR= false, foundEMBL= false, foundNBRF= false,
  1155.             foundPearson= false, foundFitch= false, foundPhylip= false, foundZuker= false,
  1156.             gotolsen= false, gotpaup = false, gotasn1 = false, gotuw= false, gotMSF= false,
  1157.             isfitch= false,  isphylip= false, done= false;
  1158.   short     format= kUnknown;
  1159.   int       nlines= 0, k, splen= 0, otherlines= 0, aminolines= 0, dnalines= 0;
  1160.   char      sp[256];
  1161.   long      linestart=0;
  1162.   int     maxlines2check=500;
  1163.  
  1164. #define ReadOneLine(sp)   \
  1165.   { done |= (feof(fseq)); \
  1166.     readline( fseq, sp, &linestart);  \
  1167.     if (!done) { splen = strlen(sp); ++nlines; } }
  1168.  
  1169.   *skiplines = 0;
  1170.   *error = 0;
  1171.   if (fseq == NULL) { *error = eFileNotFound;  return kNoformat; }
  1172.  
  1173.   while ( !done ) {
  1174.     ReadOneLine(sp);
  1175.  
  1176.     /* check for mailer head & skip past if found */
  1177.     if (nlines < 4 && !done) {
  1178.       if ((strstr(sp,"From ") == sp) || (strstr(sp,"Received:") == sp)) {
  1179.         do {
  1180.           /* skip all lines until find one blank line */
  1181.           ReadOneLine(sp);
  1182.           if (!done) for (k=0; (k<splen) && (sp[k]==' '); k++) ;
  1183.           } while ((!done) && (k < splen));
  1184.         *skiplines = nlines; /* !? do we want #lines or #bytes ?? */
  1185.         }
  1186.       }
  1187.  
  1188.     if (sp==NULL || *sp==0)
  1189.       ; /* nada */
  1190.  
  1191.     /* high probability identities: */
  1192.  
  1193.     else if ( strstr(sp,"MSF:") && strstr(sp,"Type:") && strstr(sp,"Check:") )
  1194.       gotMSF= true;
  1195.  
  1196.     else if ((strstr(sp,"..") != NULL) && (strstr(sp,"Check:") != NULL))
  1197.       gotuw= true;
  1198.  
  1199.     else if (strstr(sp,"identity:   Data:") != NULL)
  1200.       gotolsen= true;
  1201.  
  1202.     else if ( strstr(sp,"::=") &&
  1203.       (strstr(sp,"Bioseq") ||       /* Bioseq or Bioseq-set */
  1204.        strstr(sp,"Seq-entry") ||
  1205.        strstr(sp,"Seq-submit") ) )  /* can we read submit format? */
  1206.           gotasn1= true;
  1207.  
  1208.     else if ( strstr(sp,"#NEXUS") == sp )
  1209.       gotpaup= true;
  1210.  
  1211.     /* uncertain identities: */
  1212.  
  1213.     else if (*sp ==';') {
  1214.       if (strstr(sp,"Strider") !=NULL) foundStrider= true;
  1215.       else foundIG= true;
  1216.       }
  1217.  
  1218.     else if (strstr(sp,"LOCUS") == sp)
  1219.       foundGB= true;
  1220.     else if (strstr(sp,"ORIGIN") == sp)
  1221.       foundGB= true;
  1222.  
  1223.     else if (strstr(sp,"ENTRY   ") == sp)  /* ? also (strcmp(sp,"\\\\\\")==0) */
  1224.       foundPIR= true;
  1225.     else if (strstr(sp,"SEQUENCE") == sp)
  1226.       foundPIR= true;
  1227.  
  1228.     else if (*sp == '>') {
  1229.       if (sp[3] == ';') foundNBRF= true;
  1230.       else foundPearson= true;
  1231.       }
  1232.  
  1233.     else if (strstr(sp,"ID   ") == sp)
  1234.       foundEMBL= true;
  1235.     else if (strstr(sp,"SQ   ") == sp)
  1236.       foundEMBL= true;
  1237.  
  1238.     else if (*sp == '(')
  1239.       foundZuker= true;
  1240.  
  1241.     else {
  1242.       if (nlines - *skiplines == 1) {
  1243.         int ispp= 0, ilen= 0;
  1244.         sscanf( sp, "%d%d", &ispp, &ilen);
  1245.         if (ispp > 0 && ilen > 0) isphylip= true;
  1246.         }
  1247.       else if (isphylip && nlines - *skiplines == 2) {
  1248.         int  tseq;
  1249.         tseq= getseqtype(sp+10, strlen(sp+10));
  1250.         if ( isalpha(*sp)     /* 1st letter in 2nd line must be of a name */
  1251.          && (tseq != kOtherSeq))  /* sequence section must be okay */
  1252.             foundPhylip= true;
  1253.         }
  1254.  
  1255.       for (k=0, isfitch= true; isfitch & (k < splen); k++) {
  1256.         if (k % 4 == 0) isfitch &= (sp[k] == ' ');
  1257.         else isfitch &= (sp[k] != ' ');
  1258.         }
  1259.       if (isfitch & (splen > 20)) foundFitch= true;
  1260.  
  1261.       /* kRNA && kDNA are fairly certain...*/
  1262.       switch (getseqtype( sp, splen)) {
  1263.         case kOtherSeq: otherlines++; break;
  1264.         case kAmino   : if (splen>20) aminolines++; break;
  1265.         case kDNA     :
  1266.         case kRNA     : if (splen>20) dnalines++; break;
  1267.         case kNucleic : break; /* not much info ? */
  1268.         }
  1269.  
  1270.       }
  1271.  
  1272.                     /* pretty certain */
  1273.     if (gotolsen) {
  1274.       format= kOlsen;
  1275.       done= true;
  1276.       }
  1277.     else if (gotMSF) {
  1278.       format= kMSF;
  1279.       done= true;
  1280.       }
  1281.     else if (gotasn1) {
  1282.       /* !! we need to look further and return  kASNseqentry | kASNseqset */
  1283.       /*
  1284.         seqentry key is Seq-entry ::=
  1285.         seqset key is Bioseq-set ::=
  1286.         ?? can't read these yet w/ ncbi tools ??
  1287.           Seq-submit ::=
  1288.           Bioseq ::=  << fails both bioseq-seq and seq-entry parsers !
  1289.       */
  1290.       if (strstr(sp,"Bioseq-set")) format= kASNseqset;
  1291.       else if (strstr(sp,"Seq-entry")) format= kASNseqentry;
  1292.       else format= kASN1;  /* other form, we can't yet read... */
  1293.       done= true;
  1294.       }
  1295.     else if (gotpaup) {
  1296.       format= kPAUP;
  1297.       done= true;
  1298.       }
  1299.  
  1300.     else if (gotuw) {
  1301.       if (foundIG) format= kIG;  /* a TOIG file from GCG for certain */
  1302.       else format= kGCG;
  1303.       done= true;
  1304.       }
  1305.  
  1306.     else if ((dnalines > 1) || done || (nlines > maxlines2check)) {
  1307.           /* decide on most likely format */
  1308.           /* multichar idents: */
  1309.       if (foundStrider) format= kStrider;
  1310.       else if (foundGB) format= kGenBank;
  1311.       else if (foundPIR) format= kPIR;
  1312.       else if (foundEMBL) format= kEMBL;
  1313.       else if (foundNBRF) format= kNBRF;
  1314.           /* single char idents: */
  1315.       else if (foundIG) format= kIG;
  1316.       else if (foundPearson) format= kPearson;
  1317.       else if (foundZuker) format= kZuker;
  1318.           /* digit ident: */
  1319.       else if (foundPhylip) format= kPhylip;
  1320.           /* spacing ident: */
  1321.       else if (foundFitch) format= kFitch;
  1322.           /* no format chars: */
  1323.       else if (otherlines > 0) format= kUnknown;
  1324.       else if (dnalines > 1) format= kPlain;
  1325.       else if (aminolines > 1) format= kPlain;
  1326.       else format= kUnknown;
  1327.  
  1328.       done= true;
  1329.       }
  1330.  
  1331.     /* need this for possible long header in olsen format */
  1332.      else if (strstr(sp,"): ") != NULL)
  1333.        maxlines2check++;
  1334.     }
  1335.  
  1336.   if (format == kPhylip) {
  1337.     /* check for interleaved or sequential -- really messy */
  1338.     int tname, tseq;
  1339.     long i, j, nspp= 0, nlen= 0, ilen, leaf= 0, seq= 0;
  1340.     char  *ps;
  1341.  
  1342.     rewind(fseq);
  1343.     for (i=0; i < *skiplines; i++) ReadOneLine(sp);
  1344.     nlines= 0;
  1345.     ReadOneLine(sp);
  1346.     sscanf( sp, "%d%d", &nspp, &nlen);
  1347.     ReadOneLine(sp); /* 1st seq line */
  1348.     for (ps= sp+10, ilen=0; *ps!=0; ps++) if (isprint(*ps)) ilen++;
  1349.  
  1350.     for (i= 1; i<nspp; i++) {
  1351.       ReadOneLine(sp);
  1352.  
  1353.       tseq= getseqtype(sp+10, strlen(sp+10));
  1354.       tname= getseqtype(sp, 10);
  1355.       for (j=0, ps= sp; isspace(*ps) && j<10; ps++, j++);
  1356.       for (ps= sp; *ps!=0; ps++) if (isprint(*ps)) ilen++;
  1357.  
  1358.       /* find probable interleaf or sequential ... */
  1359.       if (j>=9) seq += 10; /* pretty certain not ileaf */
  1360.       else {
  1361.         if (tseq != tname) leaf++; else seq++;
  1362.         if (tname == kDNA || tname == kRNA) seq++; else leaf++;
  1363.         }
  1364.  
  1365.       if (ilen <= nlen && j<9) {
  1366.         if (tname == kOtherSeq) leaf += 10;
  1367.         else if (tname == kAmino || tname == kDNA || tname == kRNA) seq++; else leaf++;
  1368.         }
  1369.       else if (ilen > nlen) {
  1370.         ilen= 0;
  1371.         }
  1372.       }
  1373.     for ( nspp *= 2 ; i<nspp; i++) {  /* this should be only bases if interleaf */
  1374.       ReadOneLine(sp);
  1375.  
  1376.       tseq= getseqtype(sp+10, strlen(sp+10));
  1377.       tname= getseqtype(sp, 10);
  1378.       for (ps= sp; *ps!=0; ps++) if (isprint(*ps)) ilen++;
  1379.       for (j=0, ps= sp; isspace(*ps) && j<10; ps++, j++);
  1380.       if (j<9) {
  1381.         if (tname == kOtherSeq) seq += 10;
  1382.         if (tseq != tname) seq++; else leaf++;
  1383.         if (tname == kDNA || tname == kRNA) leaf++; else seq++;
  1384.         }
  1385.       if (ilen > nlen) {
  1386.         if (j>9) leaf += 10; /* must be a name here for sequent */
  1387.         else if (tname == kOtherSeq) seq += 10;
  1388.         ilen= 0;
  1389.         }
  1390.       }
  1391.  
  1392.     if (leaf > seq) format= kPhylip4;
  1393.     else format= kPhylip2;
  1394.     }
  1395.  
  1396.   return(format);
  1397. #undef  ReadOneLine
  1398. } /* SeqFileFormat */
  1399.  
  1400.  
  1401.  
  1402.  
  1403. unsigned long GCGchecksum( const char *seq, const long seqlen, unsigned long *checktotal)
  1404. /* GCGchecksum */
  1405. {
  1406.   register long  i, check = 0, count = 0;
  1407.  
  1408.   for (i = 0; i < seqlen; i++) {
  1409.     count++;
  1410.     check += count * to_upper(seq[i]);
  1411.     if (count == 57) count = 0;
  1412.     }
  1413.   check %= 10000;
  1414.   *checktotal += check;
  1415.   *checktotal %= 10000;
  1416.   return check;
  1417. }
  1418.  
  1419. /* Table of CRC-32's of all single byte values (made by makecrc.c of ZIP source) */
  1420. const unsigned long crctab[] = {
  1421.   0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
  1422.   0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
  1423.   0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
  1424.   0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
  1425.   0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
  1426.   0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
  1427.   0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
  1428.   0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
  1429.   0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
  1430.   0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
  1431.   0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
  1432.   0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
  1433.   0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
  1434.   0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
  1435.   0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
  1436.   0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
  1437.   0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
  1438.   0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
  1439.   0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
  1440.   0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
  1441.   0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
  1442.   0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
  1443.   0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
  1444.   0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
  1445.   0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
  1446.   0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
  1447.   0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
  1448.   0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
  1449.   0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
  1450.   0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
  1451.   0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
  1452.   0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
  1453.   0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
  1454.   0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
  1455.   0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
  1456.   0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
  1457.   0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
  1458.   0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
  1459.   0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
  1460.   0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
  1461.   0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
  1462.   0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
  1463.   0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
  1464.   0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
  1465.   0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
  1466.   0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
  1467.   0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
  1468.   0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
  1469.   0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
  1470.   0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
  1471.   0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
  1472.   0x2d02ef8dL
  1473. };
  1474.  
  1475. unsigned long CRC32checksum(const char *seq, const long seqlen, unsigned long *checktotal)
  1476. /*CRC32checksum: modified from CRC-32 algorithm found in ZIP compression source */
  1477. {
  1478.   register unsigned long c = 0xffffffffL;
  1479.   register long n = seqlen;
  1480.  
  1481.   while (n--) c = crctab[((int)c ^ (to_upper(*seq++))) & 0xff] ^ (c >> 8);
  1482.   c= c ^ 0xffffffffL;
  1483.   *checktotal += c;
  1484.   return c;
  1485. }
  1486.  
  1487.  
  1488.  
  1489.  
  1490. short getseqtype( const char *seq, const long seqlen)
  1491. { /* return sequence kind: kDNA, kRNA, kProtein, kOtherSeq, ??? */
  1492.   char  c;
  1493.   short i, maxtest;
  1494.   short na = 0, aa = 0, po = 0, nt = 0, nu = 0, ns = 0, no = 0;
  1495.  
  1496.   maxtest = min(300, seqlen);
  1497.   for (i = 0; i < maxtest; i++) {
  1498.     c = to_upper(seq[i]);
  1499.     if (strchr(protonly, c)) po++;
  1500.     else if (strchr(primenuc,c)) {
  1501.       na++;
  1502.       if (c == 'T') nt++;
  1503.       else if (c == 'U') nu++;
  1504.       }
  1505.     else if (strchr(aminos,c)) aa++;
  1506.     else if (strchr(seqsymbols,c)) ns++;
  1507.     else if (isalpha(c)) no++;
  1508.     }
  1509.  
  1510.   if ((no > 0) || (po+aa+na == 0)) return kOtherSeq;
  1511.   /* ?? test for probability of kOtherSeq ?, e.g.,
  1512.   else if (po+aa+na / maxtest < 0.70) return kOtherSeq;
  1513.   */
  1514.   else if (po > 0) return kAmino;
  1515.   else if (aa == 0) {
  1516.     if (nu > nt) return kRNA;
  1517.     else return kDNA;
  1518.     }
  1519.   else if (na > aa) return kNucleic;
  1520.   else return kAmino;
  1521. } /* getseqtype */
  1522.  
  1523.  
  1524. char* compressSeq( const char gapc, const char *seq, const long seqlen, long *newlen)
  1525. {
  1526.   register char *a, *b;
  1527.   register long i;
  1528.   char  *newseq;
  1529.  
  1530.   *newlen= 0;
  1531.   if (!seq) return NULL;
  1532.   newseq = (char*) malloc(seqlen+1);
  1533.   if (!newseq) return NULL;
  1534.   for (a= (char*)seq, b=newseq, i=0; *a!=0; a++)
  1535.     if (*a != gapc) {
  1536.       *b++= *a;
  1537.       i++;
  1538.       }
  1539.   *b= '\0';
  1540.   newseq = (char*) realloc(newseq, i+1);
  1541.   *newlen= i;
  1542.   return newseq;
  1543. }
  1544.  
  1545.  
  1546.  
  1547. /***
  1548. char *rtfhead = "{\\rtf1\\defformat\\mac\\deff2 \
  1549. {\\fonttbl\
  1550.   {\\f1\\fmodern Courier;}{\\f2\\fmodern Monaco;}\
  1551.   {\\f3\\fswiss Helvetica;}{\\f4\\fswiss Geneva;}\
  1552.   {\\f5\\froman Times;}{\\f6\\froman Palatino;}\
  1553.   {\\f7\\froman New Century Schlbk;}{\\f8\\ftech Symbol;}}\
  1554. {\\stylesheet\
  1555.   {\\s1 \\f5\\fs20 \\sbasedon0\\snext1 name;}\
  1556.   {\\s2 \\f3\\fs20 \\sbasedon0\\snext2 num;}\
  1557.   {\\s3 \\f1\\f21 \\sbasedon0\\snext3 seq;}}";
  1558.  
  1559. char *rtftail = "}";
  1560. ****/
  1561.  
  1562. short writeSeq(FILE *outf, const char *seq, const long seqlen,
  1563.                 const short outform, const char *seqid)
  1564. /* dump sequence to standard output */
  1565. {
  1566.   const short kSpaceAll = -9;
  1567. #define kMaxseqwidth  250
  1568.  
  1569.   boolean baseonlynum= false; /* nocountsymbols -- only count true bases, not "-" */
  1570.   short  numline = 0; /* only true if we are writing seq number line (for interleave) */
  1571.   boolean numright = false, numleft = false;
  1572.   boolean nameright = false, nameleft = false;
  1573.   short   namewidth = 8, numwidth = 8;
  1574.   short   spacer = 0, width  = 50, tab = 0;
  1575.   /* new parameters: width, spacer, those above... */
  1576.  
  1577.   short linesout = 0, seqtype = kNucleic;
  1578.   long  i, j, l, l1, ibase;
  1579.   char  idword[31], endstr[10];
  1580.   char  seqnamestore[128], *seqname = seqnamestore;
  1581.   char  s[kMaxseqwidth], *cp;
  1582.   char  nameform[10], numform[10], nocountsymbols[10];
  1583.   unsigned long checksum = 0, checktotal = 0;
  1584.  
  1585.   gPretty.atseq++;
  1586.   skipwhitespace(seqid);
  1587.   l = min(128, strlen(seqid));
  1588.   strncpy( seqnamestore, seqid, l);
  1589.   seqname[l] = 0;
  1590.  
  1591.   sscanf( seqname, "%30s", idword);
  1592.   sprintf(numform, "%d", seqlen);
  1593.   numwidth= strlen(numform)+1;
  1594.   nameform[0]= '\0';
  1595.  
  1596.   if (strstr(seqname,"checksum") != NULL) {
  1597.     cp = strstr(seqname,"bases");
  1598.     if (cp!=NULL) {
  1599.       for ( ; (cp!=seqname) && (*cp!=','); cp--) ;
  1600.       if (cp!=seqname) *cp=0;
  1601.       }
  1602.     }
  1603.  
  1604.   strcpy( endstr,"");
  1605.   l1 = 0;
  1606.  
  1607.   if (outform == kGCG || outform == kMSF)
  1608.     checksum = GCGchecksum(seq, seqlen, &checktotal);
  1609.   else
  1610.     checksum = seqchecksum(seq, seqlen, &checktotal);
  1611.  
  1612.   switch (outform) {
  1613.  
  1614.     case kPlain:
  1615.     case kUnknown:    /* no header, just sequence */
  1616.       strcpy(endstr,"\n"); /* end w/ extra blank line */
  1617.       break;
  1618.  
  1619.     case kOlsen:  /* Olsen seq. editor takes plain nucs OR Genbank  */
  1620.     case kGenBank:
  1621.       fprintf(outf,"LOCUS       %s       %d bp\n", idword, seqlen);
  1622.       fprintf(outf,"DEFINITION  %s, %d bases, %X checksum.\n", seqname, seqlen, checksum);
  1623.    /* fprintf(outf,"ACCESSION   %s\n", accnum); */
  1624.       fprintf(outf,"ORIGIN      \n");
  1625.       spacer = 11;
  1626.       numleft = true;
  1627.       numwidth = 8;  /* dgg. 1Feb93, patch for GDE fail to read short numwidth */
  1628.       strcpy(endstr, "\n//");
  1629.       linesout += 4;
  1630.       break;
  1631.  
  1632.     case kPIR:
  1633.       /* somewhat like genbank... \\\*/
  1634.       /* fprintf(outf,"\\\\\\\n"); << only at top of file, not each entry... */
  1635.       fprintf(outf,"ENTRY           %s \n", idword);
  1636.       fprintf(outf,"TITLE           %s, %d bases, %X checksum.\n", seqname, seqlen, checksum);
  1637.    /* fprintf(outf,"ACCESSION       %s\n", accnum); */
  1638.       fprintf(outf,"SEQUENCE        \n");
  1639.       numwidth = 7;
  1640.       width= 30;
  1641.       spacer = kSpaceAll;
  1642.       numleft = true;
  1643.       strcpy(endstr, "\n///");
  1644.       /* run a top number line for PIR */
  1645.       for (j=0; j<numwidth; j++) fputc(' ',outf);
  1646.       for (j= 5; j<=width; j += 5) fprintf(outf,"%10d",j);
  1647.       fputc('\n',outf);
  1648.       linesout += 5;
  1649.       break;
  1650.  
  1651.     case kNBRF:
  1652.       if (getseqtype(seq, seqlen) == kAmino)
  1653.         fprintf(outf,">P1;%s\n", idword);
  1654.       else
  1655.         fprintf(outf,">DL;%s\n", idword);
  1656.       fprintf(outf,"%s, %d bases, %X checksum.\n", seqname, seqlen, checksum);
  1657.       spacer = 11;
  1658.       strcpy(endstr,"*\n");
  1659.       linesout += 3;
  1660.       break;
  1661.  
  1662.     case kEMBL:
  1663.       fprintf(outf,"ID   %s\n", idword);
  1664.   /*  fprintf(outf,"AC   %s\n", accnum); */
  1665.       fprintf(outf,"DE   %s, %d bases, %X checksum.\n", seqname, seqlen, checksum);
  1666.       fprintf(outf,"SQ             %d BP\n", seqlen);
  1667.       strcpy(endstr, "\n//"); /* 11Oct90: bug fix*/
  1668.       tab = 4;     /** added 31jan91 */
  1669.       spacer = 11; /** added 31jan91 */
  1670.       width = 60;
  1671.       linesout += 4;
  1672.       break;
  1673.  
  1674.     case kGCG:
  1675.       fprintf(outf,"%s\n", seqname);
  1676.    /* fprintf(outf,"ACCESSION   %s\n", accnum); */
  1677.       fprintf(outf,"    %s  Length: %d  (today)  Check: %d  ..\n", idword, seqlen, checksum);
  1678.       spacer = 11;
  1679.       numleft = true;
  1680.       strcpy(endstr, "\n");  /* this is insurance to help prevent misreads at eof */
  1681.       linesout += 3;
  1682.       break;
  1683.  
  1684.     case kStrider: /* ?? map ?*/
  1685.       fprintf(outf,"; ### from DNA Strider ;-)\n");
  1686.       fprintf(outf,"; DNA sequence  %s, %d bases, %X checksum.\n;\n", seqname, seqlen, checksum);
  1687.       strcpy(endstr, "\n//");
  1688.       linesout += 3;
  1689.       break;
  1690.  
  1691.     case kFitch:
  1692.       fprintf(outf,"%s, %d bases, %X checksum.\n", seqname, seqlen, checksum);
  1693.       spacer = 4;
  1694.       width = 60;
  1695.       linesout += 1;
  1696.       break;
  1697.  
  1698.     case kPhylip2:
  1699.     case kPhylip4:
  1700.       /* this is version 3.2/3.4 -- simplest way to write
  1701.         version 3.3 is to write as version 3.2, then
  1702.         re-read file and interleave the species lines */
  1703.       if (strlen(idword)>10) idword[10] = 0;
  1704.       fprintf(outf,"%-10s  ",idword);
  1705.       l1  = -1;
  1706.       tab = 12;
  1707.       spacer = 11;
  1708.       break;
  1709.  
  1710.     case kASN1:
  1711.       seqtype= getseqtype(seq, seqlen);
  1712.       switch (seqtype) {
  1713.         case kDNA     : cp= "dna"; break;
  1714.         case kRNA     : cp= "rna"; break;
  1715.         case kNucleic : cp= "na"; break;
  1716.         case kAmino   : cp= "aa"; break;
  1717.         case kOtherSeq: cp= "not-set"; break;
  1718.         }
  1719.       fprintf(outf,"  seq {\n");
  1720.       fprintf(outf,"    id { local id %d },\n", gPretty.atseq);
  1721.       fprintf(outf,"    descr { title \"%s\" },\n", seqid);
  1722.       fprintf(outf,"    inst {\n");
  1723.       fprintf(outf,"      repr raw, mol %s, length %d, topology linear,\n", cp, seqlen);
  1724.       fprintf(outf,"      seq-data\n");
  1725.       if (seqtype == kAmino)
  1726.         fprintf(outf,"        iupacaa \"");
  1727.       else
  1728.         fprintf(outf,"        iupacna \"");
  1729.       l1  = 17;
  1730.       spacer = 0;
  1731.       width  = 78;
  1732.       tab  = 0;
  1733.       strcpy(endstr,"\"\n      } } ,");
  1734.       linesout += 7;
  1735.       break;
  1736.  
  1737.     case kPAUP:
  1738.       nameleft= true;
  1739.       namewidth = 9;
  1740.       spacer = 21;
  1741.       width  = 100;
  1742.       tab  = 0; /* 1; */
  1743.       /* strcpy(endstr,";\nend;"); << this is end of all seqs.. */
  1744.       /* do a header comment line for paup */
  1745.       fprintf(outf,"[Name: %-16s  Len:%6d  Check: %8X]\n", idword, seqlen, checksum);
  1746.       linesout += 1;
  1747.       break;
  1748.  
  1749.     case kPretty:
  1750.       numline= gPretty.numline;
  1751.       baseonlynum= gPretty.baseonlynum;
  1752.       namewidth = gPretty.namewidth;
  1753.       numright = gPretty.numright;
  1754.       numleft = gPretty.numleft;
  1755.       nameright = gPretty.nameright;
  1756.       nameleft = gPretty.nameleft;
  1757.       spacer = gPretty.spacer + 1;
  1758.       width  = gPretty.seqwidth;
  1759.       tab  = gPretty.tab;
  1760.       /* also add rtf formatting w/ font, size, style */
  1761.       if (gPretty.nametop) {
  1762.         fprintf(outf,"Name: %-16s  Len:%6d  Check: %8X\n", idword, seqlen, checksum);
  1763.         linesout++;
  1764.         }
  1765.       break;
  1766.  
  1767.     case kMSF:
  1768.       fprintf(outf," Name: %-16s Len:%6d  Check: %5d  Weight:  1.00\n",
  1769.                     idword, seqlen, checksum);
  1770.       linesout++;
  1771.       nameleft= true;
  1772.       namewidth= 15; /* need MAX namewidth here... */
  1773.       sprintf(nameform, "%%+%ds ",namewidth);
  1774.       spacer = 11;
  1775.       width  = 50;
  1776.       tab = 0; /* 1; */
  1777.       break;
  1778.  
  1779.     case kIG:
  1780.       fprintf(outf,";%s, %d bases, %X checksum.\n", seqname, seqlen, checksum);
  1781.       fprintf(outf,"%s\n", idword);
  1782.       strcpy(endstr,"1"); /* == linear dna */
  1783.       linesout += 2;
  1784.       break;
  1785.  
  1786.     default :
  1787.     case kZuker: /* don't attempt Zuker's ftn format */
  1788.     case kPearson:
  1789.       fprintf(outf,">%s, %d bases, %X checksum.\n", seqname, seqlen, checksum);
  1790.       linesout += 1;
  1791.       break;
  1792.     }
  1793.  
  1794.   if (*nameform==0) sprintf(nameform, "%%%d.%ds ",namewidth,namewidth);
  1795.   if (numline) sprintf(numform, "%%%ds ",numwidth);
  1796.   else sprintf(numform, "%%%dd ",numwidth);
  1797.   strcpy( nocountsymbols, kNocountsymbols);
  1798.   if (baseonlynum) {
  1799.     if (strchr(nocountsymbols,gPretty.gapchar)==NULL) {
  1800.       strcat(nocountsymbols," ");
  1801.       nocountsymbols[strlen(nocountsymbols)-1]= gPretty.gapchar;
  1802.       }
  1803.     if (gPretty.domatch && (cp=strchr(nocountsymbols,gPretty.matchchar))!=NULL) {
  1804.       *cp= ' ';
  1805.       }
  1806.     }
  1807.  
  1808.   if (numline) {
  1809.    *idword= 0;
  1810.    }
  1811.  
  1812.   width = min(width,kMaxseqwidth);
  1813.   for (i=0, l=0, ibase = 1; i < seqlen; ) {
  1814.  
  1815.     if (l1 < 0) l1 = 0;
  1816.     else if (l1 == 0) {
  1817.       if (nameleft) fprintf(outf, nameform, idword);
  1818.       if (numleft) { if (numline) fprintf(outf, numform, "");
  1819.                     else fprintf(outf, numform, ibase);}
  1820.       for (j=0; j<tab; j++) fputc(' ',outf);
  1821.       }
  1822.  
  1823.     l1++;                 /* don't count spaces for width*/
  1824.     if (numline) {
  1825.       if (spacer==kSpaceAll || (spacer != 0 && (l+1) % spacer == 1)) {
  1826.         if (numline==1) fputc(' ',outf);
  1827.         s[l++] = ' ';
  1828.         }
  1829.       if (l1 % 10 == 1 || l1 == width) {
  1830.         if (numline==1) fprintf(outf,"%-9d ",i+1);
  1831.         s[l++]= '|'; /* == put a number here */
  1832.         }
  1833.       else s[l++]= ' ';
  1834.       i++;
  1835.       }
  1836.  
  1837.     else {
  1838.       if (spacer==kSpaceAll || (spacer != 0 && (l+1) % spacer == 1))
  1839.         s[l++] = ' ';
  1840.       if (!baseonlynum) ibase++;
  1841.       else if (0==strchr(nocountsymbols,seq[i])) ibase++;
  1842.       s[l++] = seq[i++];
  1843.       }
  1844.  
  1845.     if (l1 == width || i == seqlen) {
  1846.       if (outform==kPretty) for ( ; l1<width; l1++) {
  1847.         if (spacer==kSpaceAll || (spacer != 0 && (l+1) % spacer == 1))
  1848.           s[l++] = ' ';
  1849.         s[l++]=' '; /* pad w/ blanks */
  1850.         }
  1851.       s[l] = '\0';
  1852.       l = 0; l1 = 0;
  1853.  
  1854.       if (numline) {
  1855.         if (numline==2) fprintf(outf,"%s",s); /* finish numberline ! and | */
  1856.         }
  1857.       else {
  1858.         if (i == seqlen) fprintf(outf,"%s%s",s,endstr);
  1859.         else fprintf(outf,"%s",s);
  1860.         if (numright || nameright) fputc(' ',outf);
  1861.         if (numright)  fprintf(outf,numform, ibase-1);
  1862.         if (nameright) fprintf(outf, nameform,idword);
  1863.         }
  1864.       fputc('\n',outf);
  1865.       linesout++;
  1866.       }
  1867.     }
  1868.   return linesout;
  1869. }  /*writeSeq*/
  1870.  
  1871.  
  1872.  
  1873. /* End file: ureadseq.c */
  1874.