static char *RCSid = "$Id: parse_keys.c,v 1.1 2000/01/14 22:49:16 jwm Exp $"; /*********************************************************************** parse_keys.c ********************************************************************** Description: Contains functions which provide fundamental operations for patient data tape exchange. Modules included are: space_remove_and_cap() removes imbedded spaces from a string and converts it to upper case strip_string() removes all leading and trailing spaces from a null terminated text string parse_key() determines the key index from a passed in list of keywords parse_value() determines the value index for a key value, if any. extract_line() extract text line out of an AAPM formatted text buffer block and removes the line terminator. expand_key() expands legal abbreviations into their full text equivalent (only supports '#' for now). extract_ints() extracts integer(s) from a text string using AAPM supported delimiters between values. extract_floats() extracts integer(s) from a text string using AAPM supported delimiters between values. remove_quotes() removes all quoted strings from ASCII data text buffered line. read_comment_string() reads a string from a text file and strips off any terminator and any comments (comments are all text following a ';' in the string) read_aapm_dose_values() reads a line of doses from an AAPM formatted dose file and extracts the dose values into an array. Handles buffered data files. ************************ Revision History: $Log: parse_keys.c,v $ * Revision 1.1 2000/01/14 22:49:16 jwm * Remove comments originating in other development trees * * Revision 1.0 2000/01/14 22:34:49 jwm * Initial revision =================================================================== */ /* Include Files */ #include #include #include #include #include #include #include "sitedata.h" #define NOT_MAIN #include "exchkeys.h" #include "patexchange.h" #define LINE_LENGTH_LIMIT 80 /*********************************************************************** space_remove_and_cap() ********************************************************************** Functional Description: Removes all spaces from a string and converts all characters to uppercase. *********************************************************************/ void space_remove_and_cap /* REMOVE SPACES AND FORCE TO UPPER CASE */ ( char *string /* STRING TO STRIP AND CONVERT TO UPPERCASE */ ) { char temp_string[120]; /* TEMPORARY STRING */ char *ptr; /* POINTER FOR STRTOK'ING THROUGH STRING */ int length; /* LENGTH OF STRING TO FORCE TO UPPER CASE */ int i; /* LOOP COUNTER */ /* MAKE A LOCAL COPY FOR MANIPULATION */ strcpy( temp_string, string ); /* BREAK THE STRING INTO TOKENS COPYING THE PIECES BACK TO string */ ptr = strtok( temp_string, " " ); /* IF ptr IS NULL, NO SPACES EXIST */ if ( ptr == NULL ) return; /* COPY THE BEGINNING OF THE STRING */ strcpy( string, ptr ); /* UNTIL ptr IS NULL, KEEP MOVING STRING PIECES */ while( (ptr = strtok( NULL, " " )) != NULL ) { strcat( string, ptr ); } /* FORCE THE RETURNED STRING TO UPPERCASE */ length = strlen( string ); for ( i=0; istart; stop-- ) { if ( temp_string[stop] != ' ' && temp_string[stop] != '\t' ) break; } /* COPY THE APPROPRIATE PIECES INTO THE STRING RETURNED */ for ( i=start; i<=stop; i++ ) string[i-start] = temp_string[i]; /* NULL TERMINATE THE STRING */ string[i-start] = '\0'; } /**************** End of space_remove_and_cap() ***********************/ /*********************************************************************** parse_key() ********************************************************************** Functional Description: Returns the index of the key in the character string passed in. ************************ Processing: Parses a key/value line with := separators into a key and a value string. The key is evaluated for equivalence with known keys and the index number+1 of the key is returned. The value string returned is dynamically allocated and includes everything to the right of the separator. Returns the index of the key, or a -1 if the key is not in list. ************************ Programmer Notes: * END *********************************************************************/ int parse_key /* GET KEY INDEX NUMBER AND VALUE STRING */ ( char *string, /* STRING PASSED IN */ char *keylist[], /* LIST OF KNOWN KEYS */ int num_keys, /* NUMBER OF KEYS IN LIST */ char **value_string /* PORTION TO RIGHT OF := SEPARATOR */ ) { char *ptr; /* POINTER TO SEPARATOR STRING */ char temp_string[MAX_LINE_LENGTH]; /* TEMP COPY OF PASSED IN STRING */ int i; /* LOOP COUNTER */ char *break_ptr; /* POINTER TO NEXT STRING SEGMENT */ /* DUPLICATE THE STRING */ strcpy( temp_string, string ); /* ENSURE THAT A SEPARATOR EXISTS */ if ( (ptr = strstr( temp_string, ":=" )) == NULL ) /* THIS IS NOT A DELIMITED LINE. RETURN ekUNDEFINEDKEY */ return( num_keys-1 ); /* SHOULD POINT TO AN UNDEFINED KEY */ /* PULL THE KEY OFF, REMOVE ALL SPACES AND FORCE TO UPPERCASE */ *ptr = '\0'; space_remove_and_cap( temp_string ); /* EXPAND ANY SPECIAL CHARACTERS */ if ( expand_key( temp_string ) != SUCCESS ) return( FAILURE ); /* SEARCH ALL KEYS FOR A MATCH */ for ( i=0; i= max_buffer_length ) { sprintf( aapm_log_string, "Error. String too long for buffer (%d)", position ); aapm_status( eAAPM_ERROR, aapm_log_string ); buffer[position] = '\0'; return( FAILURE ); } if ( position >= LINE_LENGTH_LIMIT && error_count == 0 ) { sprintf( aapm_log_string, "String exceeds 80 char length (CONTINUING)" ); aapm_status( eAAPM_ERROR, aapm_log_string ); error_count = 1; } position++; break; } /* INCREMENT THE DATA BLOCK INDEX */ (*offset)++; } /* NULL TERMINATE THE STRING */ buffer[position] = '\0'; return( SUCCESS ); } /******************** End of extract_line() ***************************/ /*********************************************************************** expand_key() ********************************************************************** Functional Description: Expands special characters in a keyword or value string into the appropriate textual substitute. *********************************************************************/ int expand_key ( char *string /* KEY STRING TO BE EXPANDED */ ) { char temp_string[MAX_LINE_LENGTH]; /* TEMPORARY STORAGE STRING */ static char *number="NUMBER"; int position, i, j; /* INDICES */ int num_to_process; int total_length; /* ENSURE THAT THE STRING IS SHORT ENOUGH */ total_length = strlen( string ); if ( total_length >= MAX_LINE_LENGTH ) return( FAILURE ); strcpy( temp_string, string ); /* SEARCH FOR SPECIAL CHARACTERS */ position = 0; num_to_process = strlen( temp_string ); for (i=0; i= MAX_LINE_LENGTH ) return( FAILURE ); for ( j=0; j 120) { printf("**** In extract_ints(): string too long = %d ****",len); exit(1); } /* EXTRACT ALL QUOTED STRINGS, LEAVING ONLY THE GOOD STUFF */ remove_quotes( string, tmp_string ); /* EXTRACT ALL VALUES EXPECTING A SPACE OR COMMA DELIMITER */ ptr = strtok( tmp_string, " ," ); count = 0; while( ptr != NULL ) { array[count] = atoi( ptr ); if( ++count >= max_array ) break; /* We've already got the request filled */ ptr = strtok( NULL, " ," ); } return( count ); } /********************* End of extract_ints() **************************/ /*********************************************************************** extract_floats() ********************************************************************** Functional Description: Extracts floating point value(s) from a character string. *********************************************************************/ int extract_floats ( char *string, /* STRING CONTAINING INTS */ float *array, /* ARRAY TO FILL WITH VALUES EXTRACTED */ int max_array /* MAXIMUM # OF ARRAY MEMBERS ALLOWED */ ) { int count; /* # OF VALUES EXTRACTED */ char tmp_string[121]; /* TEMP STRING HOLDER */ char *ptr; /* TEMP STRING POINTER */ int len; /* LENGTH OF INPUT STRING */ /* CHECK INPUT STRING SIZE */ if( (len = strlen(string)) > 120) { printf("**** In extract_floats(): string too long = %d ****",len); exit(1); } /* EXTRACT ALL QUOTED STRINGS, LEAVING ONLY THE GOOD STUFF */ remove_quotes( string, tmp_string ); /* EXTRACT ALL VALUES EXPECTING A SPACE OR COMMA DELIMITER */ ptr = strtok( tmp_string, " ," ); count = 0; while( ptr != NULL ) { array[count] = atof( ptr ); if( ++count >= max_array ) break; /* We've already got the request filled */ ptr = strtok( NULL, " ," ); } return( count ); } /********************** End of extract_floats() ***********************/ /*********************************************************************** remove_quotes() ********************************************************************** Functional Description: Extracts all quoted (") strings from a string and returns the rest. *********************************************************************/ void remove_quotes ( char *source, /* SOURCE STRING */ char *dest /* DESTINATION STRING MUST BE SAME SIZE AS SOURCE STRING */ ) { int length; /* LENGTH OF SOURCE STRING */ int i; /* SOURCE STRING CHARACTER INDEX */ int j; /* DEST STRING CHARACTER INDEX */ int cur_quote; /* FLAG FOR CHARACTERS IN QUOTED FIELD (1) OR OUTSIDE QUOTED FIELD (0) */ /* COPY SOURCE TO DEST 1 CHAR AT A TIME */ length = strlen( source ); /* SET FLAG SO THAT FIRST CHARACTER IS NOT IN QUOTED SECTION */ cur_quote = j = 0; for ( i=0; i character and with any comment (delimited by ';') stripped off. *********************************************************************/ int read_comment_string ( char *string, /* STRING TO READ INTO */ int length, /* MAXIMUM LENGTH OF STRING */ FILE *input /* INPUT FILE STREAM POINTER */ ) { char *ptr; /* POINTER TO COMMENT START */ /* READ THE STRING */ if ( read_string( string, length, input ) != SUCCESS ) return( FAILURE ); /* STRIP OFF ANY COMMENT */ ptr = strchr( string, ';' ); if ( ptr != NULL ) *ptr = '\0'; return( SUCCESS ); } /********************** End of read_comment_string() ******************/ /*********************************************************************** read_aapm_dose_values() ********************************************************************** Functional Description: Reads a text string out of a text block in memory. If a null length string is returned, and the pointer is at the end of the block, it reads in the next block of data. *********************************************************************/ int read_aapm_dose_values ( FILE *input, /* INPUT FILE STREAM POINTER */ dosedist_t *doses, /* DOSE STRUCTURE */ float *array, /* ARRAY TO PUT VALUES INTO */ int max_array /* MAXIMUM NUMBER OF ENTRIES IN ARRAY */ ) { char string[82]; /* TEXT READING STRING */ /* READ THE NEXT STRING OUT OF THE BUFFER */ while ( extract_line( doses->data_block, &(doses->offset), doses->block_size, string, 82 ) != SUCCESS ) { /* READ IN THE NEXT BUFFER IF OUT OF DATA AND MORE EXISTS */ if ( doses->cur_block >= doses->total_blocks ) { sprintf( aapm_log_string, "Premature EOF for doses" ); aapm_status( eAAPM_ERROR, aapm_log_string ); return( -1 ); } else { /* READ IN THE NEXT BLOCK AND TRY AGAIN */ if ( fread( (void *)doses->data_block, (size_t)1, (size_t)doses->block_size, input) != doses->block_size ) { sprintf( aapm_log_string, "Error reading block #%d of dose text data", doses->cur_block ); aapm_status( eAAPM_ERROR, aapm_log_string ); return( -1 ); } /* RESET THE OFFSET AND CURRENT BLOCK NUMBER */ doses->cur_block++; doses->offset = 0; } } /* END OF WHILE LOOP */ /* READ DOSE VALUES OUT OF THE ARRAY AND RETURN THE NUMBER OF VALUES READ */ return( extract_floats( string, array, max_array )); } /****************** End of read_aapm_dose_values() ******************/ /********************* End of parse_keys.c ****************************/