#include "dbinc.h" /***************************************************************************** * * * 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: dbloadsd.c FUNCTIONS FOR LOADING STRUCTURE DEFINITIONS FROM EXTERNAL FILE */ /*----------------------------------------------------------------------------- FUNCTION: DBLOADSD Loads a set of structure definitions from an external text file into memory, and appends it to a linked list of structure definitions for that database. PARAMETERS: filename = name of external text file ierr = error code RETURNS: VOID */ void DBLOADSD(char *filename, int *ierr) { STRUCT_DEF_HDR_TYPE *strdef_list, **link_address; USHORT nentries; *ierr = 0; if ((!(db_ptr)) || first_database_call) { *ierr = DB_IS_NOT_OPEN; return; } if ((db_ptr->error_code = load_structure_definition(filename, &strdef_list, &nentries, &(db_ptr->format_list))) != 0) { db_ptr->error_data = STRUCTURE_DEF; report_db_error("DBLOADSD"); *ierr = db_ptr->error_code * 1000 - db_ptr->error_data; return; } if (strdef_list) { if (db_ptr->struct_def == NULL) /* allows multiple calls to DBLOADSD */ { db_ptr->struct_def = strdef_list; db_ptr->prev_strdef = strdef_list + (nentries - 1); } else { concat_strdef(&(db_ptr->struct_def), strdef_list); if ((db_ptr->block_strdef_loaded) && (db_ptr->next_strdef == NULL)) { db_ptr->next_strdef = strdef_list; link_address = (STRUCT_DEF_HDR_TYPE **) &( (db_ptr->block_strdef + (db_ptr->block_hdr.struct_def_nentries - 1)) ->LINK_PTR ); *link_address = db_ptr->next_strdef; /* (db_ptr->block_strdef + (db_ptr->block_hdr.struct_def_nentries - 1)) ->pa.access.link_ptr = db_ptr->next_strdef; */ } } } if (db_ptr->format_list) if (match_formats(db_ptr->struct_def, db_ptr->format_list)) { report_db_error("DBLOADSD"); *ierr = FORMAT_ERROR; return; } } /*----------------------------------------------------------------------------- FUNCTION: load_structure_definition It loads structure definitions (DEFINE_STRUCT/ELEM/FORMAT) and structure printing formats (DEFINE_FORMAT) from an external text file into memory. PARAMETERS: filename = name of external text file hdr = pointer to memory location that structure definitions have been loaded into nentries = no. of STRUCT_DEF_ELEM_TYPE entries loaded format_list = pointer to memory location that structure printing formats have been loaded into RETURNS: 0 if okay error code otherwise */ int load_structure_definition(char *filename, STRUCT_DEF_HDR_TYPE **hdr, USHORT *nentries, FORMAT_HDR_TYPE **format_list) { FILE *fpin; char keyword[80]; USHORT fmt_nentries = 0; int error_code; *nentries = 0; /* ---> OPEN STRUCTURE DEFINITION FILE */ if ((fpin = fopen(filename, "rb")) == NULL) { printf("\n ERROR: Cannot open file %s", filename); return(UNABLE_TO_OPEN); } /* ---> ALLOCATE MEMORY FOR STRUCTURE DEFINITIONS & FORMAT SPECIFICATIONS */ if ((*hdr = (STRUCT_DEF_HDR_TYPE *) calloc(1, STRUCT_DEF_ENTRY_SIZE)) == NULL) return(INSUFFICIENT_MEMORY); if ((*format_list = (FORMAT_HDR_TYPE *) calloc(1, sizeof(FORMAT_ENTRY_TYPE))) == NULL) return(INSUFFICIENT_MEMORY); /* ---> SCAN EXTERNAL FILE */ while (getword_nc(fpin, keyword, 80)) { if (!strcmp(keyword, "DEFINE_STRUCT")) { if ((error_code = define_struct(fpin, hdr, nentries)) != 0) return(error_code); } else if (!strcmp(keyword, "DEFINE_FORMAT")) { if ((error_code = define_format(fpin, format_list, &fmt_nentries)) != 0) return(error_code); } else { printf("\n ERROR: Unrecognized parameter\n SCANNING: %s\n",keyword); return(READ_ERROR); } } fclose(fpin); /* ---> ADD NULL ENTRY TERMINATORS FOR THE TWO LINKED LISTS */ if (*nentries) { if ((*hdr = (STRUCT_DEF_HDR_TYPE *) realloc((char *) *hdr, (1 + *nentries) * STRUCT_DEF_ENTRY_SIZE)) == NULL) return(INSUFFICIENT_MEMORY); set_byte((UBYTE *) (*hdr + *nentries), 0, STRUCT_DEF_ENTRY_SIZE); (*nentries)++; /* add entry for NULL terminator */ } if (fmt_nentries) { if ((*format_list = (FORMAT_HDR_TYPE *) realloc((char *) *format_list, (1 + fmt_nentries) * sizeof(FORMAT_HDR_TYPE))) == NULL) return(INSUFFICIENT_MEMORY); set_byte((UBYTE *)(*format_list + fmt_nentries), 0, sizeof(FORMAT_HDR_TYPE)); return(match_formats(*hdr, *format_list)); } else return(0); } /*----------------------------------------------------------------------------- FUNCTION: define_format It processes the DEFINE_FORMAT statements from an external text file. PARAMETERS: fpin = pointer to external text file format_list = pointer to linked list of structure format definitions nentries = no. of FORMAT_ENTRY_TYPE entries in format_list RETURNS: 0 if okay error code otherwise */ int define_format(FILE *fpin, FORMAT_HDR_TYPE **format_list, USHORT *nentries) { char keyword[20], buff[80], test[3], *struct_name, *elem_name; USHORT nelem, i; unsigned int nbytes; FORMAT_ENTRY_TYPE *format_ptr; if ((getwords_nc(fpin, buff, 80, 2) != 2) || (sscanf(buff, "%19s %hd %2s", keyword, &nelem, test) != 2)) { printf("\n SCANNING: %s", buff); return(READ_ERROR); } nbytes = (*nentries + nelem + 1) * sizeof(FORMAT_ELEM_TYPE); if ((*format_list = (FORMAT_HDR_TYPE *) realloc(*format_list, nbytes)) == NULL) return(INSUFFICIENT_MEMORY); format_ptr = (FORMAT_ENTRY_TYPE *) *format_list + *nentries; if ((struct_name = malloc(strlen(keyword))) == NULL) return(INSUFFICIENT_MEMORY); strcpy(struct_name, keyword); format_ptr->hdr.name = struct_name; format_ptr->hdr.nelem = nelem; for (i = 0; i < nelem; i++) { format_ptr += 1; if (!getword_nc(fpin, keyword, 20)) goto read_error; if (strcmp(keyword, "FORMAT")) goto read_error; if (!getword_nc(fpin, keyword, 20)) goto read_error; if ((elem_name = malloc(strlen(keyword))) == NULL) return(INSUFFICIENT_MEMORY); strcpy(elem_name, keyword); format_ptr->elem.name = elem_name; format_ptr->elem.format_ptr = define_format_spec(fpin); } *nentries += nelem + 1; return(0); read_error: printf("\n SCANNING: %s\n", keyword); return(READ_ERROR); } /*----------------------------------------------------------------------------- FUNCTION: concat_strdef It appends a block of structure definitions to a linked list of more structure definitions. PARAMETERS: head = pointer to head of linked list new = pointer to block of structure definitions to be appended RETURNS: VOID */ void concat_strdef(STRUCT_DEF_HDR_TYPE **head, STRUCT_DEF_HDR_TYPE *new) { STRUCT_DEF_HDR_TYPE *member, *save, **link_address; if (*head == NULL) *head = new; else { member = *head; do { while (*(member->name)) member += member->nelem + 1; save = member; link_address = (STRUCT_DEF_HDR_TYPE **) &(save->LINK_PTR); member = *link_address; /* member = save->pa.access.link_ptr; */ } while (member != NULL); link_address = (STRUCT_DEF_HDR_TYPE **) &(save->LINK_PTR); *link_address = new; /* save->pa.access.link_ptr = new; */ } }