📄 alnread.c
字号:
(TLineInfoReaderPtr lirp, int pos){ if (lirp == NULL || lirp->first_line == NULL || pos < 0 || lirp->data_pos == -1) { return 0; } if (lirp->data_pos == pos) { if (lirp->curr_line_pos == NULL) { return 0; } else { return *lirp->curr_line_pos; } } if (lirp->data_pos > pos) { s_LineInfoReaderReset (lirp); } while (lirp->data_pos < pos && lirp->curr_line != NULL) { lirp->curr_line_pos ++; /* skip over spaces, progress to next line if necessary */ s_LineInfoReaderAdvancePastSpace (lirp); lirp->data_pos ++; } if (lirp->curr_line_pos != NULL) { return *lirp->curr_line_pos; } else { return 0; }}/* The following functions are used to manage the SStringCount structure. * These functions are useful for determining whether a string is unique * or whether only one string is used for a particular purpose. * The structure also tracks the line numbers on which a particular string * appeared. *//* This function allocates memory for a new SStringCount structure, * initializes its member variables. The function also places the * structure at the end of list if list is not NULL. * The function returns a pointer to the newly allocated SStringCount * structure. */static TStringCountPtr s_StringCountNew (TStringCountPtr list){ TStringCountPtr new_item, last; new_item = (TStringCountPtr) malloc (sizeof (SStringCount)); if (new_item == NULL) { return NULL; } new_item->string = NULL; new_item->num_appearances = 0; new_item->line_numbers = NULL; new_item->next = NULL; last = list; while (last != NULL && last->next != NULL) { last = last->next; } if (last != NULL) { last->next = new_item; } return new_item;}/* This function recursively frees data associated with the structures * and structure member variables in a linked list of SStringCount * structures. */static void s_StringCountFree (TStringCountPtr list){ if (list == NULL) { return; } s_StringCountFree (list->next); s_IntLinkFree (list->line_numbers); free (list);}/* This function searches list to see if the string matches any of the * existing entries. If so, the num_appearances value for that entry is * increased and the line_num is added to that entry's list of line numbers. * Otherwise a new entry is created at the end of the list. * The function returns list if list was not NULL, or a pointer to the * newly created SStringCount structure otherwise. */static TStringCountPtr s_AddStringCount ( char * string, int line_num, TStringCountPtr list){ TStringCountPtr add_to, last; TIntLinkPtr new_offset; if (string == NULL) { for (add_to = list; add_to != NULL && add_to->string != NULL; add_to = add_to->next) { last = add_to; } } else { for (add_to = list; add_to != NULL && (add_to->string == NULL || strcmp (string, add_to->string) != 0); add_to = add_to->next) { last = add_to; } } if (add_to == NULL) { add_to = s_StringCountNew (list); if (list == NULL) list = add_to; if (add_to != NULL) { add_to->string = string; } } if (add_to != NULL) { add_to->num_appearances ++; new_offset = s_IntLinkNew (line_num, add_to->line_numbers); if (add_to->line_numbers == NULL) { add_to->line_numbers = new_offset; } } return list; }/* The following functions are replacements for strncasecmp and strcasecmp *//* This function returns -1 if str1 is less than str2 in the first cmp_count * characters (using case-insensitive comparisons), 0 if they are equal, * and 1 if str1 is greater than str2. */static int s_StringNICmp (char * str1, char *str2, int cmp_count){ char * cp1; char * cp2; int char_count, diff; if (str1 == NULL && str2 == NULL) { return 0; } if (str1 == NULL) { return -1; } if (str2 == NULL) { return 1; } cp1 = str1; cp2 = str2; char_count = 0; while (*cp1 != 0 && *cp2 != 0 && char_count < cmp_count) { diff = toupper ((int) *cp1) - toupper ((int) *cp2); if (diff != 0) { return diff; } char_count ++; cp1++; cp2++; } if (char_count == cmp_count) { return 0; } else if (*cp1 == 0 && *cp2 != 0) { return -1; } else if (*cp1 != 0 && *cp2 == 0) { return 1; } else { return 0; }}/* This function returns -1 if str1 is less than str2 using case-insensitive * comparisons), 0 if they are equal, and 1 if str1 is greater than str2. */static int s_StringICmp (char * str1, char *str2){ char * cp1; char * cp2; int diff; if (str1 == NULL && str2 == NULL) { return 0; } if (str1 == NULL) { return -1; } if (str2 == NULL) { return 1; } cp1 = str1; cp2 = str2; while (*cp1 != 0 && *cp2 != 0) { diff = toupper ((int) *cp1) - toupper ((int) *cp2); if (diff != 0) { return diff; } cp1++; cp2++; } if (*cp1 == 0 && *cp2 != 0) { return -1; } else if (*cp1 != 0 && *cp2 == 0) { return 1; } else { return 0; }}/* The following functions are used to analyze specific kinds of lines * found in alignment files for information regarding the number of * expected sequences, the expected length of those sequences, and the * characters used to indicate missing, gap, and match characters. *//* This function reads two numbers separated by whitespace from the * beginning of the string and uses them to set the expected number of * sequences and the expected number of characters per sequence. */static voids_GetFASTAExpectedNumbers(char * str, SAlignRawFilePtr afrp){ char * cp; char * cpend; char replace; int first, second; if (str == NULL || afrp == NULL) { return; } cp = str; while (! isdigit ((int )*cp) && *cp != 0) { cp++; } cpend = cp; while (isdigit ((int )*cpend) && *cpend != 0) { cpend++; } if (cp == cpend) { return; } replace = *cpend; *cpend = 0; first = atol (cp); *cpend = replace; cp = cpend; while (! isdigit ((int )*cp) && *cp != 0) { cp++; } cpend = cp; while (isdigit ((int )*cpend) && *cpend != 0) { cpend++; } if (cp == cpend) { return; } replace = *cpend; *cpend = 0; second = atol (cp); *cpend = replace; if (first > 0 && second > 0) { afrp->expected_num_sequence = first; afrp->expected_sequence_len = second; } }/* This function examines the string str to see if it begins with two * numbers separated by whitespace. The function returns eTrue if so, * otherwise it returns eFalse. */static EBool s_IsTwoNumbersSeparatedBySpace (char * str){ char * cp; EBool found_first_number = eFalse; EBool found_dividing_space = eFalse; EBool found_second_number = eFalse; EBool found_second_number_end = eFalse; if (str == NULL) { return eFalse; } cp = str; while (*cp != 0) { if (! isdigit ((int )*cp) && ! isspace ((int )*cp)) { return eFalse; } if (! found_first_number) { if (! isdigit ((int )*cp)) { return eFalse; } found_first_number = eTrue; } else if (! found_dividing_space) { if ( isspace ((int ) *cp)) { found_dividing_space = eTrue; } else if ( ! isdigit ((int )*cp)) { return eFalse; } } else if (! found_second_number) { if ( isdigit ((int )*cp)) { found_second_number = eTrue; } else if (! isspace ((int ) *cp)) { return eFalse; } } else if (! found_second_number_end) { if ( isspace ((int ) *cp)) { found_second_number_end = eTrue; } else if (! isdigit ((int )*cp)) { return eFalse; } } else if (! isspace ((int ) *cp)) { return eFalse; } cp++; } if (found_second_number) { return eTrue; } return eFalse;}/* This function finds a value name in a string, looks for an equals sign * after the value name, and then looks for an integer value after the * equals sign. If the integer value is found, the function copies the * integer value into the val location and returns eTrue, otherwise the * function returns eFalse. */static EBool s_GetOneNexusSizeComment (char * str, char * valname, int * val){ char buf[MAX_PRINTED_INT_LEN_PLUS_ONE]; char * cpstart; char * cpend; int maxlen; if (str == NULL || valname == NULL || val == NULL) { return eFalse; } cpstart = strstr (str, valname); if (cpstart == NULL) { return eFalse; } cpstart += strlen (valname); while (*cpstart != 0 && isspace ((int )*cpstart)) { cpstart++; } if (*cpstart != '=') { return eFalse; } cpstart ++; while (*cpstart != 0 && isspace ((int )*cpstart)) { cpstart++; } if (! isdigit ((int )*cpstart)) { return eFalse; } cpend = cpstart + 1; while ( *cpend != 0 && isdigit ((int )*cpend)) { cpend ++; } maxlen = cpend - cpstart; if (maxlen > kMaxPrintedIntLen) maxlen = kMaxPrintedIntLen; strncpy (buf, cpstart, maxlen); buf [maxlen] = 0; *val = atoi (buf); return eTrue;}/* This function looks for Nexus-style comments to indicate the number of * sequences and the number of characters per sequence expected from this * alignment file. If the function finds these comments, it returns eTrue, * otherwise it returns eFalse. */static void s_GetNexusSizeComments (char * str, EBool * found_ntax, EBool * found_nchar, SAlignRawFilePtr afrp){ int num_sequences; int num_chars; if (str == NULL || found_nchar == NULL || found_ntax == NULL || afrp == NULL) { return; } if (! *found_ntax && (s_GetOneNexusSizeComment (str, "ntax", &num_sequences) || s_GetOneNexusSizeComment (str, "NTAX", &num_sequences))) { afrp->expected_num_sequence = num_sequences; *found_ntax = eTrue; } if (! *found_nchar && (s_GetOneNexusSizeComment (str, "nchar", &num_chars) || s_GetOneNexusSizeComment (str, "NCHAR", &num_chars))) { afrp->expected_sequence_len = num_chars; *found_nchar = eTrue; }}/* This function looks for characters in Nexus-style comments to * indicate values for specific kinds of characters (match, missing, gap...). * If the string str contains val_name followed by an equals sign, the function * will return the first non-whitespace character following the equals sign, * otherwise the function will return a 0. */static char GetNexusTypechar (char * str, char * val_name){ char * cp; char * cpend; if (str == NULL || val_name == NULL) { return 0; } cpend = strstr (str, ";"); if (cpend == NULL) { return 0; } cp = strstr (str, val_name); if (cp == NULL || cp > cpend) { return 0; } cp += strlen (val_name); while ( isspace ((int )*cp)) { cp ++; } if (*cp != '=') { return 0; } cp++; while ( isspace ((int )*cp) || *cp == '\'') { cp ++; } return *cp;}/* This function reads a Nexus-style comment line for the characters * specified for missing, match, and gap and compares the characters from * the comment with the characters specif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -