#include "common.h" /* realloc() */ #include "geninc.h" #include "valuelst.h" /* VALUE_CODE[] */ /***************************************************************************** * * * COMMON OCEANOGRAPHIC DATA ACCESS SYSTEM (CODAS) * * * * WRITTEN BY: RAMON CABRERA, ERIC FIRING, and JULIE RANADA * * JOINT INSTITUTE FOR MARINE AND ATMOSPHERIC RESEARCH * * 1000 POPE ROAD MSB 404 * * HONOLULU, HI 96822 * * * * VERSION: 3.00 * * * * DATE: APRIL 1989 * * * *****************************************************************************/ /* FILE: defstruc.c FUNCTIONS FOR PROCESSING DEFINE_STRUCT STATEMENT */ /*----------------------------------------------------------------------------- FUNCTION: define_struct Processes a DEFINE_STRUCT statement in the producer definition file. It sets up a space in memory for the array of STRUCTURE_DEFINITION_ ENTRY_TYPE structures corresponding to each element of the structure being defined. It sets the structure_definition and nelem fields of the data_list entry (if id < MAX_DATA_LIST_SIZE) or elem_list entry (otherwise) accordingly. PARAMETERS: fpin = pointer to file containing structure definition head_ptr = address of pointer to head of list of structure definitions nentries = pointer to no. of entries in list so far RETURNS: 0 if okay system or database error code otherwise */ int define_struct(FILE *fpin, STRUCT_DEF_HDR_TYPE **head_ptr, USHORT *nentries) { int i, nelem, temp; unsigned int add_bytes; long curpos; CHAR struct_name[20], keyword[20], type[12], buff[80]; STRUCT_DEF_ENTRY_TYPE *str_def; if (getwords_nc(fpin, buff, 80, 2) != 2) goto read_error; if (sscanf(buff, " %19s %d", struct_name, &nelem) != 2) goto read_error; struct_name[19] = '\0'; add_bytes = (nelem + 1) * STRUCT_DEF_ENTRY_SIZE; if ((*head_ptr = (STRUCT_DEF_HDR_TYPE *) realloc((char *) (*head_ptr), *nentries * STRUCT_DEF_ENTRY_SIZE + add_bytes)) == NULL) return(INSUFFICIENT_MEMORY); str_def = (STRUCT_DEF_ENTRY_TYPE *) (*head_ptr) + *nentries; set_byte((UBYTE *) str_def, 0, add_bytes); strcpy(str_def->hdr.name, struct_name); str_def->hdr.nelem = (LONG) nelem; str_def += 1; for (i = 0; i < nelem; i++) { getword_nc(fpin, keyword, 20); if (strcmp(keyword, "ELEM")) { printf("\n SCANNING: %s, should be ELEM\n", keyword); return(READ_ERROR); } if (getwords_nc(fpin, buff, 80, 4) != 4) goto read_error; if (sscanf(buff, " %hd %11s %19s %11s", &(str_def[i].elem.count), type, str_def[i].elem.name, str_def[i].elem.units) != 4) goto read_error; if ((temp = get_code(VALUE_CODE, type)) == BADINT) { printf("\n SCANNING: %s\n", buff); return(INVALID_VALUE_TYPE); } else str_def[i].elem.value_type = temp; curpos = ftell(fpin); if (getword_nc(fpin, keyword, 20)) { if (!strcmp(keyword, "FORMAT")) *((FORMAT_SPEC **) str_def[i].elem.format_ptr) = define_format_spec(fpin); else if (fseek(fpin, curpos, SEEK_SET) != 0) return(SEEK_ERROR); } } *nentries += (nelem + 1); return(0); read_error: printf("\n SCANNING: %s ", buff); return(READ_ERROR); } /* ARRAY OF POINTERS TO PRINT FUNCTIONS -- Default is fprintf; special print functions must return unsigned int indicating number of bytes printed, and take output file pointer and data pointer as arguments. */ static struct { char *name; unsigned int (*print_function)(); } PRINT_FUNCTION[] = { {"" , NULL}, /* NULL pointer defaults to fprintf */ {"NULL" , NULL}, {"fprintf" , NULL}, {"print_bit_pattern" , print_bit_pattern}, {"print_ymdhms_time" , print_ymdhms_time}, {"print_dmsh_position", print_dmsh_position}, {"prpckpt" , prpckt}, {"prpckp" , prpckp}, {NULL , NULL} /* list terminator must be NULL */ }; /*----------------------------------------------------------------------------- FUNCTION: define_format_spec It reads a format specification from an external text file, allocates memory and loads it into memory. PARAMETER: fpin = pointer to external text file RETURNS: pointer to memory location that the format specification has been loaded into if okay NULL otherwise */ FORMAT_SPEC *define_format_spec(FILE *fpin) { char line[255], print_function_name[20], *format_string, pause_string[6], test[3]; int pause, print_function_index; FORMAT_SPEC *format_ptr; if (get_quotation(fpin, line, 255) == NULL) goto read_error; if ((format_string = malloc(strlen(line))) == NULL) goto memory_error; if ((format_ptr = (FORMAT_SPEC *) malloc(sizeof(FORMAT_SPEC))) == NULL) goto memory_error; strcpy(format_string, line); if (getwords_nc(fpin, line, 256, 2) != 2) goto read_error; if (sscanf(line, " %5s %19s %2s", pause_string, print_function_name, test) != 2) goto read_error; if (!stricmp(pause_string, "PAUSE")) pause = PAUSE; else if (!stricmp(pause_string, "GO")) pause = GO; else goto read_error; if ((print_function_index = find_print_function(print_function_name)) < 0) goto read_error; format_ptr->fmt_string = format_string; format_ptr->pause = pause; format_ptr->print_function = PRINT_FUNCTION[print_function_index].print_function; return(format_ptr); read_error: printf("\n ERROR: In define_format_spec\n Scanning: %s\n", line); return(NULL); memory_error: printf("\n ERROR: In define_format_spec\n Insufficient memory\n"); return(NULL); } /*----------------------------------------------------------------------------- FUNCTION: find_print_function Given the name of a special printing function, it searches the static array PRINT_FUNCTION for the corresponding index. PARAMETER: fn_name = name of printing function to search for RETURNS: array index if found -1 otherwise */ int find_print_function(char *fn_name) { int i = 0; while (PRINT_FUNCTION[i].name) if (!stricmp(PRINT_FUNCTION[i].name, fn_name)) return(i); else i++; return(-1); }