📄 alnread.c
字号:
{ TLineInfoPtr lip, p; if (string == NULL) { return list; } lip = s_LineInfoNew (string, line_num, line_offset); if (lip == NULL) { return NULL; } if (list == NULL) { list = lip; } else { p = list; while (p != NULL && p->next != NULL) { p = p->next; } p->next = lip; } return list;}/* This function creates a new bracketed comment */static TBracketedCommentListPtr s_BracketedCommentListNew (TBracketedCommentListPtr list, char * string, int line_num, int line_offset){ TBracketedCommentListPtr comment; comment = (TBracketedCommentListPtr) malloc (sizeof (SBracketedCommentList)); if (comment == NULL) { return NULL; } comment->comment_lines = s_LineInfoNew (string, line_num, line_offset); comment->next = NULL; if (list != NULL) { while (list->next != NULL) { list = list->next; } list->next = comment; } return comment;}/* This function frees a bracketed comment list. */static void s_BracketedCommentListFree (TBracketedCommentListPtr list){ if (list == NULL) { return; } s_BracketedCommentListFree (list->next); list->next = NULL; s_LineInfoFree (list->comment_lines);}/* This function adds a line to a bracketed comment. */static void s_BracketedCommentListAddLine (TBracketedCommentListPtr comment, char * string, int line_num, int line_offset){ if (comment == NULL) { return; } comment->comment_lines = s_AddLineInfo (comment->comment_lines, string, line_num, line_offset);}/* This function counts the sequences found in a bracketed comment. */static int s_CountSequencesInBracketedComment (TBracketedCommentListPtr comment){ TLineInfoPtr lip; int num_segments = 0; EBool skipped_line_since_last_defline = eTrue; if (comment == NULL || comment->comment_lines == NULL) { return 0; } lip = comment->comment_lines; /* First line must be left bracket on a line by itself */ if (lip->data[0] != '[' || strspn (lip->data + 1, " \t\r\n") != strlen (lip->data + 1)) { return 0; } lip = lip->next; while (lip != NULL && lip->next != NULL) { if (lip->data[0] == '>') { if (!skipped_line_since_last_defline) { return 0; } else { num_segments ++; skipped_line_since_last_defline = eFalse; } } else { skipped_line_since_last_defline = eTrue; } lip = lip->next; } /* Last line must be right bracket on a line by itself */ /* First line must be left bracket on a line by itself */ if (lip->data[0] != ']' || strspn (lip->data + 1, " \t\r\n") != strlen (lip->data + 1)) { return 0; } return num_segments;}/* This function counts the number of sequences that appear in * bracketed comments. If the number of sequences is inconsistent, * the function will issue error messages and return a 1, otherwise * the function will return the number of sequences that appear in * each bracketed comment. */static int s_GetNumSegmentsInAlignment (TBracketedCommentListPtr comment_list, FReportErrorFunction errfunc, void * errdata){ TBracketedCommentListPtr comment; TSizeInfoPtr segcount_list = NULL; int num_segments = 1; int num_segments_this_bracket; int num_segments_expected; TSizeInfoPtr best; if (comment_list == NULL) { return num_segments; } for (comment = comment_list; comment != NULL; comment = comment->next) { num_segments_this_bracket = s_CountSequencesInBracketedComment (comment); segcount_list = s_AddSizeInfoAppearances (segcount_list, num_segments_this_bracket, 1); if (comment != comment_list && segcount_list->next != NULL) { best = s_GetMostPopularSizeInfo (segcount_list); num_segments_expected = best->size_value; if (num_segments_expected != num_segments_this_bracket) { s_ReportBadNumSegError (comment->comment_lines->line_num, num_segments_this_bracket, num_segments_expected, errfunc, errdata); } } } if (segcount_list != NULL && segcount_list->next == NULL && segcount_list->size_value > 0) { num_segments = segcount_list->size_value; } s_SizeInfoFree (segcount_list); return num_segments;}/* This function gets a list of the offsets of the * sequences in bracketed comments. */static TIntLinkPtr GetSegmentOffsetList (TBracketedCommentListPtr comment_list){ TIntLinkPtr new_offset, offset_list = NULL; TBracketedCommentListPtr comment; TLineInfoPtr lip; if (comment_list == NULL) { return NULL; } for (comment = comment_list; comment != NULL; comment = comment->next) { if (s_CountSequencesInBracketedComment (comment) == 0) { continue; } for (lip = comment->comment_lines; lip != NULL; lip = lip->next) { if (lip->data != NULL && lip->data[0] == '>') { new_offset = s_IntLinkNew (lip->line_num + 1, offset_list); if (offset_list == NULL) offset_list = new_offset; } } } return offset_list;}static char * s_TokenizeString (char * str, char *delimiter, char **last){ int skip; int length; if (str == NULL) { str = *last; } if (delimiter == NULL) { *last = NULL; return NULL; } if (str == NULL || *str == 0) { return NULL; } skip = strspn (str, delimiter); str += skip; length = strcspn (str, delimiter); *last = str + length; if (**last != 0) { **last = 0; (*last) ++; } return str;} /* This function creates a new list of SLineInfo structures by tokenizing * each data element from line_list into multiple tokens at whitespace. * The function returns a pointer to the new list. The original list is * unchanged. */static TLineInfoPtr s_BuildTokenList (TLineInfoPtr line_list){ TLineInfoPtr first_token, lip; char * tmp; char * piece; char * last; int line_pos; first_token = NULL; for (lip = line_list; lip != NULL; lip = lip->next) { if (lip->data != NULL && (tmp = strdup (lip->data)) != NULL) { piece = s_TokenizeString (tmp, " \t\r", &last); while (piece != NULL) { line_pos = piece - tmp; line_pos += lip->line_offset; first_token = s_AddLineInfo (first_token, piece, lip->line_num, line_pos); piece = s_TokenizeString (NULL, " \t\r", &last); } free (tmp); } } return first_token;}/* This function takes a list of SLineInfo structures, allocates memory * to hold their contents contiguously, and stores their contents, minus * the whitespace, in the newly allocated memory. * The function returns a pointer to this newly allocated memory. */static char * s_LineInfoMergeAndStripSpaces (TLineInfoPtr list){ TLineInfoPtr lip; int len; char * result; char * cp_to; char * cp_from; if (list == NULL) { return NULL; } len = 0; for (lip = list; lip != NULL; lip = lip->next) { if (lip->data != NULL) { len += strlen (lip->data); } } result = (char *) malloc (len + 1); if (result == NULL) { return result; } cp_to = result; for (lip = list; lip != NULL; lip = lip->next) { if (lip->data != NULL) { cp_from = lip->data; while (*cp_from != 0) { if (! isspace ((int )*cp_from)) { *cp_to = *cp_from; cp_to ++; } cp_from ++; } } } *cp_to = 0; return result;}/* The following functions are used to manage the SLineInfoReader * structure. The intention is to allow the user to access the data * from a linked list of SLineInfo structures using a given position * in the data based on the number of sequence data characters rather than * any particular line number or position in the line. This is useful * for matching up a data position in a record with a match character with * the same data position in the first or master record. This is also useful * for determining how to interpret special characters that may have * context-sensitive meanings. For example, a ? could indicate a missing * character if it is inside a sequence but indicate a gap if it is outside * a sequence. *//* This function is used to advance the current data position pointer * for a SLineInfoReader structure past white space and blank lines * in sequence data. */static void s_LineInfoReaderAdvancePastSpace (TLineInfoReaderPtr lirp){ if (lirp->curr_line_pos == NULL) { return; } while ( isspace ((int ) *lirp->curr_line_pos) || *lirp->curr_line_pos == 0) { while ( isspace ((int )*lirp->curr_line_pos)) { lirp->curr_line_pos ++; } if (*lirp->curr_line_pos == 0) { lirp->curr_line = lirp->curr_line->next; while (lirp->curr_line != NULL && lirp->curr_line->data == NULL) { lirp->curr_line = lirp->curr_line->next; } if (lirp->curr_line == NULL) { lirp->curr_line_pos = NULL; return; } else { lirp->curr_line_pos = lirp->curr_line->data; } } }}/* This function sets the current data position pointer to the first * non-whitespace character in the sequence data. */static void s_LineInfoReaderReset (TLineInfoReaderPtr lirp){ if (lirp == NULL) { return; } lirp->curr_line = lirp->first_line; while (lirp->curr_line != NULL && lirp->curr_line->data == NULL) { lirp->curr_line = lirp->curr_line->next; } if (lirp->curr_line == NULL) { lirp->curr_line_pos = NULL; lirp->data_pos = -1; } else { lirp->curr_line_pos = lirp->curr_line->data; s_LineInfoReaderAdvancePastSpace (lirp); if (lirp->curr_line_pos == NULL) { lirp->data_pos = -1; } else { lirp->data_pos = 0; } }} /* This function creates a new SLineInfoReader structure and initializes * its member variables. The current data position pointer is set to the * first non-whitespace character in the sequence data, and the data position * counter is set to zero. The function returns a pointer to the new * LineInfoReader data structure. */static TLineInfoReaderPtr s_LineInfoReaderNew (TLineInfoPtr line_list){ TLineInfoReaderPtr lirp; if (line_list == NULL) { return NULL; } lirp = (TLineInfoReaderPtr) malloc (sizeof (SLineInfoReader)); if (lirp == NULL) { return NULL; } lirp->first_line = line_list; s_LineInfoReaderReset (lirp); return lirp;}/* This function safely interprets the current line number of the * SLineInfoReader structure. If the structure is NULL or the * current line is NULL (usually because the data position has been * advanced to the end of the available sequence data), the function * returns -1, since the current data position does not actually exist. * Otherwise, the line number of the character at the current data position * is returned. */static int s_LineInfoReaderGetCurrentLineNumber (TLineInfoReaderPtr lirp){ if (lirp == NULL || lirp->curr_line == NULL) { return -1; } else { return lirp->curr_line->line_num; }}/* This function safely interprets the position of the current data position * of the SLineInfoReader structure. If the structure is NULL or the * current line is NULL or the current line position is NULL (usually because * the data position has been advanced to the end of the available sequence * data), the function returns -1, since the current data position does not * actually exist. * Otherwise, the position within the line of the character at the current * data position is returned. */static int s_LineInfoReaderGetCurrentLineOffset (TLineInfoReaderPtr lirp){ if (lirp == NULL || lirp->curr_line == NULL || lirp->curr_line_pos == NULL) { return -1; } else { return lirp->curr_line->line_offset + lirp->curr_line_pos - lirp->curr_line->data; }}/* This function frees the memory associated with the SLineInfoReader * structure. Notice that this function does NOT free the SLineInfo list. * This is by design. */static void s_LineInfoReaderFree (TLineInfoReaderPtr lirp){ if (lirp == NULL) { return; } free (lirp); lirp = NULL;}/* This function retrieves the "pos"th sequence data character from the lines * of sequence data. If the data position requested is greater than the * current position, the current data pointer will be advanced until the * current position is the requested position or there is no more data. If * there is no more data, the function returns a 0. If the data position * requested is lower than the current position, the current position is reset * to the beginning of the sequence and advanced from there. * As a result, it is clearly more efficient to read the data in the forward * direction, but it is still possible to access the data randomly. */static char s_FindNthDataChar
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -