📄 phylip.c
字号:
} /* reducebestrees */void shellsort(double *a, long *b, long n){ /* Shell sort keeping a, b in same order */ /* used by dnapenny, dolpenny, & penny */ long gap, i, j, itemp; double rtemp; gap = n / 2; while (gap > 0) { for (i = gap + 1; i <= n; i++) { j = i - gap; while (j > 0) { if (a[j - 1] > a[j + gap - 1]) { rtemp = a[j - 1]; a[j - 1] = a[j + gap - 1]; a[j + gap - 1] = rtemp; itemp = b[j - 1]; b[j - 1] = b[j + gap - 1]; b[j + gap - 1] = itemp; } j -= gap; } } gap /= 2; }} /* shellsort */void getch(Char *c, long *parens, FILE *treefile){ /* get next nonblank character */ do { if (eoln(treefile)) scan_eoln(treefile); (*c) = gettc(treefile); if ((*c) == '\n' || (*c) == '\t') (*c) = ' '; } while ( *c == ' ' && !eoff(treefile) ); if ((*c) == '(') (*parens)++; if ((*c) == ')') (*parens)--;} /* getch */void getch2(Char *c, long *parens){ /* get next nonblank character */ do { if (eoln(intree)) scan_eoln(intree); *c = gettc(intree); if (*c == '\n' || *c == '\t') *c = ' '; } while (!(*c != ' ' || eoff(intree))); if (*c == '(') (*parens)++; if (*c == ')') (*parens)--;} /* getch2 */void findch(Char c, Char *ch, long which){ /* scan forward until find character c */ boolean done; long dummy_parens; done = false; while (!done) { if (c == ',') { if (*ch == '(' || *ch == ')' || *ch == ';') { printf( "\n\nERROR in user tree %ld: unmatched parenthesis or missing comma\n\n", which); exxit(-1); } else if (*ch == ',') done = true; } else if (c == ')') { if (*ch == '(' || *ch == ',' || *ch == ';') { printf("\n\nERROR in user tree %ld: ", which); printf("unmatched parenthesis or non-bifurcated node\n\n"); exxit(-1); } else { if (*ch == ')') done = true; } } else if (c == ';') { if (*ch != ';') { printf("\n\nERROR in user tree %ld: ", which); printf("unmatched parenthesis or missing semicolon\n\n"); exxit(-1); } else done = true; } if (*ch != ')' && done) continue; getch(ch, &dummy_parens, intree); }} /* findch */void findch2(Char c, long *lparens, long *rparens, Char *ch){ /* skip forward in user tree until find character c */ boolean done; long dummy_parens; done = false; while (!done) { if (c == ',') { if (*ch == '(' || *ch == ')' || *ch == ':' || *ch == ';') { printf("\n\nERROR in user tree: "); printf("unmatched parenthesis, missing comma"); printf(" or non-trifurcated base\n\n"); exxit(-1); } else if (*ch == ',') done = true; } else if (c == ')') { if (*ch == '(' || *ch == ',' || *ch == ':' || *ch == ';') { printf( "\n\nERROR in user tree: unmatched parenthesis or non-bifurcated node\n\n"); exxit(-1); } else if (*ch == ')') { (*rparens)++; if ((*lparens) > 0 && (*lparens) == (*rparens)) { if ((*lparens) == spp - 2) { getch(ch, &dummy_parens, intree); if (*ch != ';') { printf( "\n\nERROR in user tree: "); printf("unmatched parenthesis or missing semicolon\n\n"); exxit(-1); } } } done = true; } } if (*ch != ')' && done) continue; if (*ch == ')') getch(ch, &dummy_parens, intree); }} /* findch2 */void processlength(double *valyew, double *divisor, Char *ch, boolean *minusread, FILE *treefile, long *parens){ /* read a branch length from a treefile */ long digit, ordzero; boolean pointread; ordzero = '0'; *minusread = false; pointread = false; *valyew = 0.0; *divisor = 1.0; getch(ch, parens, treefile); digit = (long)(*ch - ordzero); while ( ((digit <= 9) && (digit >= 0)) || *ch == '.' || *ch == '-') { if (*ch == '.' ) pointread = true; else if (*ch == '-' ) *minusread = true; else { *valyew = *valyew * 10.0 + digit; if (pointread) *divisor *= 10.0; } getch(ch, parens, treefile); digit = (long)(*ch - ordzero); } if (*minusread) *valyew = -(*valyew);} /* processlength */void writename(long start, long n, long *enterorder){ /* write species name and number in entry order */ long i, j; for (i = start; i < start+n; i++) { printf(" %3ld. ", i+1); for (j = 0; j < nmlngth; j++) putchar(nayme[enterorder[i] - 1][j]); putchar('\n'); fflush(stdout); }} /* writename */void memerror(){ printf("Error allocating memory\n"); exxit(-1);} /* memerror */void odd_malloc(long x){ /* error message if attempt to malloc too little or too much memory */ printf ("ERROR: a function asked for an inappropriate amount of memory:"); printf (" %ld bytes\n", x); printf (" This can mean one of two things:\n"); printf (" 1. The input file is incorrect"); printf (" (perhaps it was not saved as Text Only),\n"); printf (" 2. There is a bug in the program.\n"); printf (" Please check your input file carefully.\n"); printf (" If it seems to be a bug, please mail joe@gs.washington.edu\n"); printf (" with the name of the program, your computer system type,\n"); printf (" a full description of the problem, and with the input data file.\n"); printf (" (which should be in the body of the message, not as an Attachment).\n"); /* abort() can be used to crash * for debugging */ exxit(-1);}MALLOCRETURN *mymalloc(long x){ /* wrapper for malloc, allowing error message if too little, too much */ MALLOCRETURN *new_block; if ((x <= 0) || (x > TOO_MUCH_MEMORY)) odd_malloc(x); new_block = (MALLOCRETURN *)calloc(1,x); if (!new_block) { memerror(); return (MALLOCRETURN *) new_block; } else return (MALLOCRETURN *) new_block;} /* mymalloc */void gnu(node **grbg, node **p){ /* this and the following are do-it-yourself garbage collectors. Make a new node or pull one off the garbage list */ if (*grbg != NULL) { *p = *grbg; *grbg = (*grbg)->next; } else *p = (node *)Malloc(sizeof(node)); (*p)->back = NULL; (*p)->next = NULL; (*p)->tip = false; (*p)->times_in_tree = 0.0; (*p)->r = 0.0; (*p)->theta = 0.0; (*p)->x = NULL; (*p)->protx = NULL; /* for the sake of proml */} /* gnu */void chuck(node **grbg, node *p){ /* collect garbage on p -- put it on front of garbage list */ p->back = NULL; p->next = *grbg; *grbg = p;} /* chuck */void zeronumnuc(node *p, long endsite){ long i,j; for (i = 0; i < endsite; i++) for (j = (long)A; j <= (long)O; j++) p->numnuc[i][j] = 0;} /* zeronumnuc */void zerodiscnumnuc(node *p, long endsite){ long i,j; for (i = 0; i < endsite; i++) for (j = (long)zero; j <= (long)seven; j++) p->discnumnuc[i][j] = 0;} /* zerodiscnumnuc */void allocnontip(node *p, long *zeros, long endsite){ /* allocate an interior node */ /* used by dnacomp, dnapars, & dnapenny */ p->numsteps = (steptr)Malloc(endsite*sizeof(long)); p->oldnumsteps = (steptr)Malloc(endsite*sizeof(long)); p->base = (baseptr)Malloc(endsite*sizeof(long)); p->oldbase = (baseptr)Malloc(endsite*sizeof(long)); p->numnuc = (nucarray *)Malloc(endsite*sizeof(nucarray)); memcpy(p->base, zeros, endsite*sizeof(long)); memcpy(p->numsteps, zeros, endsite*sizeof(long)); memcpy(p->oldbase, zeros, endsite*sizeof(long)); memcpy(p->oldnumsteps, zeros, endsite*sizeof(long)); zeronumnuc(p, endsite);} /* allocnontip */void allocdiscnontip(node *p, long *zeros, unsigned char *zeros2, long endsite){ /* allocate an interior node */ /* used by pars */ p->numsteps = (steptr)Malloc(endsite*sizeof(long)); p->oldnumsteps = (steptr)Malloc(endsite*sizeof(long)); p->discbase = (discbaseptr)Malloc(endsite*sizeof(unsigned char)); p->olddiscbase = (discbaseptr)Malloc(endsite*sizeof(unsigned char)); p->discnumnuc = (discnucarray *)Malloc(endsite*sizeof(discnucarray)); memcpy(p->discbase, zeros2, endsite*sizeof(unsigned char)); memcpy(p->numsteps, zeros, endsite*sizeof(long)); memcpy(p->olddiscbase, zeros2, endsite*sizeof(unsigned char)); memcpy(p->oldnumsteps, zeros, endsite*sizeof(long)); zerodiscnumnuc(p, endsite);} /* allocdiscnontip */void allocnode(node **anode, long *zeros, long endsite){ /* allocate a node */ /* used by dnacomp, dnapars, & dnapenny */ *anode = (node *)Malloc(sizeof(node)); allocnontip(*anode, zeros, endsite);} /* allocnode */void allocdiscnode(node **anode, long *zeros, unsigned char *zeros2, long endsite){ /* allocate a node */ /* used by pars */ *anode = (node *)Malloc(sizeof(node)); allocdiscnontip(*anode, zeros, zeros2, endsite);} /* allocdiscnontip */void gnutreenode(node **grbg, node **p, long i, long endsite, long *zeros){ /* this and the following are do-it-yourself garbage collectors. Make a new node or pull one off the garbage list */ if (*grbg != NULL) { *p = *grbg; *grbg = (*grbg)->next; memcpy((*p)->numsteps, zeros, endsite*sizeof(long)); memcpy((*p)->oldnumsteps, zeros, endsite*sizeof(long)); memcpy((*p)->base, zeros, endsite*sizeof(long)); memcpy((*p)->oldbase, zeros, endsite*sizeof(long)); zeronumnuc(*p, endsite); } else allocnode(p, zeros, endsite); (*p)->back = NULL; (*p)->next = NULL; (*p)->tip = false; (*p)->visited = false; (*p)->index = i; (*p)->numdesc = 0; (*p)->sumsteps = 0.0;} /* gnutreenode */void gnudisctreenode(node **grbg, node **p, long i, long endsite, long *zeros, unsigned char *zeros2){ /* this and the following are do-it-yourself garbage collectors. Make a new node or pull one off the garbage list */ if (*grbg != NULL) { *p = *grbg; *grbg = (*grbg)->next; memcpy((*p)->numsteps, zeros, endsite*sizeof(long)); memcpy((*p)->oldnumsteps, zeros, endsite*sizeof(long)); memcpy((*p)->discbase, zeros2, endsite*sizeof(unsigned char)); memcpy((*p)->olddiscbase, zeros2, endsite*sizeof(unsigned char)); zerodiscnumnuc(*p, endsite); } else allocdiscnode(p, zeros, zeros2, endsite); (*p)->back = NULL; (*p)->next = NULL; (*p)->tip = false; (*p)->visited = false; (*p)->index = i; (*p)->numdesc = 0; (*p)->sumsteps = 0.0;} /* gnudisctreenode */void chucktreenode(node **grbg, node *p){ /* collect garbage on p -- put it on front of garbage list */ p->back = NULL; p->next = *grbg; *grbg = p;} /* chucktreenode */void setupnode(node *p, long i){ /* initialization of node pointers, variables */ p->next = NULL; p->back = NULL; p->times_in_tree = (double) i * 1.0; p->index = i; p->tip = false;} /* setupnode */long count_sibs (node *p){ /* Count the number of nodes in a ring, return the total number of */ /* nodes excluding the one passed into the function (siblings) */ node *q; long return_int = 0; if (p->tip) { printf ("Error: the function count_sibs called on a tip. This is a bug.\n"); exxit (-1); } q = p->next; while (q != p) { if (q == NULL) { printf ("Error: a loop of nodes was not closed.\n"); exxit (-1); } else { return_int++; q = q->next; } } return return_int;} /* count_sibs */void inittrav (node *p){ /* traverse to set pointers uninitialized on inserting */ long i, num_sibs; node *sib_ptr; if (p == NULL) return; if (p->tip) return; num_sibs = count_sibs (p); sib_ptr = p; for (i=0; i < num_sibs; i++) { sib_ptr = sib_ptr->next; sib_ptr->initialized = false; inittrav(sib_ptr->back); }} /* inittrav */void commentskipper(FILE ***intree, long *bracket){ /* skip over comment bracket contents in reading tree */ char c; c = gettc(**intree); while (c != ']') { if(feof(**intree)) { printf("\n\nERROR: Unmatched comment brackets\n\n"); exxit(-1); } if(c == '[') { (*bracket)++; commentskipper(intree, bracket); } c = gettc(**intree); } (*bracket)--;} /* commentskipper */long countcomma(FILE **treefile, long *comma){ /* Modified by Dan F. 11/10/96 */ /* The next line inserted so this function leaves the file pointing to where it found it, not just re-winding it. */ long orig_position = ftell (*treefile); Char c; long lparen = 0; long bracket = 0; (*comma) = 0; for (;;){ c = getc(*treefile); if (feof(*treefile)) break; if (c == ';') break; if (c == ',') (*comma)++; if (c == '(') lparen++; if (c == '[') { bracket++; commentskipper(&treefile, &bracket); } } /* Don't just rewind, */ /* rewind (*treefile); */ /* Re-set to where it pointed when the function was called */ fseek (*treefile, orig_position, SEEK_SET); return lparen + (*comma);} /*countcomma*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -