/***********************************************************************/ /* Open Visualization Data Explorer */ /* (C) Copyright IBM Corp. 1989,1999 */ /* ALL RIGHTS RESERVED */ /* This code licensed under the */ /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */ /***********************************************************************/ /* * $Header: /home/gda/dxcvs/dx/src/exec/dxmods/genimp_parse.c,v 1.3 1999/05/10 15:45:25 gda Exp $ */ #include #include #include "genimp.h" /* This should be the only visible entry point for this file */ Error _dxf_gi_InputInfoTable (char *, char *,FILE **); /* Flags to FileTok() 'newline' parameter */ #define NO_NEWLINE 0 #define NEWLINE_OK 1 #define FORCE_NEWLINE 2 #define L_CASE(str) \ {int si; \ for(si = 0; si < strlen(str); si++) \ str[si] = tolower(str[si]);} struct parse_state { FILE *fp; char *filename; int lineno; char *line; char token[MAX_DSTR]; char *current; }; static Error parse_marker(char *p,char *marker); static Error nextchar(char **p, unsigned int *c); static Error infoFile (struct parse_state *); static Error infoGrid (struct parse_state *); static Error infoSeries (struct parse_state *); static Error infoField (struct parse_state *); static Error infoStructure (struct parse_state *); static Error infoFormat (struct parse_state *); static Error infoType (struct parse_state *); static Error infoLayout (struct parse_state *); static Error infoMajority (struct parse_state *); static Error infoHeader (struct parse_state *); static Error infoInterleaving (struct parse_state *); static Error infoBlock (struct parse_state *); static Error infoPositions (struct parse_state *, struct place_state *); static Error infoPoints (struct parse_state *); static Error infoDepend (struct parse_state *); static Error infoRecSeparat (struct parse_state *); static Error infoEnd (struct parse_state *); static Error MakeupDefault (char *, int); static Error CheckInputs(void); static Error InitFileTok(struct parse_state *, FILE *, char *); static Error FileTok(struct parse_state *,char *, int , char** ); static Error get_header(struct parse_state *, char *, struct header *); static Error getline(struct parse_state *); static Error parse_template(char *, char **); static Error getmorevar(int *); static Error readplacement(char **, struct parse_state *, int, int *,char *); static Error readdesc(char **,struct parse_state *,int *,ByteOrder *,Type *, char *); static Error parse_datafile(struct place_state *); static Error get_format(struct parse_state *,char **,int *,ByteOrder *); static Error get_type(struct parse_state *,char **,Type *,int *); /* * Bits for flags field of struct parameter */ #define PARAM_SET 0x1 #define PARAM_SPECIFIED(pnum) (para[pnum].flags & PARAM_SET) #define SET_PARAM_SPECIFIED(pnum) (para[pnum].flags |= PARAM_SET) #define CLR_PARAM_SPECIFIED(pnum) (para[pnum].flags &= ~PARAM_SET) struct parameter{ char name[32]; int (* getInfo)(); int flags; }; #define PARAM_File 0 #define PARAM_Grid 1 #define PARAM_Series 2 #define PARAM_Fields 3 #define PARAM_Structure 4 #define PARAM_Format 5 #define PARAM_Type 6 #define PARAM_Layout 7 #define PARAM_Majority 8 #define PARAM_Header 9 #define PARAM_Interleaving 10 #define PARAM_Block 11 #define PARAM_Positions 12 #define PARAM_Points 13 #define PARAM_Depend 14 #define PARAM_RecSeparat 15 #define PARAM_End 16 #define NUM_PARS 17 /* number of parameters in table */ static struct parameter para[] = { { "file", infoFile, 0}, { "grid", infoGrid, 0}, { "series", infoSeries, 0}, { "field", infoField, 0}, { "structure", infoStructure, 0}, { "format", infoFormat, 0}, { "type", infoType, 0}, { "layout", infoLayout, 0}, { "majority", infoMajority, 0}, { "header", infoHeader, 0}, { "interleaving", infoInterleaving, 0}, { "block", infoBlock, 0}, { "positions", infoPositions, 0}, { "points", infoPoints, 0}, { "dependency", infoDepend, 0}, { "recordseparator", infoRecSeparat, 0}, { "end", infoEnd, 0} }; static struct type_spec { Type type; char *type_name; } type_table [] = { { TYPE_UBYTE, "byte" }, { TYPE_UBYTE, "ubyte" }, { TYPE_BYTE, "sbyte" }, { TYPE_SHORT, "short"}, { TYPE_USHORT, "ushort"}, { TYPE_INT, "int" }, { TYPE_UINT, "uint" }, { TYPE_STRING, "string"}, { TYPE_FLOAT, "float"}, { TYPE_DOUBLE, "double"}, { TYPE_DOUBLE, NULL} /* terminating entry (name=NULL),must be last */ }; static struct header **rec_sep; static int max_vars = MAX_VARS; /* number of variables allocated */ /* FN: read in the information table and set up the information. EF: return with information in arg1 so that processing may proceed. */ Error _dxf_gi_InputInfoTable(char *table, char *format, FILE **datafp) { FILE *fp; char *p, *headerfile; int i; struct parse_state ps; struct place_state dataps; for(i=0; iline */ DXFree(ps.line); done: /* if header info contained in data file (and not already read) * read it here */ if (_dxd_gi_fromfile && !parse_datafile(&dataps)) goto error; *datafp = dataps.fp; if (!CheckInputs()) goto error; if (!MakeupDefault(headerfile,ps.lineno)) goto error; DXFree(headerfile); return OK; parse_error: DXAddMessage(" (file %s: line %d)",headerfile,ps.lineno); error: if (fp) _dxfclose_dxfile(fp,headerfile); if (headerfile) DXFree(headerfile); return ERROR; } /* * Examine the user's input options for illegal or conflicting combinations. */ static Error CheckInputs(void) { int i,f,n; dep_type firstdep; if (!PARAM_SPECIFIED(PARAM_Grid) && !PARAM_SPECIFIED(PARAM_Points)){ DXSetError(ERROR_BAD_PARAMETER,"#10845","grid","points"); goto error; } /* I don't think we'll ever see this one */ if (PARAM_SPECIFIED(PARAM_Points) && _dxd_gi_numdims > 1){ DXSetError(ERROR_BAD_PARAMETER,"#10846","points","1-D positions"); goto error; } if (PARAM_SPECIFIED(PARAM_Layout)) { if( _dxd_gi_interleaving == IT_FIELD && _dxd_gi_format == ASCII ) _dxd_gi_asciiformat = FIX; else{ DXSetError(ERROR_BAD_PARAMETER,"#10846","layout", "field-interleaved ascii data"); goto error; } } if (PARAM_SPECIFIED(PARAM_Block)) { if (_dxd_gi_format == ASCII && _dxd_gi_interleaving != IT_FIELD) _dxd_gi_asciiformat = FIX; else{ DXSetError(ERROR_BAD_PARAMETER,"#10846","block", "non-field-interleaved ascii data"); goto error; } } /* if no dimensions then grid or points was empty */ if (_dxd_gi_numdims == 0){ DXSetError(ERROR_INVALID_DATA,"#10850","grid","points"); goto error; } /* check for grid size <=0 */ for (i=0; i<_dxd_gi_numdims; i++) { if (_dxd_gi_dimsize[i] <= 0) { DXSetError(ERROR_INVALID_DATA,"#10020","'grid' dimensions or 'points'"); goto error; } } /* dependency DEP_CONNECTIONS not allowed with interleaving field * locations can't be dep connections * points can't be specified */ if (PARAM_SPECIFIED(PARAM_Depend)){ firstdep = _dxd_gi_var[0]->datadep; for (f=0; f<_dxd_gi_numflds; f++){ if (_dxd_gi_interleaving==IT_FIELD && firstdep!=_dxd_gi_var[f]->datadep){ DXSetError(ERROR_INVALID_DATA,"#10855","dependency"); goto error; } if (_dxd_gi_var[f]->datadep == DEP_CONNECTIONS){ if (_dxd_gi_positions == FIELD_PRODUCT && f==_dxd_gi_loc_index){ DXSetError(ERROR_INVALID_DATA,"#10856","locations"); goto error; } if( _dxd_gi_connections == CONN_POINTS){ DXSetError(ERROR_INVALID_DATA,"#10856","points"); goto error; } } } } /* check that number of record separators matches data */ if (PARAM_SPECIFIED(PARAM_RecSeparat)){ if (_dxd_gi_interleaving!=IT_RECORD && _dxd_gi_interleaving!=IT_RECORD_VECTOR && _dxd_gi_interleaving!=IT_VECTOR){ DXSetError(ERROR_BAD_PARAMETER,"#10846","recordseparator", "record, vector and record-vector interleaved data"); goto error; } if (_dxd_gi_interleaving==IT_RECORD && PARAM_SPECIFIED(PARAM_Structure)){ for (f=0, n=0; f < _dxd_gi_numflds; f++) if (_dxd_gi_var[f]->datatype != TYPE_STRING) n+=_dxd_gi_var[f]->datadim; else n++; } else n = _dxd_gi_numflds; if (rec_sep[1]->type == SKIP_NOTHING){ rec_sep[1]->size = rec_sep[0]->size; rec_sep[1]->type = rec_sep[0]->type; strcpy(rec_sep[1]->marker, rec_sep[0]->marker); for (f=2; fsize = rec_sep[0]->size; rec_sep[f]->type = rec_sep[0]->type; strcpy(rec_sep[f]->marker,rec_sep[0]->marker); } rec_sep[n-1]->type = SKIP_NOTHING; } else if (rec_sep[n-2]->type == SKIP_NOTHING || rec_sep[n-1]->type != SKIP_NOTHING){ DXSetError(ERROR_INVALID_DATA,"#10840","recordseparator"); goto error; } /* if format=binary separator can't be lines */ if (_dxd_gi_format==BINARY){ for (f=0; ftype == SKIP_LINES){ DXSetError(ERROR_INVALID_DATA, "separators cannot be lines for binary data"); goto error; } } } /* if ascii format is free and separator is lines add one line */ if (_dxd_gi_asciiformat==FREE){ for (f=0; ftype==SKIP_LINES) rec_sep[f]->size = rec_sep[f]->size +1; } } } /* if format=binary separator can't be lines */ if (PARAM_SPECIFIED(PARAM_Series)){ if (_dxd_gi_format==BINARY){ if (_dxd_gi_serseparat.type == SKIP_LINES){ DXSetError(ERROR_INVALID_DATA, "separators cannot be lines for binary"); goto error; } } if (_dxd_gi_asciiformat==FREE && _dxd_gi_serseparat.type==SKIP_LINES) _dxd_gi_serseparat.size = _dxd_gi_serseparat.size +1; } return OK; error: return ERROR; } /* FN: Set defaults if they are not given EF: return with all the information required to read the data file and generate a DX file. */ static Error MakeupDefault(char *name,int linenum) { int i,j, size,n=0; char s[10]; int dim; /* check required parameters */ /*size = _dxfnumGridPoints();*/ /* if no file given use same as info file * if no header then start at end of infofile * last line from parsing */ if (!PARAM_SPECIFIED(PARAM_File)){ _dxd_gi_filename = (char *)DXAllocate(strlen(name) +1); strcpy(_dxd_gi_filename, name); if (!PARAM_SPECIFIED(PARAM_Header)){ _dxd_gi_header.size= linenum; _dxd_gi_header.type = SKIP_LINES; } } /* makeup variables */ if( _dxd_gi_numflds == 0 ) _dxd_gi_numflds = 1; if (!PARAM_SPECIFIED(PARAM_Fields)) { for(i = 0; i < _dxd_gi_numflds; i++) { sprintf(s, "field%d", i); strcpy(_dxd_gi_var[i]->name, s); } } if (!PARAM_SPECIFIED(PARAM_Structure)) for(i = 0; i < _dxd_gi_numflds; i++) _dxd_gi_var[i]->datadim = 1; if (!PARAM_SPECIFIED(PARAM_Type)) { j = DXTypeSize(TYPE_FLOAT); for (i = 0; i < _dxd_gi_numflds; i++) { _dxd_gi_var[i]->datatype = TYPE_FLOAT; _dxd_gi_var[i]->databytes = j; } } if (!PARAM_SPECIFIED(PARAM_Depend)) { for (i=0; i<_dxd_gi_numflds; i++) _dxd_gi_var[i]->datadep = DEP_POSITIONS; } /* place record header in correct places * and set default if no record header * and free rec_sep */ if (_dxd_gi_interleaving == IT_RECORD){ if (PARAM_SPECIFIED(PARAM_RecSeparat)) { for(i=0; i<_dxd_gi_numflds; i++){ if (_dxd_gi_var[i]->datatype == TYPE_STRING) dim = 1; else dim = _dxd_gi_var[i]->datadim; for (j=0; jrec_separat[j].size = rec_sep[n]->size; _dxd_gi_var[i]->rec_separat[j].type = rec_sep[n]->type; strcpy(_dxd_gi_var[i]->rec_separat[j].marker,rec_sep[n]->marker); n++; } } } else{ for (i=0; i<_dxd_gi_numflds; i++){ if (_dxd_gi_var[i]->datatype == TYPE_STRING) dim = 1; else dim = _dxd_gi_var[i]->datadim; for (j=0; jrec_separat[j].type=SKIP_NOTHING; } } } else{ if (PARAM_SPECIFIED(PARAM_RecSeparat)) { for(i=0; i<_dxd_gi_numflds; i++){ _dxd_gi_var[i]->rec_separat[0].size = rec_sep[i]->size; _dxd_gi_var[i]->rec_separat[0].type = rec_sep[i]->type; strcpy(_dxd_gi_var[i]->rec_separat[0].marker,rec_sep[i]->marker); n++; } } else{ for (i=0; i<_dxd_gi_numflds; i++) _dxd_gi_var[i]->rec_separat[0].type=SKIP_NOTHING; } } /* Clean up Record Sep */ if (PARAM_SPECIFIED(PARAM_RecSeparat)){ for (i=0; icurrent; char *p; int myGI_numflds = 0; char name[MAX_MARKER]; /* search for = and skip it, then filename can contain = */ /* Skip any leading white space and '=' */ while (*current && (*current == ' ' || *current == '\t' || *current == '=')) current++; if (!*current) goto error; ps->current = current; while(FileTok(ps, ", \n\t",NO_NEWLINE,&p) && p) { if (myGI_numflds >= max_vars){ if (!getmorevar(&max_vars)) goto error; } if ( _dxd_gi_var[myGI_numflds] == NULL ) { if ((_dxd_gi_var[myGI_numflds] = (struct variable *)DXAllocate(sizeof(struct variable))) == NULL ) goto error; } if (!parse_marker(p,name)) goto error; strcpy(_dxd_gi_var[myGI_numflds]->name, name); if (!strcmp(p,"locations")) { _dxd_gi_loc_index = myGI_numflds; _dxd_gi_positions = FIELD_PRODUCT; } ++myGI_numflds; } if ( _dxd_gi_numflds == 0 ) _dxd_gi_numflds = myGI_numflds; /* update number of fields */ else if ( _dxd_gi_numflds != myGI_numflds ) { DXSetError(ERROR_BAD_PARAMETER,"#10840","field"); goto error; } return OK; error: return ERROR; } /* FN: read the structure of data of each field. If variables have been constructed via DXAllocate then check for compatibility between structure and field. Otherwise, the number of structures is the number of fields. Do variable construction EF: return with _dxd_gi_var[0.._dxd_gi_numflds]->datadim being set. Note: the strucutre here is scalar, 2-vector, .... up to 5-vector. This can be extended by adding the statement strcmp(p, "?-vector") and set the _dxd_gi_var[i]->datadim. */ static Error infoStructure(struct parse_state *ps) { char *p; int n=0; while( FileTok(ps,"=, \n\t",NO_NEWLINE,&p) && p) { if (n >= max_vars){ if (!getmorevar(&max_vars)) goto error; } if ( _dxd_gi_var[n]==NULL ) { if ((_dxd_gi_var[n] = (struct variable *)DXAllocate(sizeof(struct variable))) == NULL ) goto error; } if (!strcmp(p, "scalar") ) _dxd_gi_var[n]->datadim = 1; else if ( !strcmp(p+1, "-vector") ) { int k = atoi(p); if ((k <= 0) || (k > MAX_POS_DIMS)) { DXSetError(ERROR_NOT_IMPLEMENTED,"#10860","structure",p); goto error; } _dxd_gi_var[n]->datadim = k; } else if (!strncmp(p,"string",6)){ int k = atoi(p+7); if (k <= 0) { DXSetError(ERROR_BAD_PARAMETER,"#10122","stringlength",1); goto error; } _dxd_gi_var[n]->datadim = k+1; } else { DXSetError(ERROR_BAD_PARAMETER,"#10862","structure",p); goto error; } ++n; } if (_dxd_gi_numflds == 0 ) _dxd_gi_numflds = n; else if (_dxd_gi_numflds != n ) { DXSetError(ERROR_BAD_PARAMETER,"#10840","structure"); goto error; } return OK; error: return ERROR; } /* FN: read in the data format. ( either ascii or binary ). EF: Update the data format. */ static Error infoFormat(struct parse_state *ps) { char *p; if (!FileTok(ps,"=, \n\t",NO_NEWLINE,&p)) { DXAddMessage("#10865","format"); goto error; } if (!p){ DXSetError(ERROR_INVALID_DATA,"#10865","format"); goto error; } if (!get_format(ps,&p,&_dxd_gi_format,&_dxd_gi_byteorder)) goto error; if (_dxd_gi_format < 0){ DXSetError(ERROR_BAD_PARAMETER,"#10862","format",p); goto error; } return OK; error: return ERROR; } /* routine to parse format statement */ static Error get_format(struct parse_state *ps,char **p,int *format,ByteOrder *order) { char *t; t = *p; L_CASE(t); *p = t; /* Parse the byte order if present (ok for it to not be present) */ if (!strcmp("lsb", *p) ) { *format = BINARY; *order = BO_LSB; } else if (!strcmp("msb", *p) ) { *format = BINARY; *order = BO_MSB; } else *order = BO_UNKNOWN; if (*order != BO_UNKNOWN) { /* msb/lsb specified, get next token */ if (!FileTok(ps," ,\n\t",NO_NEWLINE,p)) { DXAddMessage("#10865","format"); goto error; } if (!*p){ DXSetError(ERROR_INVALID_DATA,"#10865","format"); goto error; } } if (!strcmp("binary", *p) || !strcmp("ieee",*p)) { *format = BINARY; if (*order == BO_UNKNOWN) *order = DEFAULT_BYTEORDER; } else if (!strcmp("ascii", *p) || !strcmp("text", *p)) { *format = ASCII; if (*order != BO_UNKNOWN) DXWarning("Byte order in 'format' statement ignored"); } else *format = -1; return OK; error: return ERROR; } /* FN: read in the datatype of each variable. If the variables haven't been constructed, then DXAllocate memory for variables and update the number of fields. Otherwise do the compatibility checking. EF: return the variables with datatype and databytes been set. */ static Error infoType(struct parse_state *ps) { char *p; int n = 0; int bytes; Type type; while (FileTok(ps," =,\n\t",NO_NEWLINE,&p) && p) { if (n >= max_vars){ if (!getmorevar(&max_vars)) goto error; } if (_dxd_gi_var[n]==NULL ) { if ((_dxd_gi_var[n] = (struct variable *)DXAllocate(sizeof(struct variable))) == NULL ) goto error; } if (!get_type(ps,&p,&type,&bytes)) goto error; _dxd_gi_var[n]->datatype = type; _dxd_gi_var[n]->databytes = bytes; if (bytes<0) { DXSetError(ERROR_BAD_PARAMETER,"#10862","type",p); goto error; } ++n; } if (_dxd_gi_numflds == 0 ) _dxd_gi_numflds = n; else if (_dxd_gi_numflds != n ) { DXSetError(ERROR_BAD_PARAMETER,"#10840","type"); goto error; } return OK; error: return ERROR; } /* routine for parsing type */ static Error get_type(struct parse_state *ps,char **p,Type *type,int *bytes) { char signedtype[7]; int i,found; if (!strcmp(*p,"unsigned")){ if (!FileTok(ps," ,\n\t",NO_NEWLINE,p)&& *p){ DXAddMessage("#10862","type"); goto error; } if (!strcmp(*p,"byte")) strcpy(signedtype,"ubyte"); else if (!strcmp(*p,"int")) strcpy(signedtype,"uint"); else if (!strcmp(*p,"short")) strcpy(signedtype,"ushort"); else{ DXSetError(ERROR_INVALID_DATA,"#10862","type","unsigned ?"); goto error; } *p = signedtype; } else if (!strcmp(*p,"signed")){ if (!FileTok(ps," ,\n\t",NO_NEWLINE,p) && *p){ DXAddMessage("#10862","type"); goto error; } if (!strcmp(*p,"byte")){ strcpy(signedtype,"sbyte"); *p = signedtype; } else if (!strcmp(*p,"int")) ; else if (!strcmp(*p,"short")) ; else{ DXSetError(ERROR_INVALID_DATA,"#10862","type","signed ?"); goto error; } } for (found=i=0; type_table[i].type_name !=NULL; i++){ if (!strcmp(*p,type_table[i].type_name)) { *type = type_table[i].type; *bytes = DXTypeSize(type_table[i].type); found = 1; break; } } if (!found) *bytes = -1; return OK; error: return ERROR; } /* */ static Error infoRecSeparat(struct parse_state *ps) { char *p; int n = 0; if ((rec_sep = (struct header **)DXAllocate(sizeof(struct header*) *max_vars*MAX_POS_DIMS)) == NULL) goto error; for(n=0; ;n++){ if (!FileTok(ps,"=, \n\t",NO_NEWLINE,&p)) { DXAddMessage("#10862","recordseparator"); return ERROR; } if (n > max_vars*MAX_POS_DIMS){ DXSetError(ERROR_INVALID_DATA,"too many record separators"); goto error; } if ((rec_sep[n] = (struct header *)DXAllocate(sizeof(struct header))) == NULL ) goto error; if (!p){ break; } if (!get_header(ps,p, rec_sep[n])){ DXAddMessage("reading recordseparator %d",n); return ERROR; } } rec_sep[n]->type = SKIP_NOTHING; if (n == 0) { DXSetError(ERROR_INVALID_DATA,"no recordseparators specified"); goto error; } return OK; error: return ERROR; } /* FN: read in the width (# of bytes) of data of each variable in data file. EF: return variable with valid widths. */ static Error infoLayout(struct parse_state *ps) { char *p; int n=0; /* Layout is only use for field interleaved data */ if (!PARAM_SPECIFIED(PARAM_Fields)) _dxd_gi_interleaving = IT_FIELD; while (FileTok(ps," =,\n\t",NO_NEWLINE,&p) && p) { if (n >= max_vars){ if (!getmorevar(&max_vars)) goto error; } if (_dxd_gi_var[n]==NULL ) { if ((_dxd_gi_var[n] = (struct variable *)DXAllocate(sizeof(struct variable))) == NULL ) goto error; } /* * Get the 'skip' value */ if (!isdigit( *p ) ) { DXSetError(ERROR_BAD_PARAMETER,"#10870","skip",n+1,"layout"); goto error; } else _dxd_gi_var[n]->leading = atoi(p); /* * Get the 'width' value */ if (!FileTok(ps,", \t\n",NO_NEWLINE,&p)) { DXAddMessage("\n"); DXAddMessage("#10870","width",n+1,"layout"); goto error; } else if (!p) { DXSetError(ERROR_MISSING_DATA,"#10871","width",n+1,"layout"); goto error; } if ( !isdigit( *p ) ) { DXSetError(ERROR_BAD_PARAMETER,"#10870","width",n+1,"layout"); goto error; } else _dxd_gi_var[n]->width = atoi( p ); ++n; } if (_dxd_gi_numflds == 0 ) _dxd_gi_numflds = n; else if (_dxd_gi_numflds != n ) { DXSetError(ERROR_BAD_PARAMETER,"#10840","layout"); goto error; } return OK; error: return ERROR; } /* FN: read in the majority for the array ordering. (row/column) EF: return with majority being set. */ static Error infoMajority(struct parse_state *ps) { char *p; if (!FileTok(ps,"= \n\t",NO_NEWLINE,&p)) { DXAddMessage("#10865","majority"); goto error; } if (!p){ DXSetError(ERROR_INVALID_DATA,"#10865","majority"); goto error; } if ( !strcmp(p, "column") ) _dxd_gi_majority = COL; else if ( !strcmp(p, "row") ) _dxd_gi_majority = ROW; else { DXSetError(ERROR_BAD_PARAMETER,"#10862","majority",p); goto error; } return OK; error: return ERROR; } /* FN: read in the dependency for each variable (positions/connections) EF: return with dependency being set. */ static Error infoDepend(struct parse_state *ps) { char *p; int n=0; while (FileTok(ps," =,\n\t",NO_NEWLINE,&p) && p) { if (n >= max_vars){ if (!getmorevar(&max_vars)) goto error; } if (_dxd_gi_var[n]==NULL ) { if ((_dxd_gi_var[n] = (struct variable *)DXAllocate(sizeof(struct variable))) == NULL ) goto error; } if (!strcmp(p,"connections")) _dxd_gi_var[n]->datadep = DEP_CONNECTIONS; else if (!strcmp(p,"positions")) _dxd_gi_var[n]->datadep = DEP_POSITIONS; else{ DXSetError(ERROR_BAD_PARAMETER,"#10862","dependency",p); goto error; } ++n; } if (_dxd_gi_numflds == 0 ) _dxd_gi_numflds = n; else if (_dxd_gi_numflds != n ) { DXSetError(ERROR_BAD_PARAMETER,"#10840","dependency"); goto error; } return OK; error: return ERROR; } /* FN: read in the size of header information. EF: return with header BEING SET. */ static Error infoHeader(struct parse_state *ps) { char *p; if (!FileTok(ps,"= \n\t",NO_NEWLINE,&p)) { DXAddMessage("#10865","header"); return ERROR; } if (!p){ DXSetError(ERROR_INVALID_DATA,"#10865","header"); return ERROR; } if (!get_header(ps,p,&_dxd_gi_header)){ DXAddMessage("reading header statment"); return ERROR; } return OK; } /* FN: parse header (header, series header, record header) EF: return header set */ static Error get_header(struct parse_state *ps, char *p, struct header *head) { if (!strcmp(p,"lines")) { head->type = SKIP_LINES; if (!FileTok(ps,", \n\t",NO_NEWLINE,&p)) { DXAddMessage("#10865","lines"); goto error; } if (!p){ DXSetError(ERROR_INVALID_DATA,"#10865","lines"); goto error; } if (!isdigit(*p)){ DXSetError(ERROR_INVALID_DATA,"#10873","lines"); goto error; } head->size = atoi(p); head->marker[0] = '\0'; } else if (!strcmp(p,"bytes")) { head->type = SKIP_BYTES; if (!FileTok(ps,", \n\t",NO_NEWLINE,&p)) { DXAddMessage("#10865","bytes"); goto error; } if (!p){ DXSetError(ERROR_INVALID_DATA,"#10865","bytes"); goto error; } if (!isdigit(*p)){ DXSetError(ERROR_INVALID_DATA,"#10873","bytes"); goto error; } head->size = atoi(p); head->marker[0] = '\0'; } else if (!strcmp(p,"marker")) { head->type = SKIP_MARKER; if (!FileTok(ps," ,\n",NO_NEWLINE,&p)) { DXAddMessage("#10865","marker"); goto error; } if (!p){ DXSetError(ERROR_INVALID_DATA,"#10865","marker"); goto error; } if (!parse_marker(p,head->marker)) goto error; head->size = 0; } else { DXSetError(ERROR_INVALID_DATA,"#10862","header",p); goto error; } return OK; error: return ERROR; } /* FN: read in the interleaving specification. EF: return with interleaving being set. */ static Error infoInterleaving(struct parse_state *ps) { char *p; if (!FileTok(ps,"= \t\n",NO_NEWLINE,&p)) { DXAddMessage("#10865","interleaving"); goto error; } if (!p){ DXSetError(ERROR_INVALID_DATA,"10865","interleaving"); goto error; } if ( !strcmp(p, "field") ) _dxd_gi_interleaving = IT_FIELD; else if ( !strcmp(p, "record") ) _dxd_gi_interleaving = IT_RECORD; else if ( !strcmp(p, "vector") ) _dxd_gi_interleaving = IT_VECTOR; else if ( !strcmp(p, "record-vector") ) _dxd_gi_interleaving = IT_RECORD_VECTOR; else if ( !strcmp(p, "series-vector") ) _dxd_gi_interleaving = IT_VECTOR; else { DXSetError(ERROR_INVALID_DATA,"#10862","interleaving",p); goto error; } return OK; error: return ERROR; } /* FN: read in the leading blanks per line and number of elements per line of each field. EF: return variables with valid leading blanks and elements. */ static Error infoBlock(struct parse_state *ps) { char *p; int n=0; while (FileTok(ps,"=, \t\n",NO_NEWLINE,&p) && p) { if (n >= max_vars){ if (!getmorevar(&max_vars)) goto error; } if ( _dxd_gi_var[n]==NULL ) { if ((_dxd_gi_var[n] = (struct variable *)DXAllocate(sizeof(struct variable))) == NULL ) goto error; } /* * Get the 'skip' value */ if ( !isdigit( *p ) ) { DXSetError(ERROR_BAD_PARAMETER,"#10870","skip",n+1,"block"); goto error; } else _dxd_gi_var[n]->leading = atoi(p); /* * Get the 'elements' value */ if (!FileTok(ps,", \t\n",NO_NEWLINE,&p)) { DXAddMessage("\n"); DXAddMessage("#10871","elements",n+1); goto error; } else if (!p) { DXSetError(ERROR_MISSING_DATA,"#10871","elements",n+1,"block"); goto error; } else if ( !isdigit( *p ) ) { DXSetError(ERROR_BAD_PARAMETER,"#10870","elements",n+1,"block"); goto error; } else _dxd_gi_var[n]->elements = atoi( p ); /* * Get the 'width' value */ if (!FileTok(ps,", \t\n",NO_NEWLINE,&p)) { DXAddMessage("\n"); DXAddMessage("#10871","width",n+1,"block"); goto error; } else if (!p) { DXSetError(ERROR_MISSING_DATA,"#10871","width",n+1,"block"); goto error; } if ( !isdigit( *p ) ) { DXSetError(ERROR_BAD_PARAMETER,"#10870","width",n+1,"block"); goto error; } else _dxd_gi_var[n]->width = atoi( p ); ++n; } if ( _dxd_gi_numflds == 0 ) _dxd_gi_numflds = n; else if ( _dxd_gi_numflds != n ) { DXSetError(ERROR_BAD_PARAMETER,"#10840","block"); goto error; } return OK; error: return ERROR; } /* FN: read in the locations data from infomation table to _dxd_gi_dataloc[]. construct locations variable _dxd_gi_var[locidx] when positions non-PRODUCT. otherwise construct variables _dxd_gi_var[locidx..locidx+_dxd_gi_numdims-1] for every axis. EF: return with valid locations variable(s) and update locidx. */ static Error infoPositions(struct parse_state *ps,struct place_state *dataps) { char *p; int n = 0, size, i=0, posnums, tempi1, tempi2; int istart=0,max_values=0; Type type = TYPE_FLOAT; int format = ASCII; ByteOrder order = DEFAULT_BYTEORDER; if (_dxd_gi_positions != DEFAULT_PRODUCT) { DXWarning("#4460"); return OK; } if (!PARAM_SPECIFIED(PARAM_Points) && !PARAM_SPECIFIED(PARAM_Grid)){ DXSetError(ERROR_INVALID_DATA,"#10875","points","grid","positions"); goto error; } /* _dxd_gi_dataloc is freed in genimpcleanup() */ /* Get first token, expect it to be a number or 'regular' or 'irregular' * or a marker indicating the positions are to be read from the data file */ if (!FileTok(ps,"=, \t\n",NO_NEWLINE,&p)) { DXAddMessage("#10865","positions"); goto error; } if (!p) { DXSetError(ERROR_MISSING_DATA,"#10865","positions"); goto error; } /* if positions from file, fill _dxd_gi_fromfile */ if (!isdigit(*p) && *p != '.' && *p != '-' && strncmp(p,"reg",3) && strncmp(p,"irr",3)){ if (_dxd_gi_fromfile){ for (i=0; _dxd_gi_fromfile[i]; i++) ; } else if ((_dxd_gi_fromfile =(struct infoplace **) DXAllocate(sizeof(struct infoplace *) * MAX_POS_DIMS*3))== NULL) goto error; /* is the format and/or the type specified */ if (!readdesc(&p,ps,&format,&order,&type,"positions")) goto error; istart = i; for (i=0; itype = type; _dxd_gi_fromfile[istart+i]->format = format; _dxd_gi_fromfile[istart+i]->byteorder = order; _dxd_gi_fromfile[istart+i]->index = 10+i; if (!readplacement(&p,ps,(istart+i),&max_values,"positions")) goto error; if (!p) break; } _dxd_gi_fromfile[++i+istart]=NULL; _dxd_gi_positions = REGULAR_PRODUCT; posnums = MAX_POS_DIMS*2; if ((_dxd_gi_dataloc = (float *)DXAllocate(posnums*sizeof(float)))==NULL) goto error; return OK; } /* if positions not from file but grid or points are, parse_datafile now */ if (_dxd_gi_fromfile && !parse_datafile(dataps)) goto error; size = _dxfnumGridPoints(-1); if (isalpha(*p)) { posnums = 0; for (i=0; i<_dxd_gi_numdims; i++) { if ( !strncmp(p,"regular",7) ) { _dxd_gi_pos_type[i] = REGULAR; posnums += 2; } else if ( !strncmp(p,"irregular",9) ) { _dxd_gi_pos_type[i] = IRREGULAR; posnums += _dxd_gi_dimsize[i]; } else { DXSetError(ERROR_BAD_PARAMETER,"#10862","positions",p); goto error; } if (!FileTok(ps,", \t\n",NO_NEWLINE,&p)) { if (i == _dxd_gi_numdims-1) /* Should be reading the numbers */ DXAddMessage("#10877","positions"); else /* Should be read a position type */ DXAddMessage("#10878","positions"); goto error; } if (!p) { if (i == _dxd_gi_numdims-1) /* Should be reading the numbers */ DXSetError(ERROR_MISSING_DATA,"#10877","positions"); else DXSetError(ERROR_MISSING_DATA,"#10878","positions"); goto error; } } n = 0; if ((_dxd_gi_dataloc = (float *)DXAllocate(posnums*_dxd_gi_numdims*sizeof(float)))==NULL) goto error; do { /* DXRead the numbers */ if (!isdigit(*p) && *p != '.' && *p != '-') { if (!strcmp(p,"end")) { /* This is a recognized and handled keyword */ SET_PARAM_SPECIFIED(PARAM_End); break; } else if (*p == '#') /* A comment */ { break; } else { DXSetError(ERROR_INVALID_DATA,"#10879",n+1,"positions",p); goto error; } } if (n>=posnums){ DXSetError(ERROR_BAD_PARAMETER,"#10880","positions"); goto error; } _dxd_gi_dataloc[n++] = atof(p); } while (FileTok(ps,", \t\n",NEWLINE_OK,&p) && p); DXResetError(); /* EOF is ok here */ if (posnums != n){ DXSetError(ERROR_BAD_PARAMETER,"#10880","positions"); goto error; } if (_dxd_gi_numdims == 1) { if (_dxd_gi_pos_type[0] == IRREGULAR) _dxd_gi_positions = IRREGULAR_PRODUCT; else _dxd_gi_positions = REGULAR_PRODUCT; } else _dxd_gi_positions = MIXED_PRODUCT; } else { /* Parse a string of numbers that can span more than 1 line */ n = 0; tempi1 = (2*_dxd_gi_numdims); if (size==1) tempi2 = 2*_dxd_gi_numdims; else tempi2 = size*_dxd_gi_numdims; if ((_dxd_gi_dataloc = (float *)DXAllocate(2*_dxd_gi_numdims*sizeof(float)))==NULL) goto error; do { /* DXRead the numbers */ if (!isdigit(*p) && *p != '.' && *p != '-') { if (!strcmp(p,"end")) { /* This is a recognized and handled keyword */ SET_PARAM_SPECIFIED(PARAM_End); break; } else if (*p == '#') /* A comment */ { break; } else { DXSetError(ERROR_INVALID_DATA,"#10879",n+1,"positions",p); goto error; } } if (n == tempi1) { if((_dxd_gi_dataloc = (float *)DXReAllocate((Pointer)_dxd_gi_dataloc, size*_dxd_gi_numdims*sizeof(float))) ==NULL) goto error; } if (n >= tempi2){ DXSetError(ERROR_BAD_PARAMETER,"#10880","positions"); goto error; } _dxd_gi_dataloc[n++] = atof(p); } while (FileTok(ps,", \t\n",NEWLINE_OK,&p) && p); DXResetError(); /* EOF is ok here */ if (size*_dxd_gi_numdims == n ) _dxd_gi_positions = IRREGULAR_PRODUCT; else if ( 2*_dxd_gi_numdims == n) _dxd_gi_positions = REGULAR_PRODUCT; else{ DXSetError(ERROR_BAD_PARAMETER,"#10880","positions"); goto error; } } return OK; error: return ERROR; } /* FN: read in data file name and construct output DX file name. EF: return with valid data filename and output DX file name. */ static Error infoFile(struct parse_state *ps) { char *current = ps->current; char *p; /* search for = and skip it, then filename can contain = */ /* Skip any leading white space and '=' */ while (*current && (*current == ' ' || *current == '\t' || *current == '=')) current++; if (!*current) goto error; ps->current = current; if (!FileTok(ps," ,\t\n",NO_NEWLINE,&p)) { DXAddMessage("#10865","file"); goto error; } if (!p){ DXSetError(ERROR_MISSING_DATA,"#10865","file"); goto error; } _dxd_gi_filename = (char *)DXAllocate(strlen(p) +1); strcpy(_dxd_gi_filename, p); return OK; error: return ERROR; } /* FN: read in dimensionality and shape. EF: return with valid _dxd_gi_numdims and _dxd_gi_dimsize[]. and set _dxd_gi_connections. */ static Error infoPoints(struct parse_state *ps) { char *p; int i=0; int max_values = 0; Type type=TYPE_INT; int format=ASCII; ByteOrder order = DEFAULT_BYTEORDER; if (_dxd_gi_connections != CONN_UNKNOWN){ DXSetError(ERROR_INVALID_DATA,"#10882","points","grid"); goto error; } if (!FileTok(ps,"= ,\t\n",NO_NEWLINE,&p)) { DXAddMessage("#10865","points"); goto error; } if (!p){ DXSetError(ERROR_MISSING_DATA,"#10865","points"); goto error; } if (isdigit(*p)) { _dxd_gi_dimsize[0] = atoi( p ); if (_dxd_gi_dimsize[0] == 0) { DXSetError(ERROR_INVALID_DATA,"#10020", "number of points specified in 'points' statement"); goto error; } } else { /* points read from file */ if (!_dxd_gi_filename){ DXSetError(ERROR_INVALID_DATA,"'file' must come before 'points'"); goto error; } if (!_dxd_gi_fromfile && (_dxd_gi_fromfile = (struct infoplace **) DXAllocate(sizeof(struct infoplace *) * MAX_POS_DIMS*3))==NULL) goto error; if ((_dxd_gi_fromfile[0] = (struct infoplace *)DXAllocate( sizeof(struct infoplace)))== NULL) goto error; /* is the format and/or the type specified */ if (!readdesc(&p,ps,&format,&order,&type,"points")) goto error; _dxd_gi_fromfile[1]=NULL; _dxd_gi_fromfile[0]->type = type; _dxd_gi_fromfile[0]->format = format; _dxd_gi_fromfile[0]->byteorder = order; _dxd_gi_fromfile[0]->index = 0; if (!readplacement(&p,ps,0,&max_values,"points")) goto error; } _dxd_gi_numdims = 1; _dxd_gi_connections = CONN_POINTS; return OK; error: return ERROR; } /* FN: read in dimensionality and shape. EF: return with valid _dxd_gi_numdims and _dxd_gi_dimsize[]. and set _dxd_gi_connections. */ static Error infoGrid(struct parse_state *ps) { char *p; int i=0,n=0,max_values=0,readfile=0; Type type=TYPE_INT; int format=ASCII; ByteOrder order = DEFAULT_BYTEORDER; _dxd_gi_numdims=0; if (_dxd_gi_connections != CONN_UNKNOWN){ DXSetError(ERROR_INVALID_DATA,"#10882","grid","points"); goto error; } /* check first character, if alpha data is read from file */ if (!FileTok(ps,"=xX, \t\n",NO_NEWLINE,&p)) { DXAddMessage("\nGrid statement is incorrect"); goto error; } if (!p){ DXSetError(ERROR_INVALID_DATA,"grid statement is empty"); goto error; } if (isdigit(*p)){ for (i=0 ; itype = type; _dxd_gi_fromfile[i]->format = format; _dxd_gi_fromfile[i]->byteorder = order; _dxd_gi_fromfile[i]->index = i; if (!readplacement(&p,ps,i,&max_values,"grid")) goto error; if (!p) break; if (!FileTok(ps,"xX, \t\n",NO_NEWLINE,&p)) { DXAddMessage("\nGrid statement is incorrect"); goto error; } if (!p) break; } _dxd_gi_fromfile[++i]=NULL; } _dxd_gi_connections = CONN_GRID; return OK; error: return ERROR; } /* FN: read in the number of time series (records). */ static Error infoSeries(struct parse_state *ps) { char *p; int i = 0; float start = 0.0, delta = 0.0; while (FileTok(ps,"=, \t\n",NO_NEWLINE,&p) && p) { if (isalpha(*p)){ if (i<0){ DXSetError(ERROR_INVALID_DATA,"#10885","series separator"); goto error; } if (!strncmp(p,"separator",9)){ if (!FileTok(ps,"= \n\t",NO_NEWLINE,&p)) { DXAddMessage("#10865","series"); goto error; } if (!p){ DXSetError(ERROR_INVALID_DATA,"#10865","series separator"); goto error; } if (!get_header(ps,p,&_dxd_gi_serseparat)){ DXAddMessage("reading series separator"); goto error; } } else{ DXSetError(ERROR_INVALID_DATA,"#10862","series"); goto error; } if (FileTok(ps," \n\t",NO_NEWLINE,&p) && p){ DXSetError(ERROR_INVALID_DATA,"#10885","series separator"); goto error; } break; } else{ i++; if (i == 1) _dxd_gi_series = atoi( p ); else if (i == 2) start = atof( p ); else if (i == 3) delta = atof( p ); } } if (i == 0) { DXSetError(ERROR_MISSING_DATA,"#10865","series"); goto error; } else if (i == 1) { start = 1.0; delta = 1.0; } else if (i == 2) { delta = 1.0; } if (!(_dxd_gi_seriesvalues = (float *)DXAllocate(_dxd_gi_series*sizeof(float)))) goto error; _dxd_gi_seriesvalues[0] = start; for (i=1; i<_dxd_gi_series; i++) _dxd_gi_seriesvalues[i] = _dxd_gi_seriesvalues[i-1] + delta; return OK; error: return ERROR; } /* FN: do nothing but catch the 'end' keyword. */ static Error infoEnd(struct parse_state *ps) { return OK; } static Error parse_marker(char *p, char marker[MAX_MARKER]) { int i; unsigned int c; /* Skip any leading white space */ while (*p && (*p == ' ' || *p == '\t')){ p++; } if (!*p) goto error; marker[0] = '\0'; if (*p == '"') { /* DXCopy everything inside of the two "'s */ p++; for (i=0 ; (i=MAX_MARKER){ DXSetError(ERROR_INVALID_DATA,"#10887","marker"); goto error; } marker[i] = '\0'; return OK; error: return ERROR; } static Error nextchar(char **p, unsigned int *c) { unsigned int i, digit, num; if (**p == '\\') { (*p)++; switch (**p) { case 'n': *c = '\n'; break; /* '\n' */ case 't': *c = '\t'; break; /* '\t' */ case 'r': *c = '\r'; break; /* '\r' */ case 'f': *c = '\f'; break; /* '\r' */ case 'b': *c = '\b'; break; /* '\b' */ default: if (isdigit(**p)) { /* DXExtract an 1, 2 or 3 digit octal number */ num = i = 0; (*p)--; /* Prime the loop */ do { (*p)++; digit = **p - '0'; if (digit >= 8) { DXSetError(ERROR_INVALID_DATA,"#10890",**p); goto error; } num = num*8 + **p - '0'; } while ((++i < 3) && isdigit(*(*p+1))); if (num > 0xff) { DXSetError(ERROR_INVALID_DATA,"10891",num); goto error; } *c = num; } else { *c = (int)**p; } } } else *c = (int)**p; return OK; error: return ERROR; } /* parse the template if it exists the template is header and * file is data file. Set filename. */ static Error parse_template(char *format, char **filename) { char *file; char *p,*pstr,*pstart,*pend,*pcomma; int i,length; struct parse_state ps; char *statement; if (!format) return OK; /* Skip "general" */ format+=7; /* Skip any leading white space */ while (*format && (*format == ' ' || *format == '\t' || *format == ',')){ format++; } if (!*format) return OK; /* just space, no template */ /* set data filename */ SET_PARAM_SPECIFIED(PARAM_File); _dxd_gi_filename = (char *)DXAllocate(strlen(*filename) +1); strcpy(_dxd_gi_filename,*filename); ps.line=NULL; if (!strncmp(format,"template",8)){ if ((p = strchr(format,'=')) ==NULL){ DXSetError(ERROR_INVALID_DATA,"#10895","template"); goto error; } p++; while (*p && (*p == ' ' || *p == '\t' || *p == ',')){ p++; } if (p){ /* get header filename length */ i=0; file = p; while (*p && *p != ' ' && *p != '\t' && *p != ','){ p++; i++; } } else{ DXSetError(ERROR_BAD_PARAMETER,"#10865","template"); goto error; } if (i > strlen(*filename)){ DXFree(*filename); *filename = (char *)DXAllocate(i+1); } strncpy(*filename,file,i); (*filename)[i]='\0'; /* skip to next statement */ while (*p && (*p == ' ' || *p == '\t' || *p == ',')){ p++; } } else{ /* no template name is given * all header info is given in format string from Import */ *filename[0] = '\0'; p = format; /* skip to next statement */ while (*p && (*p == ' ' || *p == '\t' || *p == ',')){ p++; } } if (*p){ /* initialize ps without a filepointer to read the template string */ ps.filename = NULL; ps.fp = NULL; ps.current = NULL; ps.lineno = 0; ps.line = (char *)DXAllocate(MAX_DSTR); if (!ps.line) goto error; /* copy each statement into ps.line (which is allocated already) */ /* then current points to beginning of ps.line */ pstart = p; pend = pstart; while(pstart){ *ps.line = '\0'; pend = pstart; statement = ps.line; while(!*ps.line){ if ((pend = strchr(pend, ','))==NULL){ /* last statement */ length = strlen(pstart); if (length < MAX_DSTR-2){ /* strncpy(statement,pstart,length); statement[length]=' '; statement[length+1]='\0'; ps.line = statement; */ strncpy(ps.line,pstart,length); ps.line[length]=' '; ps.line[length+1]='\0'; } else{ DXSetError(ERROR_INTERNAL,"statement too long"); goto error; } } else{ /* is this a keyword */ pcomma = pend; /* mark comma so can replace with space */ pend++; while(*pend && (*pend == ' ' || *pend == '\t')) pend++; for (i=0; i= 0){ /* format was specified */ *format = form; *order = or; if (!FileTok(ps," ,\t\n",NO_NEWLINE,p)){ DXAddMessage("reading %s statement",statement); goto error; } } if (!get_type(ps,p,type,&bytes)) goto error; if(bytes >= 0 && !FileTok(ps," ,\t\n",NO_NEWLINE,p)){ DXAddMessage("reading %s statement",statement); goto error; } return OK; error: return ERROR; } /* fill one infoplace struct */ static Error readplacement(char **p,struct parse_state *ps,int which, int *max_values, char *statement) { int i,n=0,bytes; struct infoplace *fromfile; Type t; fromfile = _dxd_gi_fromfile[which]; t = fromfile->type; if ((fromfile->skip = (int *)DXAllocate(MAX_POS_DIMS *sizeof(int)))== NULL) goto error; if ((fromfile->width = (int *)DXAllocate(MAX_POS_DIMS *sizeof(int)))== NULL) goto error; bytes = DXTypeSize(t); if ((fromfile->data = (void *)DXAllocate(MAX_POS_DIMS *bytes))==NULL) goto error; /* if no data in the file use the default * for positions only */ if (**p == '?'){ fromfile->begin.type=SKIP_NOTHING; fromfile->skip[0]=0; n=1; if (!FileTok(ps,", \t\n",NO_NEWLINE,p)) /* advance the fp */ goto error; goto done; } if (!get_header(ps,*p,&fromfile->begin)){ DXAddMessage("reading %s statment",statement); goto error; } while (FileTok(ps," ,\t\n",NO_NEWLINE,p) && (*p) && isdigit(**p)){ fromfile->skip[n] = atoi(*p); /* get the 'skip' value */ if (!FileTok(ps,", \t\n",NO_NEWLINE,p)) { DXAddMessage("\n"); DXAddMessage("#10870","width",which,statement); goto error; } if (!*p) { DXSetError(ERROR_MISSING_DATA,"#10871","width",which,statement); goto error; } if ( !isdigit( **p ) ) { DXSetError(ERROR_BAD_PARAMETER,"#10870","width",which,statement); goto error; } fromfile->width[n] = atoi( *p ); n++; } done: fromfile->skip[n]=-1; if (n==0) /* no skip info (how many values?) */ *max_values+=MAX_POS_DIMS; else *max_values+=n; return OK; error: return ERROR; } /* read header info from data file and place in a correct place */ static Error parse_datafile(struct place_state *dataps) { int i,j=0,k=0,num,max_size=0; int read_header; Type t; float f; for (i=0; _dxd_gi_fromfile[i]; i++){ for (num=0; _dxd_gi_fromfile[i]->skip[num]>0; num++) ; if (num==0) num=MAX_POS_DIMS; max_size =+ DXTypeSize(_dxd_gi_fromfile[i]->type) * num; } dataps->lines = 0; dataps->bytes = 0; if (!_dxf_gi_extract(dataps,&read_header)){ DXAddMessage("reading header information from data file"); goto error; } /* if header statement exists adjust accordingly */ if (read_header==1){ /* header marker was already read */ DXWarning("header info not before data, cannot pipe"); if (_dxd_gi_filename[0]=='!'){ DXSetError(ERROR_INVALID_DATA, "can't use filter if header info is after begining of data"); goto error; } rewind(dataps->fp); } if (_dxd_gi_header.type!=SKIP_NOTHING){ switch (_dxd_gi_header.type){ case(SKIP_LINES): if (_dxd_gi_header.size < dataps->lines){ DXWarning("header info not before data, cannot pipe"); if (_dxd_gi_filename[0]=='!'){ DXSetError(ERROR_INVALID_DATA, "can't use filter if header info is after begining of data"); goto error; } rewind(dataps->fp); } else _dxd_gi_header.size = _dxd_gi_header.size-dataps->lines; break; case(SKIP_BYTES): if (_dxd_gi_header.size < dataps->bytes){ DXWarning("header info not before data, cannot pipe"); if (_dxd_gi_filename[0]=='!'){ DXSetError(ERROR_INVALID_DATA, "can't use filter if header info is after begining of data"); goto error; } rewind(dataps->fp); } else _dxd_gi_header.size = _dxd_gi_header.size-dataps->bytes; break; } } /* extract data from structure and place in correct place */ for (i=0; _dxd_gi_fromfile[i]; i++){ if (_dxd_gi_fromfile[i]->begin.type==SKIP_NOTHING){ if ((float)(int)(k/2.0) == (float)k/2.0) _dxd_gi_dataloc[k++]=0.0; else _dxd_gi_dataloc[k++]=1.0; } else{ t = _dxd_gi_fromfile[i]->type; for (num=0; _dxd_gi_fromfile[i]->skip[num]>=0; num++){ switch(_dxd_gi_fromfile[i]->type){ case(TYPE_UBYTE): f = (float)DREF(ubyte,_dxd_gi_fromfile[i]->data,num); break; case(TYPE_BYTE): f = (float)DREF(byte,_dxd_gi_fromfile[i]->data,num); break; case(TYPE_USHORT): f = (float)DREF(ushort,_dxd_gi_fromfile[i]->data,num); break; case(TYPE_SHORT): f = (float)DREF(short,_dxd_gi_fromfile[i]->data,num); break; case(TYPE_UINT): f = (float)DREF(uint,_dxd_gi_fromfile[i]->data,num); break; case(TYPE_INT): f = (float)DREF(int,_dxd_gi_fromfile[i]->data,num); break; case(TYPE_FLOAT): f = (float)DREF(float,_dxd_gi_fromfile[i]->data,num); break; case(TYPE_DOUBLE): f = (float)DREF(double,_dxd_gi_fromfile[i]->data,num); break; } if (_dxd_gi_fromfile[i]->index < 10) /* for grid or points */ _dxd_gi_dimsize[j++]= (int)f; else /* for positions */ _dxd_gi_dataloc[k++]=f; } } } if (j>0) _dxd_gi_numdims = j; /* clean up _dxd_gi_fromfile, done using this */ for (i=0; _dxd_gi_fromfile[i]; i++){ DXFree((Pointer)_dxd_gi_fromfile[i]->skip); DXFree((Pointer)_dxd_gi_fromfile[i]->width); DXFree((Pointer)_dxd_gi_fromfile[i]->data); DXFree((Pointer)_dxd_gi_fromfile[i]); } DXFree(_dxd_gi_fromfile); _dxd_gi_fromfile=NULL; return OK; error: return ERROR; } /* * Initialized a parse_state variable for use with StrTok(). * File is assumed to already be open with file pointer fp. */ static Error InitFileTok(struct parse_state *ps, FILE *fp, char *filename) { ps->filename = filename; ps->current = NULL; ps->fp = fp; ps->lineno = 0; ps->line = (char *)DXAllocate(MAX_DSTR); return OK; } /* * Operate similar to C lib strtok(), but allows the user to specify * whether a new line should be read to find the next token. * ERROR/OK is returned with error code set and *token is returned * as NULL (if no token found) or as a pointer to string containing * the token. */ static Error FileTok(struct parse_state *ps,char *sep, int newline, char** token) { char *current = ps->current; char *tp = &ps->token[0]; char *str; int n; /* * Looking for a token (something with a character not found in sep). * Scan across newlines if newlinek is true. */ do { /* * DXRead a new line if * a) this is the first time called * b) the last time we were called left *current == '\0'; * c) we are scanning for a token on the next line */ if (current == NULL || *current == '\0' || (newline & FORCE_NEWLINE)) { if (!ps->filename || !getline(ps)) return ERROR; current = ps->line; } /* Find first character not found in sep */ while (*current && strchr(sep,*current)) current++; } while ((newline & NEWLINE_OK) && !*current); if (*current) { /* We found a token */ /* if token begins with " go to next " before looking for end */ if (*current == '\"'){ do { *tp = *current; tp++; current++; }while (*current && *current!='\"'); } do { *tp = *current; tp++; current++; /* if (*current=='\\'){ current++; if (*current==','){ *tp=*current; tp++; current++;} else {current--;} } */ } while (*current && !strchr(sep,*current)); *tp = '\0'; *token = &ps->token[0]; } else { /* No token was found (before the end of line) */ *token = NULL; } ps->current = current; return OK; error: return ERROR; } static Error getline(struct parse_state *ps) { char str[MAX_DSTR]; char *line = ps->line; char *current = ps->current; int n=0; /* get newline allocating space if ness */ if ((fgets(str,MAX_DSTR,ps->fp))==NULL){ DXSetError(ERROR_INVALID_DATA,"#10898",ps->filename); return ERROR; } ps->lineno++; strcpy(line,str); while ((int)strlen(str)>MAX_DSTR-2){ if ((fgets(str,MAX_DSTR,ps->fp))==NULL){ DXSetError(ERROR_INVALID_DATA,"#10898",ps->filename); return ERROR; } n++; line = (char *)DXReAllocate(line,(unsigned int)strlen(str)+n*MAX_DSTR); strcat(line,str); } if (line[strlen(line)-2] == '\r') line[strlen(line)-2] = '\n'; current = line; ps->current = current; ps->line = line; return OK; } static Error getmorevar(int *num) { int i,oldnum = *num; *num = *num + *num *.5; if ((_dxd_gi_var = (struct variable **)DXReAllocate((Pointer)_dxd_gi_var, sizeof(struct variable *) * *num)) == NULL) return ERROR; for (i=oldnum; i < *num; i++) _dxd_gi_var[i] = NULL; return OK; }