static char rcsver[] = "$Id: header.c,v 2.2 1999/07/12 23:14:08 gorelick Exp $"; /** ** $Source: /tes/src/vanilla/RCS/header.c,v $ ** ** $Log: header.c,v $ ** Revision 2.2 1999/07/12 23:14:08 gorelick ** *** empty log message *** ** ** Revision 2.1 1999/02/10 04:00:50 gorelick ** *** empty log message *** ** ** Revision 2.0 1998/12/22 22:47:04 gorelick ** release version ** ** Revision 2.0 1998/12/18 01:26:03 gorelick ** release version ** ** Revision 1.5 1998/12/18 01:04:48 gorelick ** *** empty log message *** ** ** Revision 1.4 1998/11/12 22:58:55 gorelick ** first release version ** **/ #include "header.h" #include "proto.h" #include "io_lablib3.h" #define GetKey(ob, name) OdlFindKwd(ob, name, NULL, 0, ODL_THIS_OBJECT) FIELD *MakeField(OBJDESC *, LABEL *); int DetermineFieldType(char *type, int size); IFORMAT eformat_to_iformat(EFORMAT e); /** ** LoadLabel() - Read and decode a PDS label, including individual fields. **/ LABEL * LoadLabel(char *fname) { OBJDESC *ob, *tbl, *col; KEYWORD *kw; FIELD *f; LIST *list; LABEL *l; int i; ushort scope; int reclen, nfields; char *name, *alias = NULL; ob = OdlParseLabelFile(fname, NULL, ODL_EXPAND_STRUCTURE, 1); if (ob == NULL) { fprintf(stderr, "Unable to read file: %s\n", fname); return (NULL); } /* find the first (and only?) table object */ if ((tbl = OdlFindObjDesc(ob,"TABLE",NULL,NULL, 0, ODL_TO_END)) == NULL) { fprintf(stderr, "Unable to find TABLE object: %s\n", fname); fprintf(stderr, "Is this a vanilla file?\n"); return (NULL); } if ((kw = OdlFindKwd(tbl, "ROW_BYTES", NULL,0, ODL_THIS_OBJECT)) != NULL) { reclen = atoi(OdlGetKwdValue(kw)); } else { fprintf(stderr, "Unable to find keyword: ROW_BYTES: %s\n", fname); fprintf(stderr, "Is this a vanilla file? Is it's ^STRUCTURE file ok?\n"); return (NULL); } if ((kw = OdlFindKwd(tbl, "COLUMNS", NULL, 0, ODL_THIS_OBJECT)) != NULL) { nfields = atoi(OdlGetKwdValue(kw)); } else { fprintf(stderr, "Unable to find keyword: COLUMNS\n"); return (NULL); } if ((kw = OdlFindKwd(tbl, "NAME", NULL, 0, ODL_THIS_OBJECT)) != NULL) { name = OdlGetKwdValue(kw); } l = calloc(1, sizeof(LABEL)); l->reclen = reclen; l->nfields = nfields; l->name = name; /** ** get all the column descriptions **/ list = new_list(); i = 0; scope = ODL_CHILDREN_ONLY; col = tbl ; while ((col = OdlNextObjDesc(col, 0, &scope)) != NULL) { if ((f = MakeField(col, l)) != NULL) { list_add(list, f); i++; } } if (list->number != nfields) { fprintf(stderr, "Wrong number of column definitions. Expected %d, got %d.\n", list->number, nfields); } l->fields = list; /** ** Get list of key fields **/ if ((kw = GetKey(tbl, "PRIMARY_KEYS")) != NULL || (kw = GetKey(tbl, "PRIMARY_KEY")) != NULL || (kw = GetKey(tbl, "KEYS")) != NULL) { int j; LIST *keylist; FIELD *f; char keyname[256]; char **array; i = OdlGetAllKwdValuesArray(kw, &array); keylist = new_list(); for (j = 0; j < i; j++) { strcpy(keyname, &array[j][1]); keyname[strlen(keyname) - 1] = 0; if ((f = FindFieldInLabel(keyname, l)) == NULL) { fprintf(stderr, "Unable to find key: \"%s\" in label \"%s\"\n", keyname, l->name); return(NULL); } list_add(keylist, f); } l->keys = keylist; } return (l); } /** ** Convert a field description into a FIELD struct **/ FIELD * MakeField(OBJDESC *col, LABEL *l) { FIELD *f; VARDATA *vardata; KEYWORD *kw; int i = 0; char *ptr; do { f = (FIELD *) calloc(1, sizeof(FIELD)); f->label = l; if ((kw = GetKey(col, "NAME")) == NULL) { fprintf(stderr, "Column %d has no name.\n", i); break; } f->name = OdlGetKwdValue(kw); f->alias = NULL; if ((kw = GetKey(col, "ALIAS_NAME")) != NULL) { f->alias = OdlGetKwdValue(kw); } if ((kw = GetKey(col, "START_BYTE")) == NULL) { fprintf(stderr, "Column %s: START_BYTE not specified.\n", f->name); break; } f->start = atoi(OdlGetKwdValue(kw)) - 1; if ((kw = GetKey(col, "BYTES")) == NULL) { fprintf(stderr, "Column %s: BYTES not specified.\n", f->name); break; } f->size = atoi(OdlGetKwdValue(kw)); if ((kw = GetKey(col, "ITEMS")) != NULL) { f->dimension = atoi(OdlGetKwdValue(kw)); /** ** If BYTES was specified, this will overwrite the value ** with the indivdual element size, as we expect. **/ if ((kw = GetKey(col, "ITEM_BYTES")) != NULL) { f->size = atoi(OdlGetKwdValue(kw)); } else { fprintf(stderr, "Column %s: ITEM_BYTES not specified, dividing BYTES by ITEMS.\n", f->name); f->size = f->size / f->dimension; } } if ((kw = GetKey(col, "DATA_TYPE")) == NULL) { fprintf(stderr, "Column %s: DATA_TYPE not specified.\n", f->name); break; } f->type = OdlGetKwdValue(kw); if ((f->eformat = ConvertType(f->type)) == -1) { fprintf(stderr, "Unrecognized type: %s, %s %d bytes\n", f->name, f->type, f->size); break; } f->iformat = eformat_to_iformat(f->eformat); if ((kw = GetKey(col, "SCALING_FACTOR")) != NULL) { f->scale = atof(OdlGetKwdValue(kw)); } if ((kw = GetKey(col, "OFFSET")) != NULL) { f->offset = atof(OdlGetKwdValue(kw)); } if ((kw = GetKey(col, "VAR_RECORD_TYPE")) != NULL) { ptr = OdlGetKwdValue(kw); vardata = f->vardata = calloc(1, sizeof(VARDATA)); if (!strcmp(ptr, "VAX_VARIABLE_LENGTH")) vardata->type = VAX_VAR; else if (!strcmp(ptr, "Q15")) vardata->type = Q15; else { fprintf(stderr, "Unrecognized VAR_DATA_TYPE: %s\n", ptr); } if ((kw = GetKey(col, "VAR_ITEM_BYTES")) != NULL) { vardata->size = atoi(OdlGetKwdValue(kw)); if ((kw = GetKey(col, "VAR_DATA_TYPE")) != NULL) { ptr = OdlGetKwdValue(kw); } else { fprintf(stderr, "VAR_DATA_TYPE not specified for field: %s\n", f->name); exit(1); } if ((vardata->eformat = ConvertType(ptr)) == -1) { fprintf(stderr, "Unrecognized vartype: %s, %s %d bytes\n", f->name, ptr, vardata->size); } vardata->iformat = eformat_to_iformat(vardata->eformat); } else { fprintf(stderr, "VAR_ITEM_BYTES not specified for field: %s\n", f->name); exit(1); } } if (f->eformat == BYTE_OFFSET) { f->eformat = MSB_INTEGER; f->iformat = eformat_to_iformat(f->eformat); vardata = f->vardata = calloc(1, sizeof(VARDATA)); vardata->size = 2; vardata->eformat = MSB_INTEGER; vardata->iformat = INT; vardata->type = Q15; } /* f->label; f->name; f->start; f->size; f->dimension; f->eformat; f->iformat; f->scale; f->offset; f->vardata; vardata->type; vardata->size; */ return(f); } while(0); return(NULL); } IFORMAT eformat_to_iformat(EFORMAT e) { switch(e) { case MSB_INTEGER: case ASCII_INTEGER: return(INT); break; case MSB_UNSIGNED_INTEGER: case BYTE_OFFSET: return(UINT); break; case IEEE_REAL: case ASCII_REAL: return ( REAL ); break; case CHARACTER: return ( STRING ); break; default: fprintf(stderr, "Unrecognized etype: %d\n", e); } } int ConvertType(char *type) { if (!strcasecmp(type, "MSB_INTEGER")) { return(MSB_INTEGER); } else if (!strcasecmp(type, "MSB_UNSIGNED_INTEGER")) { return(MSB_UNSIGNED_INTEGER); } else if (!strcasecmp(type, "IEEE_REAL")) { return(IEEE_REAL); } else if (!strcasecmp(type, "CHARACTER")) { return(CHARACTER); } else if (!strcasecmp(type, "ASCII_INTEGER")) { return(ASCII_INTEGER); } else if (!strcasecmp(type, "ASCII_REAL")) { return(ASCII_REAL); } else if (!strcasecmp(type, "BYTE_OFFSET")) { return(BYTE_OFFSET); } return(-1); } /** ** Given a field name, locate it in the list of labels. **/ FIELD * FindField(char *name, LIST *tables) { char buf[256]; char *p; char *field_name; char *label_name; int i; TABLE *t; LABEL *l; FIELD *f; strcpy(buf, name); if ((p = strchr(buf, '.')) != NULL) { *p = '\0'; label_name = buf; field_name = p + 1; } else { label_name = NULL; field_name = buf; } /** ** If this field name includes a dimension, get rid of it **/ if ((p = strchr(field_name, '[')) != NULL) { *p = '\0'; } for (i = 0; i < tables->number; i++) { t = (tables->ptr)[i]; l = t->label; /** ** If the user told us what struct the field is in, skip all others **/ if (label_name && strcasecmp(label_name, l->name)) continue; /** ** There was an error here. Was just returning the check ** on the first label. **/ if ((f = FindFieldInLabel(field_name, l)) != NULL) { return(f); } } return (NULL); } FIELD * FindFieldInLabel(char *name, LABEL * l) { int i; FIELD **f = (FIELD **) l->fields->ptr; int nfields = l->fields->number; for (i = 0; i < nfields; i++) { if (!strcasecmp(name, f[i]->name)) { return (f[i]); } if (f[i]->alias && !strcasecmp(name, f[i]->alias)) { return (f[i]); } } return (NULL); } /** ** Load the header values specific to an individual file **/ FRAGMENT * LoadFragment(char *fname, TABLE *table) { OBJDESC *ob, *tbl, *col; KEYWORD *kw; LIST *startlist=NULL, *endlist=NULL; FRAGMENT *f; int rows; int offset; struct stat sbuf; if (stat(fname, &sbuf) == -1) { fprintf(stderr, "Unable to find file: %s\n", fname); return(NULL); } ob = OdlParseLabelFile(fname, NULL, ODL_EXPAND_STRUCTURE, 1); if (ob == NULL) { fprintf(stderr, "Unable to read file: %s\n", fname); return (NULL); } if ((kw = OdlFindKwd(ob, "^TABLE", NULL, 0, ODL_THIS_OBJECT)) != NULL) { offset = atoi(OdlGetKwdValue(kw)); } else { fprintf(stderr, "Unable to find table pointer (^TABLE) in: %s\n", fname); return (NULL); } /* find the first (and only?) table object */ if ((tbl = OdlFindObjDesc(ob, "TABLE", NULL, NULL, 0, ODL_TO_END)) == NULL) { fprintf(stderr, "Unable to find TABLE object: %s\n", fname); return (NULL); } if ((kw = OdlFindKwd(tbl, "ROWS", NULL,0, ODL_THIS_OBJECT)) != NULL) { rows = atoi(OdlGetKwdValue(kw)); } else { fprintf(stderr, "Unable to find keyword ROWS: %s\n", fname); return (NULL); } if ((kw = GetKey(tbl, "START_KEYS")) != NULL) { int i,j; char **array; DATA *dataval; FIELD **keys = (FIELD **)table->label->keys->ptr; i = OdlGetAllKwdValuesArray(kw, &array); startlist = new_list(); dataval = calloc(i, sizeof(DATA)); for (j = 0; j < i; j++) { dataval[j] = ConvertASCIItoData(array[j], keys[j]->iformat); list_add(startlist, &dataval[j]); } } else if ((kw = GetKey(tbl, "START_KEY")) != NULL) { DATA *dataval; FIELD **keys = (FIELD **)table->label->keys->ptr; startlist = new_list(); dataval = calloc(1, sizeof(DATA)); dataval[0] = ConvertASCIItoData(OdlGetKwdValue(kw), keys[0]->iformat); list_add(startlist, &dataval[0]); } if ((kw = GetKey(tbl, "END_KEYS")) != NULL) { int i,j; char **array; DATA *dataval; FIELD **keys = (FIELD **)table->label->keys->ptr; i = OdlGetAllKwdValuesArray(kw, &array); endlist = new_list(); dataval = calloc(i, sizeof(DATA)); for (j = 0; j < i; j++) { dataval[j] = ConvertASCIItoData(array[j], keys[j]->iformat); list_add(endlist, &dataval[j]); } } else if ((kw = GetKey(tbl, "STOP_KEY")) != NULL) { DATA *dataval; FIELD **keys = (FIELD **)table->label->keys->ptr; endlist = new_list(); dataval = calloc(1, sizeof(DATA)); dataval[0] = ConvertASCIItoData(OdlGetKwdValue(kw), keys[0]->iformat); list_add(endlist, &dataval[0]); } f = calloc(1, sizeof(FRAGMENT)); /** ** This is the all important ^PTR conversion **/ f->offset = (offset - 1) * table->label->reclen; f->nrows = rows; f->start_keys = startlist; f->end_keys = endlist; f->sbuf = sbuf; if (sbuf.st_size != f->offset + f->nrows * table->label->reclen) { fprintf(stderr, "File is an odd size: %s\n", fname); } return(f); }