home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / TIERRA40.ZIP / BEAGLE / RUN_INFO.C < prev    next >
C/C++ Source or Header  |  1992-09-11  |  20KB  |  732 lines

  1. /* run_info.c  27-3-92  makes run_info file for tierra.run, with genotypes */
  2. /*** Beagle Explorer: Version 3.1  Copyright (c) 1990, 1991, 1992  Tom Ray ***/
  3.  
  4. #include "stdio.h"
  5. #include "stdlib.h"
  6. #include "string.h"
  7. #include "dir.h"
  8. #include "alloc.h"
  9. #include "ctype.h"
  10.  
  11. typedef unsigned int   Uint;
  12. typedef unsigned long  Ulong;
  13.  
  14. struct last_out {
  15.     Ulong  time;
  16.     Ulong  ctime;
  17.     char   bd;
  18.     Uint   size;
  19.     char   label[4];
  20.     } ;
  21.  
  22. struct pop_dat {
  23.     long  max; /* maximum population of this genotype */
  24.     long  min; /* minimum population of this genotype */
  25.     long  beg; /* beginning population of this genotype */
  26.     long  end; /* current population of this genotype */
  27.     } ;
  28.  
  29. struct gene_dat {
  30.     struct tnode  *t;
  31.     long          index;
  32.     } ;
  33.  
  34. struct snode {
  35.     long             max;  /* max pop value upon which tree is sorted */
  36.     long             num;  /* number of genotypes of this max value */
  37.     long             gsiz; /* allocated size of *gd array */
  38.     struct gene_dat  *g;
  39.     struct snode     *l;  /* left sub-tree */
  40.     struct snode     *r;  /* right sub-tree */
  41.     } ;
  42.  
  43. struct tnode {
  44.     long            size;  /* genome size */
  45.     struct pop_dat  sd; /* pop_dat for this size class */
  46.     int             gsize; /* allocated size of *g array */
  47.     struct pop_dat  *g; /* array of pop_dat structures */
  48.     struct tnode    *l;  /* left sub-tree */
  49.     struct tnode    *r;  /* right sub-tree */
  50.     } ;
  51.  
  52. int  genotypes, update;
  53. char  directory[80];
  54. char  infile[13];
  55. char  data[81];
  56. FILE  *inf, *souf, *gouf;
  57.  
  58. struct pop_dat  totals;
  59. struct last_out  rlo;
  60. Ulong  sctime, stime, tctime, ttime;
  61. unsigned  _stklen = 60000;
  62.  
  63. int   main(void), temp_info_chk_g(void);
  64. int t_read(char  data[], struct last_out  *lo, int  *first, int  *genotypes);
  65. void  gtierun(void);
  66. struct tnode * AddTree(struct tnode  *p, struct last_out  *lo);
  67. struct snode * Tree2Tree(struct tnode  *t, struct snode  *s, int  index);
  68. struct snode * AddMaxTree(struct tnode  *t, int  index, struct snode  *s);
  69. void OutSearchTree(struct snode  *s, FILE  *ouf, int  *out_num, int  update);
  70. void CountTree(struct snode  *s, int  *num);
  71. void OutUpdate(struct snode  *s, FILE  *ouf, int  update);
  72. void FreeSTree(struct snode  *p);
  73. void FreeTTree(struct tnode  *p);
  74. struct tnode * oldPruneTree(struct tnode  *p, struct tnode  *root);
  75. void PruneTree(struct tnode  *p);
  76. struct tnode * AddPrunedTree(struct tnode  *r, struct tnode *p);
  77. struct tnode * DoUpdate(struct tnode  *p, int  update);
  78. struct tnode * AddFragTree(struct tnode *p, long size, char lbl[], long end);
  79. void ZeroTree(struct tnode  *p);
  80. void StartFragment(char  data[], struct last_out  *lo,
  81.     struct tnode  **uroot, struct tnode  **troot, int  c);
  82.  
  83. int Lbl2Int(char  s[])
  84. {   if(s[0] == '-') return 0;
  85.     return 1 + (s[2]- 'a') + (26 * (s[1] - 'a')) + (676 * (s[0] - 'a'));
  86. }
  87.  
  88. void Int2Lbl(int  i, char  s[])
  89. {   if(!i)
  90.     {   strcpy(s,"---");
  91.         return;
  92.     }
  93.     i--;
  94.     s[0] = 'a' + i / 676;
  95.     i %= 676;
  96.     s[1] = 'a' + i / 26;
  97.     i %= 26;
  98.     s[2] = 'a' + i;
  99.     s[3] = 0;
  100. }
  101.  
  102. int main(void)
  103. {   char  buf[80];
  104.  
  105.     update = 100;
  106.     sprintf(infile,"break.1");
  107.     sprintf(directory,"c:\\tierra\\td");
  108.  
  109.     printf("directory (default: %s) = ", directory);
  110.     gets(buf);
  111.     if (strlen(buf))
  112.         sprintf(directory, "%s", buf);
  113.  
  114.     printf("input file (default: %s) = ", infile);
  115.     gets(buf);
  116.     if (strlen(buf))
  117.         sprintf(infile, "%s", buf);
  118.  
  119.     printf("update frequency (default: %d) = ", update);
  120.     gets(buf);
  121.     if (strlen(buf))
  122.         sscanf(buf, "%d", &update);
  123.  
  124.     if (temp_info_chk_g())
  125.         gtierun();
  126.     return 1;
  127. }
  128.  
  129. int temp_info_chk_g(void)
  130. {   char  path[80];
  131.     int   success;
  132.  
  133.     getcwd(path,79);
  134.     success = chdir(directory);
  135.     chdir(path);
  136.     if(success)
  137.     {   printf("directory %s not found\n", directory);
  138.         return 0;
  139.     }
  140.  
  141.     sprintf(path,"%s\\%s", directory, infile);
  142.     inf = fopen(path,"r");
  143.     if(inf == NULL)
  144.     {   printf("file %s not found\n", path);
  145.         return 0;
  146.     }
  147.     fclose(inf);
  148.  
  149.     return 1;
  150. }
  151.  
  152. void gtierun(void)
  153. {   int  first = 1, upcount = update;
  154.     struct tnode  *uroot = NULL, *troot = NULL;
  155.     Ulong c = 0;
  156.     char   bifile[13];
  157.     int    binum = 1;
  158.  
  159.     sctime = stime = tctime = ttime = 0;
  160.     rlo.time = rlo.ctime = rlo.size = 0;
  161.     sscanf(infile,"%[^.]", bifile);
  162.     sprintf(data,"%s\\%s", directory, infile);
  163.     inf = fopen(data,"r");
  164.     if(inf == NULL)
  165.     {   printf("input file %s not found\n", data);
  166.         return ;
  167.     }
  168.     sprintf(data,"%s\\run_info", directory);
  169.     souf = fopen(data,"w");
  170.     sprintf(data,"%s\\run_info.g", directory);
  171.     gouf = fopen(data,"w");
  172.     for(;;)
  173.     {   if(fgets(data,80,inf) == NULL)
  174.         {   fclose(inf);
  175.             binum++;
  176.             sprintf(data,"%s/%s.%d", directory, bifile, binum);
  177.             inf = fopen(data,"r");
  178.             if(inf == NULL)
  179.                 break ;
  180.             if(fgets(data,80,inf) == NULL)
  181.                 break ;
  182.         }
  183.         if(!t_read(data, &rlo, &first, &genotypes))
  184.         {   StartFragment(data,&rlo,&uroot,&troot,c);
  185.             sctime = rlo.ctime; stime = rlo.time;
  186.             if(!c) { tctime = sctime; ttime = stime; }
  187.             while(rlo.ctime > upcount) upcount += update;
  188.             continue;
  189.         }
  190.         if(!(c%1000LU))
  191.             printf("Time = %5lu,%06lu  Coreleft = %6lu\r",
  192.                 rlo.ctime, rlo.time, coreleft());
  193.         c++;
  194.         if(update && rlo.ctime >= upcount)
  195.         {   upcount += update;
  196.             uroot = DoUpdate(uroot,update);
  197.             sctime = rlo.ctime; stime = rlo.time;
  198.         }
  199.         if(update) uroot = AddTree(uroot,&rlo);
  200.         troot = AddTree(troot,&rlo);
  201.     }
  202.     fclose(inf);
  203.     if(update) uroot = DoUpdate(uroot,update);
  204.     FreeTTree(uroot);
  205.     sctime = tctime; stime = ttime;
  206.     troot = DoUpdate(troot,0);
  207.     FreeTTree(troot);
  208.     fclose(souf); fclose(gouf);
  209.     if(!genotypes)
  210.     {   sprintf(data,"del %s\\run_info.g", directory);
  211.         system(data);
  212.     }
  213. }
  214.  
  215. struct tnode * AddTree(struct tnode  *p, struct last_out  *lo)
  216. {   int  i, j, osize;
  217.     struct pop_dat  *pd;
  218.  
  219.     if(p == NULL)
  220.     {   if(lo->bd == 'd')
  221.         {   printf("new node is a death, exiting\n");
  222.             exit(0);
  223.         }
  224.         p = (struct tnode  *) calloc(1,sizeof(struct tnode));
  225.         if(p == NULL)
  226.         {   printf("calloc failure, exiting\n");
  227.             exit(0);
  228.         }
  229. /*
  230.         else
  231.             printf("coreleft = %6lu\n", coreleft());
  232. */
  233.         p->size = lo->size;
  234.         p->sd.max = p->sd.end = 1;
  235.         p->sd.min = p->sd.beg = 0;
  236.         if(genotypes)
  237.         {   i = Lbl2Int(lo->label);
  238.             p->gsize = i + 1;
  239.             p->g = (struct pop_dat  *)
  240.                 calloc(p->gsize,sizeof(struct pop_dat));
  241.             if(p->g == NULL)
  242.             {   printf("calloc failure, exiting\n");
  243.                 exit(0);
  244.             }
  245. /*
  246.             else
  247.                 printf("coreleft = %6lu\n", coreleft());
  248. */
  249.             (p->g + i)->end = (p->g + i)->max = 1;
  250.         }
  251.         p->l = p->r = NULL;
  252.     }
  253.     else if(lo->size < p->size)
  254.         p->l = AddTree(p->l,lo);
  255.     else if(lo->size > p->size)
  256.         p->r = AddTree(p->r,lo);
  257.     else
  258.     {   if(genotypes)
  259.         {   i = Lbl2Int(lo->label);
  260.             if(i >= p->gsize)
  261.             {   osize = p->gsize;
  262.                 p->gsize = i + 5;
  263.                 if(p->g == NULL)
  264.                     p->g = (struct pop_dat  *)
  265.                         calloc(p->gsize, sizeof(struct pop_dat));
  266.                 else
  267.                     p->g = (struct pop_dat  *)
  268.                         realloc(p->g, p->gsize * sizeof(struct pop_dat));
  269.                 if(p->g == NULL)
  270.                 {   printf("realloc failure, exiting\n");
  271.                     exit(0);
  272.                 }
  273. /*
  274.                 else
  275.                     printf("coreleft = %6lu\n", coreleft());
  276. */
  277.                 for(j = osize; j < p->gsize; j++)
  278.                 {   pd = p->g + j;
  279.                     pd->max = pd->min = pd->beg = pd->end = 0;
  280.                 }
  281.             }
  282.         }
  283.         if(lo->bd == 'b')
  284.         {   p->sd.end++;
  285.             if(p->sd.end > p->sd.max)
  286.                 p->sd.max = p->sd.end;
  287.             if(genotypes)
  288.             {   pd = p->g + i;
  289.                 pd->end++;
  290.                 if(pd->end > pd->max)
  291.                     pd->max = pd->end;
  292.             }
  293.         }
  294.         else
  295.         {   p->sd.end--;
  296.             if(p->sd.end < p->sd.min)
  297.                 p->sd.min = p->sd.end;
  298.             if(genotypes)
  299.             {   pd = p->g + i;
  300.                 pd->end--;
  301.                 if(pd->end < pd->min)
  302.                     pd->min = pd->end;
  303.             }
  304.         }
  305.     }
  306.     return p;
  307. }
  308.  
  309. struct snode * Tree2Tree(struct tnode  *t, struct snode  *s, int  index)
  310. {   int  i;
  311.  
  312.     if(t != NULL)          /* sort tnode tree into snode tree */
  313.     {   s = Tree2Tree(t->l,s,index);
  314.         if(index) for(i = 0; i < t->gsize; i++)
  315.         {  if((t->g + i)->max > 0)
  316.                s = AddMaxTree(t,i,s);
  317.         }
  318.         else s = AddMaxTree(t,-1,s);
  319.         s = Tree2Tree(t->r,s,index);
  320.     }
  321.     return s;
  322. }
  323.  
  324. struct snode * AddMaxTree(struct tnode  *t, int  index, struct snode  *s)
  325. {   int  i;
  326.     long  osiz;
  327.  
  328.     if(s == NULL)
  329.     {   s = (struct snode  *) calloc(1,sizeof(struct snode));
  330.         if(s == NULL)
  331.         {   printf("calloc failure, exiting\n");
  332.             exit(0);
  333.         }
  334. /*
  335.         else
  336.             printf("coreleft = %6lu\n", coreleft());
  337. */
  338.         if(index == -1) s->max = t->sd.max;
  339.         else s->max = (t->g + index)->max;
  340.         s->num = 1;
  341.         s->gsiz = 1;
  342.         s->g = (struct gene_dat  *) calloc(s->gsiz,sizeof(struct gene_dat));
  343.         if(s->g == NULL)
  344.         {   printf("calloc failure, exiting\n");
  345.             exit(0);
  346.         }
  347. /*
  348.         else
  349.             printf("coreleft = %6lu\n", coreleft());
  350. */
  351.         s->g->t = t;
  352.         s->g->index = index;
  353.         s->l = s->r = NULL;
  354.     }
  355.     else if((index == -1 && (t->sd.max < s->max)) ||
  356.         (index != -1 && ((t->g + index)->max < s->max)))
  357.         s->l = AddMaxTree(t,index,s->l);
  358.     else if((index == -1 && (t->sd.max > s->max)) ||
  359.         (index != -1 && ((t->g + index)->max > s->max)))
  360.         s->r = AddMaxTree(t,index,s->r);
  361.     else
  362.     {   s->num++;
  363.         if(s->num > s->gsiz)
  364.         {   osiz = s->gsiz;
  365.             s->gsiz *= 1.1;
  366.             if(s->gsiz == osiz) s->gsiz++;
  367.             s->g = (struct gene_dat  *)
  368.                 realloc(s->g, s->gsiz * sizeof(struct gene_dat));
  369.             if(s->g == NULL)
  370.             {   printf("realloc failure, exiting\n");
  371.                 exit(0);
  372.             }
  373. /*
  374.             else
  375.                 printf("coreleft = %6lu\n", coreleft());
  376. */
  377.             for(i = osiz; i < s->gsiz; i++)
  378.             {   (s->g + i)->t = NULL;
  379.                 (s->g + i)->index = -1;
  380.             }
  381.         }
  382.         i = s->num - 1;
  383.         (s->g + i)->t = t;
  384.         (s->g + i)->index = index;
  385.     }
  386.     return s;
  387. }
  388.  
  389. void OutSearchTree(struct snode  *s, FILE  *ouf, int  *out_num, int  update)
  390. {   int   i, in;
  391.     char  lbl[4];
  392.     struct pop_dat  *p;
  393.  
  394.     if(update && *out_num <= 0) return;
  395.     if(s != NULL)
  396.     {   OutSearchTree(s->r, ouf, out_num, update);
  397.         if(s->max) for(i = 0; i < s->num; i++)
  398.         {   if(update && *out_num <= 0) return;
  399.             in = (s->g + i)->index;
  400.             if(in == -1)
  401.             {   strcpy(lbl,"---");
  402.                 p = &((s->g + i)->t->sd);
  403.             }
  404.             else
  405.             {   Int2Lbl(in,lbl);
  406.                 p = (s->g + i)->t->g + in;
  407.             }
  408.             fprintf(ouf,"%04ld%s    %ld    %ld    %ld    %ld\n",
  409.                 (s->g + i)->t->size, lbl, p->min, p->max, p->end, p->beg);
  410.             if(update) (*out_num)--;
  411.         }
  412.         OutSearchTree(s->l, ouf, out_num, update);
  413.     }
  414. }
  415.  
  416. void CountTree(struct snode  *s, int  *num)
  417. {   if(s != NULL)
  418.     {   if(s->max) *num += s->num;
  419.         CountTree(s->l,num);
  420.         CountTree(s->r,num);
  421.     }
  422. }
  423.  
  424. void OutUpdate(struct snode  *s, FILE  *ouf, int  update)
  425. {   int  num_sp = 0, out_num = 55;
  426.  
  427.     CountTree(s, &num_sp);
  428.     if(update && num_sp > 55) num_sp = 55;
  429.     out_num = num_sp;
  430.     fprintf(ouf,"num_sp = %d  sctime = %ld  stime = %ld  update = %d\n",
  431.         num_sp, sctime, stime, update);
  432.     fprintf(ouf,"classes    min    max    end    beg\n");
  433.     OutSearchTree(s, ouf, &out_num, update);
  434. }
  435.  
  436. void FreeSTree(struct snode  *p)
  437. {   if(p != NULL)
  438.     {   FreeSTree(p->l);
  439.         FreeSTree(p->r);
  440.         free(p->g);
  441.         free(p);
  442.     }
  443. }
  444.  
  445. void FreeTTree(struct tnode  *p)
  446. {   if(p != NULL)
  447.     {   FreeTTree(p->l);
  448.         FreeTTree(p->r);
  449.         free(p->g);
  450.         free(p);
  451.     }
  452. }
  453.  
  454. struct tnode * oldPruneTree(struct tnode  *p, struct tnode  *root)
  455. {   if(p != NULL)
  456.     {   if(p->sd.end > 0)
  457.             root = AddPrunedTree(root,p);
  458.         oldPruneTree(p->l,root);
  459.         oldPruneTree(p->r,root);
  460.     }
  461.     return root;
  462. }
  463.  
  464. void PruneTree(struct tnode  *p)
  465. {   int  i;
  466.     struct pop_dat  *pd;
  467.  
  468.     if(p != NULL)
  469.     {   if(p->sd.end <= 0)
  470.         {   p->sd.max = p->sd.min = p->sd.beg = p->sd.end = 0;
  471.             if(genotypes)
  472.             {   free(p->g);
  473.                 p->g = NULL;
  474.                 p->gsize = 0;
  475.             }
  476.         }
  477.         else
  478.             p->sd.max = p->sd.beg = p->sd.end; p->sd.min = 0;
  479.         if(genotypes) for(i = 0; i < p->gsize; i++)
  480.         {   pd = p->g + i;
  481.             if(pd->end <= 0)
  482.                 pd->max = pd->min = pd->beg = pd->end = 0;
  483.             else
  484.                 pd->max = pd->beg = pd->end; pd->min = 0;
  485.         }
  486.         PruneTree(p->l);
  487.         PruneTree(p->r);
  488.     }
  489. }
  490.  
  491. struct tnode * AddPrunedTree(struct tnode  *r, struct tnode *p)
  492. {   int  i;
  493.     struct pop_dat  *d;
  494.  
  495.     if(r == NULL)
  496.     {   r = (struct tnode  *) calloc(1,sizeof(struct tnode));
  497.         if(r == NULL)
  498.         {   printf("calloc failure, exiting\n");
  499.             exit(0);
  500.         }
  501. /*
  502.         else
  503.             printf("coreleft = %6lu\n", coreleft());
  504. */
  505.         *r = *p;
  506.         r->sd.beg = r->sd.max = r->sd.end; r->sd.min = 0;
  507.         if(genotypes) for(i = 0; i < r->gsize; i++)
  508.         {   d = r->g + i;
  509.             if(d->end <= 0)
  510.                 d->beg = d->max = d->min = d->end = 0;
  511.             else
  512.             {   d->beg = d->max = d->end; d->min = 0;
  513.             }
  514.         }
  515.         r->l = r->r = NULL;
  516.     }
  517.     else if(p->size < r->size)
  518.         r->l = AddPrunedTree(r->l,p);
  519.     else if(p->size > r->size)
  520.         r->r = AddPrunedTree(r->r,p);
  521.     else if(p->size == r->size)
  522.         printf("size repeated in pruned tree\n");
  523.     return r;
  524. }
  525.  
  526. struct tnode * DoUpdate(struct tnode  *p, int  update)
  527. {   struct snode  *sroot = NULL;
  528.  
  529.     sroot = Tree2Tree(p,sroot,0);
  530.     OutUpdate(sroot, souf, update);
  531.     FreeSTree(sroot);
  532. /*
  533.     printf("coreleft = %6lu\n", coreleft());
  534. */
  535.     sroot = NULL;
  536.     sroot = Tree2Tree(p,sroot,1);
  537.     OutUpdate(sroot, gouf, update);
  538.     FreeSTree(sroot);
  539. /*
  540.     printf("coreleft = %6lu\n", coreleft());
  541. */
  542.     if(!update) return p;
  543.     PruneTree(p);
  544.     return p;
  545. }
  546.  
  547. struct tnode * AddFragTree(struct tnode *p, long size, char lbl[], long end)
  548. {   int  i, j;
  549.     long  osize;
  550.  
  551.     if(p == NULL)
  552.     {   p = (struct tnode  *) calloc(1,sizeof(struct tnode));
  553.         if(p == NULL)
  554.         {   printf("calloc failure, exiting\n");
  555.             exit(0);
  556.         }
  557. /*
  558.         else
  559.             printf("coreleft = %6lu\n", coreleft());
  560. */
  561.         p->size = size;
  562.         p->sd.beg = p->sd.end = p->sd.max = end;
  563.         if(genotypes)
  564.         {   i = Lbl2Int(lbl);
  565.             p->gsize = i + 1;
  566.             p->g = (struct pop_dat  *) calloc(p->gsize,sizeof(struct pop_dat));
  567.             if(p->g == NULL)
  568.             {   printf("calloc failure, exiting\n");
  569.                 exit(0);
  570.             }
  571. /*
  572.             else
  573.                 printf("coreleft = %6lu\n", coreleft());
  574. */
  575.             (p->g + i)->beg = (p->g + i)->end = (p->g + i)->max = end;
  576.         }
  577.         p->l = p->r = NULL;
  578.     }
  579.     else if(size < p->size)
  580.         p->l = AddFragTree(p->l,size,lbl,end);
  581.     else if(size > p->size)
  582.         p->r = AddFragTree(p->r,size,lbl,end);
  583.     else
  584.     {   if(genotypes)
  585.         {   i = Lbl2Int(lbl);
  586.             if(i >= p->gsize)
  587.             {   osize = p->gsize;
  588.                 p->gsize = i + 5;
  589.                 p->g = (struct pop_dat  *)
  590.                     realloc(p->g, p->gsize * sizeof(struct pop_dat));
  591.                 if(p->g == NULL)
  592.                 {   printf("realloc failure, exiting\n");
  593.                     exit(0);
  594.                 }
  595. /*
  596.                 else
  597.                     printf("coreleft = %6lu\n", coreleft());
  598. */
  599.                 for(j = osize; j < p->gsize; j++)
  600.                     (p->g + j)->max = (p->g + j)->min =
  601.                     (p->g + j)->beg = (p->g + j)->end = 0;
  602.             }
  603.             (p->g + i)->max = (p->g + i)->beg = (p->g + i)->end = end;
  604.         }
  605.         p->sd.max += end; p->sd.end += end; p->sd.beg += end;
  606.     }
  607.     return p;
  608. }
  609.  
  610. void ZeroTree(struct tnode  *p)
  611. {   int  i;
  612.  
  613.     if(p != NULL)
  614.     {   ZeroTree(p->l);
  615.         ZeroTree(p->r);
  616.         p->sd.end = 0;
  617.         if(genotypes)
  618.             for(i = 0; i < p->gsize; i++)
  619.                 (p->g + i)->end = 0;
  620.     }
  621. }
  622.  
  623. void StartFragment(char  data[], struct last_out  *lo,
  624.     struct tnode  **uroot, struct tnode  **troot, int  c)
  625. {   int  i, lnum_sp;
  626.     long  size, end;
  627.     char  ldata[81], lbl[4];
  628.  
  629.     if(update && c) *uroot = DoUpdate(*uroot, update);
  630.     if(c)
  631.     {   FreeTTree(*uroot);
  632. /*
  633.         printf("coreleft = %6lu\n", coreleft());
  634. */
  635.         *uroot = NULL;
  636.         ZeroTree(*troot);
  637.     }
  638.     sscanf(data,"%*s%*s%d%*s%*s%lu%*s%*s%lu", &lnum_sp, &lo->ctime, &lo->time);
  639.     for(i = 0; i < lnum_sp; i++)
  640.     {   fgets(ldata,80,inf);
  641.         sscanf(ldata,"%ld%s%ld", &size, lbl, &end);
  642.         if(!i)
  643.     {   if(!strcmp(lbl,"---"))
  644.                 genotypes = 0;
  645.             else
  646.                 genotypes = 1;
  647.         }
  648.         *uroot = AddFragTree(*uroot,size,lbl,end);
  649.         *troot = AddFragTree(*troot,size,lbl,end);
  650.     }
  651. }
  652.  
  653. int t_read(char  data[], struct last_out  *lo, int  *first, int  *genotypes)
  654. {   struct last_out  ti;
  655.     int    nargs;
  656.     char   v2[9], v3[9], v4[9];
  657.  
  658.     sscanf(data,"%s", v2);
  659.     if(!strcmp(v2,"num_sp")) return 0;
  660.     nargs = sscanf(data,"%lx%s%s%s", &ti.time, v2, v3, v4);
  661.     if(*first)
  662.     {   *first = 0;
  663.         if(nargs == 4) *genotypes = 1;
  664.         else *genotypes = 0;
  665.         lo->time += ti.time;     /* assumes lo structure initialized to zero */
  666.         if(lo->time >= 1000000L)
  667.         {   lo->time %= 1000000L;
  668.             lo->ctime++;
  669.         }
  670.         lo->bd = v2[0];
  671.         sscanf(v3,"%u", &lo->size);
  672.         if(*genotypes) strcpy(lo->label,v4);
  673.         else strcpy(lo->label,"");
  674.     }
  675.     else
  676.     {   lo->time += ti.time;
  677.         if(lo->time >= 1000000L)
  678.         {   lo->time %= 1000000L;
  679.             lo->ctime++;
  680.         }
  681.         if(*genotypes) switch(nargs)
  682.         {   case 1: break;
  683.             case 2:
  684.             {   if(isdigit(v2[0]))
  685.                 {   sscanf(v2,"%u", &lo->size); break; }
  686.                 else
  687.                 {   if(strlen(v2) == 1)
  688.                     {   lo->bd = v2[0]; break; }
  689.                     else
  690.                     {   strcpy(lo->label,v2); break; }
  691.                 }
  692.             }
  693.             case 3:
  694.             {   if(isdigit(v2[0]))
  695.                 {   sscanf(v2,"%u", &lo->size);
  696.                     strcpy(lo->label,v3);
  697.                 }
  698.                 else
  699.                 {   lo->bd = v2[0];
  700.                     if(isdigit(v3[0]))
  701.                         sscanf(v3,"%u", &lo->size);
  702.                     else
  703.                         strcpy(lo->label,v3);
  704.                 }
  705.                 break;
  706.             }
  707.             case 4:
  708.             {   lo->bd = v2[0];
  709.                 sscanf(v3,"%u", &lo->size);
  710.                 strcpy(lo->label,v4);
  711.                 break;
  712.             }
  713.         }
  714.         else switch(nargs)
  715.         {   case 1: break;
  716.             case 2:
  717.             {   if(isdigit(v2[0]))
  718.                     sscanf(v2,"%u", &lo->size);
  719.                 else
  720.                     lo->bd = v2[0];
  721.                 break;
  722.             }
  723.             case 3:
  724.             {   lo->bd = v2[0];
  725.                 sscanf(v3,"%u", &lo->size);
  726.                 break;
  727.             }
  728.         }
  729.     }
  730.     return 1;
  731. }
  732.