int stristart(const char *s1, const char *s2) { int i=0; while (s1[i] && UCASE(s1[i]) == UCASE(s2[i])) i++; if (s1[i]==0) { return 0; } else return 2*(UCASE(s1[i]) < UCASE(s2[i]))-1; }
INTERNAL char tochar(char h, char l) { char p; h = (char) UCASE(h); l = (char) UCASE(l); h -= '0'; if (h > 9) h -= 7; l -= '0'; if (l > 9) l -= 7; p = h * 16 + l; return p; }
int OutputAlignmentMsf(MultipleAlignment *ma, char *filename) { FILE *out = fopen(filename, "wb"); SequenceAlignment *sa; int i, j, k; if (out) { char t[100]; time_t now = time(0); char ** names = (char**) malloc(sizeof(char*) * ma->numChains); char *period = strrchr(filename, '.'); sa = GetSequenceAlignment(ma); *period = 0; fprintf(out, "MSF of: %s from: 1 to: %4i\n", filename, sa->seqs[0]->length); *period = '.'; strftime(t, 100, "%d-%b-%y %X", localtime(&now)); /* asctime is not thread-safe, and Windows has no thread-safe version of it. */ fprintf(out, "%s MSF: %4i Type: P %s Check: 9999 ..\n\n", filename, sa->seqs[0]->length, t); for (i=0; i<ma->numChains; i++) { char *id = ma->chains[i]->pdb->idString; int len = strlen(id); if (len > 13) len = 12; names[i] = (char*) calloc(16, sizeof(char)); memset(names[i], ' ', 13 * sizeof(char)); memcpy(names[i], id, len); } for (i=ma->numChains-1; i>=0; i--) { char *id = ma->chains[i]->pdb->idString; int chainCount = 0; for (j=i-1; j>=0; j--) { if (!strcmp(names[i], names[j])) { names[j][14] = 1; names[i][14] = 1; if (ma->chains[i]->pdb->chainName == ma->chains[j]->pdb->chainName) { chainCount++; names[j][15] = 1; names[i][15] = 1; } } } if (names[i][15] || names[i][14]) { int len = 13; char *end = strchr(id, ':'); char chain = ma->chains[i]->pdb->chainName; if (!chain || chain == 0) chain = '_'; if (!end) end = strchr(id, ' '); if (end) len = (int)(end-id); if (names[i][15]) { if (len > 8) len = 8; if (chainCount > 100) len --; if (chainCount > 1000) len --; if (chainCount > 10000) len --; chainCount %= 100000; sprintf(names[i] + len, ":%c%i", ma->chains[i]->pdb->chainName, chainCount); } else { if (len > 10) len = 10; sprintf(names[i] + len, ":%c", ma->chains[i]->pdb->chainName); } } } for (i=0; i<ma->numChains; i++) { int count = 0; int check = 0; for (j=0; j<sa->seqs[i]->length; j++) { count++; check += count * UCASE(sa->seqs[i]->seq[j]); count = count%57; } check %= 10000; fprintf(out, "Name: %-13s Len: %4i Check: %4i Weight: 1.00\n", names[i], sa->seqs[i]->length, check); } fprintf(out, "\n//\n\n"); for (i=0; i < sa->seqs[0]->length; i+=50) { for (j=0; j < ma->numChains; j++) { fprintf(out, "%-13s", names[j]); for (k=i; k<i+50 && k < sa->seqs[j]->length; k++) { char c = sa->seqs[j]->seq[k]; if (c == '-') c = '.'; fputc(c, out); if (k % 10 == 9 && k<i+49) fputc(' ', out); } fputc('\n', out); } fputc('\n', out); } for (i=0; i<ma->numChains; i++) { free(names[i]); } free(names); FreeSequenceAlignment(sa); fclose(out); return 1; } return 0; }
/* * wstring_to_decimal is modelled on string_to_decimal, the majority * of which can be found in the common file char_to_decimal.h. The * significant differences are: * * 1. This code recognizes only C99 (hex fp strings and restricted * characters in parentheses following "nan") vs. C90 modes, no * Fortran conventions. * * 2. *pform is an int rather than an enum decimal_string_form. On * return, *pform == 0 if no valid token was found, *pform < 0 * if a C99 hex fp string was found, and *pform > 0 if a decimal * string was found. */ static void wstring_to_decimal(const wchar_t **ppc, int c99, decimal_record *pd, int *pform) { const wchar_t *cp = *ppc; /* last character seen */ const wchar_t *good = cp - 1; /* last character accepted */ wchar_t current; /* always equal to *cp */ int sigfound; int ids = 0; int i, agree; int nzbp = 0; /* number of zeros before point */ int nzap = 0; /* number of zeros after point */ char decpt; int nfast, nfastlimit; char *pfast; int e, esign; int expshift = 0; int form; /* * This routine assumes that the radix point is a single * ASCII character, so that following this assignment, the * condition (current == decpt) will correctly detect it. */ decpt = *(localeconv()->decimal_point); /* input is invalid until we find something */ pd->fpclass = fp_signaling; pd->sign = 0; pd->exponent = 0; pd->ds[0] = '\0'; pd->more = 0; pd->ndigits = 0; *pform = form = 0; /* skip white space */ current = *cp; while (iswspace((wint_t)current)) current = *++cp; /* look for optional leading sign */ if (current == L'+') { current = *++cp; } else if (current == L'-') { pd->sign = 1; current = *++cp; } sigfound = -1; /* -1 = no digits found yet */ /* * Admissible first non-white-space, non-sign characters are * 0-9, i, I, n, N, or the radix point. */ if (L'1' <= current && current <= L'9') { pd->fpclass = fp_normal; form = 1; good = cp; sigfound = 1; /* 1 = significant digits found */ pd->ds[ids++] = (char)current; current = *++cp; } else { switch (current) { case L'0': /* * Accept the leading zero and set pd->fpclass * accordingly, but don't set sigfound until we * determine that this isn't a "fake" hex string * (i.e., 0x.p...). */ good = cp; pd->fpclass = fp_zero; if (c99) { /* look for a hex fp string */ current = *++cp; if (current == L'X' || current == L'x') { /* assume hex fp form */ form = -1; expshift = 2; current = *++cp; /* * Only a digit or radix point can * follow "0x". */ if (NZDIGIT(current)) { pd->fpclass = fp_normal; good = cp; sigfound = 1; pd->ds[ids++] = (char)current; current = *++cp; break; } else if (current == (wchar_t)decpt) { current = *++cp; goto afterpoint; } else if (current != L'0') { /* not hex fp after all */ form = 1; expshift = 0; goto done; } } else { form = 1; } } else { form = 1; } /* skip all leading zeros */ while (current == L'0') current = *++cp; good = cp - 1; sigfound = 0; /* 0 = only zeros found so far */ break; case L'i': case L'I': /* look for inf or infinity */ current = *++cp; agree = 1; while (agree <= 7 && UCASE(current) == (wchar_t)infstring[agree]) { current = *++cp; agree++; } if (agree >= 3) { /* found valid infinity */ pd->fpclass = fp_infinity; form = 1; good = (agree < 8)? cp + 2 - agree : cp - 1; __inf_read = 1; } goto done; case L'n': case L'N': /* look for nan or nan(string) */ current = *++cp; agree = 1; while (agree <= 2 && UCASE(current) == (wchar_t)nanstring[agree]) { current = *++cp; agree++; } if (agree == 3) { /* found valid NaN */ pd->fpclass = fp_quiet; form = 1; good = cp - 1; __nan_read = 1; if (current == L'(') { /* accept parenthesized string */ if (c99) { do { current = *++cp; } while (iswalnum(current) || current == L'_'); } else { do { current = *++cp; } while (current && current != L')'); } if (current == L')') good = cp; } } goto done; default: if (current == (wchar_t)decpt) { /* * Don't accept the radix point just yet; * we need to see at least one digit. */ current = *++cp; goto afterpoint; } goto done; } } nextnumber: /* * Admissible characters after the first digit are a valid * digit, an exponent delimiter (E or e for decimal form, * P or p for hex form), or the radix point. (Note that we * can't get here unless we've already found a digit.) */ if (NZDIGIT(current)) { /* * Found another nonzero digit. If there's enough room * in pd->ds, store any intervening zeros we've found so far * and then store this digit. Otherwise, stop storing * digits in pd->ds and set pd->more. */ if (ids + nzbp + 2 < DECIMAL_STRING_LENGTH) { for (i = 0; i < nzbp; i++) pd->ds[ids++] = '0'; pd->ds[ids++] = (char)current; } else { pd->exponent += (nzbp + 1) << expshift; pd->more = 1; if (ids < DECIMAL_STRING_LENGTH) { pd->ds[ids] = '\0'; pd->ndigits = ids; /* don't store any more digits */ ids = DECIMAL_STRING_LENGTH; } } pd->fpclass = fp_normal; sigfound = 1; nzbp = 0; current = *++cp; /* * Use an optimized loop to grab a consecutive sequence * of nonzero digits quickly. */ nfastlimit = DECIMAL_STRING_LENGTH - 3 - ids; for (nfast = 0, pfast = &(pd->ds[ids]); nfast < nfastlimit && NZDIGIT(current); nfast++) { *pfast++ = (char)current; current = *++cp; } ids += nfast; if (current == L'0') goto nextnumberzero; /* common case */ /* advance good to the last accepted digit */ good = cp - 1; goto nextnumber; } else { switch (current) { case L'0': nextnumberzero: /* * Count zeros before the radix point. Later we * will either put these zeros into pd->ds or add * nzbp to pd->exponent to account for them. */ while (current == L'0') { nzbp++; current = *++cp; } good = cp - 1; goto nextnumber; case L'E': case L'e': if (form < 0) goto done; goto exponent; case L'P': case L'p': if (form > 0) goto done; goto exponent; default: if (current == decpt) { /* accept the radix point */ good = cp; current = *++cp; goto afterpoint; } goto done; } } afterpoint: /* * Admissible characters after the radix point are a valid digit * or an exponent delimiter. (Note that it is possible to get * here even though we haven't found any digits yet.) */ if (NZDIGIT(current)) { if (form == 0) form = 1; if (sigfound < 1) { /* no significant digits found until now */ pd->fpclass = fp_normal; sigfound = 1; pd->ds[ids++] = (char)current; pd->exponent = (-(nzap + 1)) << expshift; } else { /* significant digits have been found */ if (ids + nzbp + nzap + 2 < DECIMAL_STRING_LENGTH) { for (i = 0; i < nzbp + nzap; i++) pd->ds[ids++] = '0'; pd->ds[ids++] = (char)current; pd->exponent -= (nzap + 1) << expshift; } else { pd->exponent += nzbp << expshift; pd->more = 1; if (ids < DECIMAL_STRING_LENGTH) { pd->ds[ids] = '\0'; pd->ndigits = ids; /* don't store any more digits */ ids = DECIMAL_STRING_LENGTH; } } } nzbp = 0; nzap = 0; current = *++cp; /* * Use an optimized loop to grab a consecutive sequence * of nonzero digits quickly. */ nfastlimit = DECIMAL_STRING_LENGTH - 3 - ids; for (nfast = 0, pfast = &(pd->ds[ids]); nfast < nfastlimit && NZDIGIT(current); nfast++) { *pfast++ = (char)current; current = *++cp; } ids += nfast; pd->exponent -= nfast << expshift; if (current == L'0') goto zeroafterpoint; /* advance good to the last accepted digit */ good = cp - 1; goto afterpoint; } else { switch (current) { case L'0': if (form == 0) form = 1; if (sigfound == -1) { pd->fpclass = fp_zero; sigfound = 0; } zeroafterpoint: /* * Count zeros after the radix point. If we find * any more nonzero digits later, we will put these * zeros into pd->ds and decrease pd->exponent by * nzap. */ while (current == L'0') { nzap++; current = *++cp; } good = cp - 1; goto afterpoint; case L'E': case L'e': /* don't accept exponent without preceding digits */ if (sigfound == -1 || form < 0) goto done; break; case L'P': case L'p': /* don't accept exponent without preceding digits */ if (sigfound == -1 || form > 0) goto done; break; default: goto done; } } exponent: e = 0; esign = 0; /* look for optional exponent sign */ current = *++cp; if (current == L'+') { current = *++cp; } else if (current == L'-') { esign = 1; current = *++cp; } /* * Accumulate explicit exponent. Note that if we don't find at * least one digit, good won't be updated and e will remain 0. * Also, we keep e from getting too large so we don't overflow * the range of int (but notice that the threshold is large * enough that any larger e would cause the result to underflow * or overflow anyway). */ while (L'0' <= current && current <= L'9') { good = cp; if (e <= 1000000) e = 10 * e + current - L'0'; current = *++cp; } if (esign) pd->exponent -= e; else pd->exponent += e; done: /* * If we found any zeros before the radix point that were not * accounted for earlier, adjust the exponent. (This is only * relevant when pd->fpclass == fp_normal, but it's harmless * in all other cases.) */ pd->exponent += nzbp << expshift; /* terminate pd->ds if we haven't already */ if (ids < DECIMAL_STRING_LENGTH) { pd->ds[ids] = '\0'; pd->ndigits = ids; } /* * If we accepted any characters, advance *ppc to point to the * first character we didn't accept; otherwise, pass back a * signaling nan. */ if (good >= *ppc) { *ppc = good + 1; } else { pd->fpclass = fp_signaling; pd->sign = 0; form = 0; } *pform = form; }