/*****************************************************************************/ /* */ /* UNIT: NTL2_Read_TFDreferences (Level 2 library routine) */ /* */ /* Author: Nikola Stojanovic */ /* */ /* Revision: 09 AUG 94 Version 1.0 */ /* */ /* Function: */ /* */ /* Procedure reads the specified references from the Transcription Factor */ /* Database references file, in the "plain text" format, into a vector of */ /* character strings with full reference descriptions; due to the size of */ /* the references file only the specified references are read. */ /* Procedure receives the name of the file containing TFD references */ /* catalogue, number of requested references and vector of character strings */ /* with reference codes; fills in the full reference information into */ /* another vector of strings. Procedure returns the error structure, NULL if */ /* everything was OK */ /* */ /* */ /* Expected format of the Transcription Factor Database references file: */ /* */ /* */ /*****************************************************************************/ #include #include #include #include "ntl2.h" /*****************************************************************************/ /* */ /* Definitions section */ /* */ /*****************************************************************************/ /*****************************************************************************/ /* Definitions of local constants of the unit */ /*****************************************************************************/ /* Limit for the length of an error message that can be assembled */ #define ERR_MSGLIMIT 128 /* Information is read from database files by supplementary buffer of size: */ #define IN_LIMIT 200 /* Delimiting positions for various blocks of information within a line */ #define REF_CODE_START 1 #define REF_CODE_STOP 8 #define SITE_INFO_START 9 #define SITE_INFO_STOP 45 #define REFERENCE_START 46 #define REFERENCE_STOP 180 /*****************************************************************************/ /* Prototypes of all locally used functions of this unit */ /*****************************************************************************/ void NTL2_RR_Sort_Selections (int number, char **selections); errind NTL2_RR_Read_References (FILE **ref_file, int number, char **selections, char **details); errind NTL2_RR_Assemble_Error (int severity, int code, char *comment, int description); /*****************************************************************************/ /* Definitions of global (static) variables of the unit */ /*****************************************************************************/ static char In_Buff [IN_LIMIT]; /* Global input line buffer, for convenience */ static char Error_Message [ERR_MSGLIMIT]; /* Temporary buffer, error passing */ /*****************************************************************************/ /* */ /* Code section */ /* */ /*****************************************************************************/ /*****************************************************************************/ /* */ /* Procedure: NTL2_Read_TFDreferences */ /* */ /* Main (interface) procedure of this unit */ errind NTL2_Read_TFDreferences (char *file_name, int number, char **selections, char **details) { FILE *ref_file; int index; errind erret; /* Check the legality of the received information and open the file */ if (number <= 0) return NTL2_RR_Assemble_Error (USER_ERROR, ERR_BAD_REFERENCE, "Illegal number of references requested", 1); if ((ref_file = fopen (file_name, "r")) == NULL) { /* Error condition */ sprintf (Error_Message, "File <%s> does not exist", file_name); return NTL2_RR_Assemble_Error (USER_ERROR, ERR_NO_FILE, Error_Message, 0); } else { /* There is a file with the specified name */ /* Initialize the expanded details vector */ for (index = 0; index < number; index++) details [index] = NULL; /* Sort the received list of selections in alphabetical order */ NTL2_RR_Sort_Selections (number, selections); /* Now load the references from the file and close the file when done */ erret = NTL2_RR_Read_References (&ref_file, number, selections, details); if ((erret != NULL) && (erret -> kind != WARNING)) { /* Serious error */ /* Release all the strings allocated so far in the process */ for (index = 0; index < number; index++) if (details [index] != NULL) { free (details [index]); details [index] = NULL; } } fclose (ref_file); return erret; } } /*****************************************************************************/ /* */ /* Procedure: NTL2_RR_Sort_Selections */ /* */ /* Procedure sorts the received vector of strings in the alphabetical order */ void NTL2_RR_Sort_Selections (int number, char **selections) { int last, current; char *temp; for (last = number - 1; last >= 1; last--) { for (current = 0; current < last; current++) { if (strcmp (selections [current], selections [current + 1]) > 0) { temp = selections [current]; selections [current] = selections [current + 1]; selections [current + 1] = temp; } } } } /*****************************************************************************/ /* */ /* Procedure: NTL2_RR_Read_References */ /* */ /* Top level procedure for reading the Transcription Factor Database */ /* references file contents (only the records from the provided list, */ /* though); loops for each reference (line) defined in the file; receives */ /* the file pointer, number of records to read and vector of reference */ /* codes to search for; fills in the vector of expanded references; */ /* returns the assembled error record, NULL if there were no errors in */ /* loading */ errind NTL2_RR_Read_References (FILE **ref_file, int number, char **selections, char **details) { int index, space_count; char save_char, *check_string; index = 0; while (/*(*/(fgets (In_Buff, IN_LIMIT, *ref_file) != NULL) /*&& (In_Buff [0] != '\0'))*/ && (index < number)) { if ((In_Buff [0] != '\0') && (In_Buff [0] != '\n')) { if (strlen (In_Buff) < REFERENCE_START) return NTL2_RR_Assemble_Error (USER_ERROR, ERR_FILE_FORMAT, "Illegal line length in TFD reference file", 0); /* Locate the abbreviation for the reference described in the line */ space_count = REF_CODE_STOP - 1; while (((In_Buff [space_count] == ' ') || (In_Buff [space_count] == '\t')) && (space_count >= REF_CODE_START)) space_count--; if ((In_Buff [space_count] != ' ') && (In_Buff [space_count] != '\t')) space_count++; save_char = In_Buff [space_count]; In_Buff [space_count] = '\0'; check_string = NTL0_strsave (&(In_Buff [REF_CODE_START - 1])); In_Buff [space_count] = save_char; /* Check now whether there is a match between the next code and this line */ if (!strcmp (check_string, selections [index])) { space_count = strlen (In_Buff) - 1; while (((In_Buff [space_count] == ' ') || (In_Buff [space_count] == '\t') || (In_Buff [space_count] == '\n')) && (space_count >= REFERENCE_START)) space_count--; if ((In_Buff [space_count] != ' ') && (In_Buff [space_count] != '\t') && (In_Buff [space_count] != '\n')) space_count++; save_char = In_Buff [space_count]; In_Buff [space_count] = '\0'; details [index] = NTL0_strsave (&(In_Buff [REFERENCE_START - 1])); In_Buff [space_count] = save_char; index++; while ((index < number) && (!strcmp (check_string, selections [index]))) { details [index++] = NTL0_strsave (&(In_Buff [REFERENCE_START - 1])); } } free (check_string); } } if (index < number) return NTL2_RR_Assemble_Error (USER_ERROR, ERR_BAD_REFERENCE, "Reference code not found", 0); else return NULL; } /*****************************************************************************/ /* */ /* Procedure: NTL2_RR_Assemble_Error */ /* */ /* Service procedure for assembling and returnning an error report, based on */ /* the values of the input parameters; returns the record with the report */ errind NTL2_RR_Assemble_Error (int severity, int code, char *comment, int description) { char *report; errind assembled; report = (char *) NTL0_ckalloc ( (strlen (comment) + strlen ("_Read_TFDreferences: ") + 1) * sizeof (char)); sprintf (report, "_Read_TFDreferences: %s", comment); assembled = NTL1_Error_Record (severity, code, report, description); free (report); return assembled; }