/***********************************************************************/ /* 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" */ /***********************************************************************/ #include /* * internal data structs for processing external data format. */ /* constants. */ #define MAXNEST 20 /* max number of nested include files */ #define MAXBUF 1024 /* max length of a single input token */ #define MAXRANK 50 /* max rank for data items */ #define MAXTERMS 100 /* max terms in mesh or product array */ /* as objects are created, they are added to a linked list of objects, * with an id associated with each. */ struct objlist { int id; /* unique per input file */ Object o; /* if != NULL, actual object */ char *name; /* if named, the name */ int oused; /* whether object is really used in the file */ int odelete; /* what to do with object when done */ int nrefs; /* size of following list */ struct objlist **refs; /* list of objects referenced by this one */ struct objlist *next; /* linked list of all objects in file */ struct getby *gp; /* if a remote id, the info for remote */ }; /* odelete values. * what to do at the end when deleting the dictionary. this is used to * keep the top level objects without monkeying with the ref counts. */ #define OBJ_CANDELETE 0 #define OBJ_NODELETE 1 /* oused values * in onepass, all objects are created at the time they are encountered, * and at the end all unreferenced objects are deleted. * in twopass, all objects are identified as being referenced or not and * in the second pass the unused objects are not created. */ #define OBJ_UNUSED 0 #define OBJ_USED 1 #define NAMEATTR "name" /* local object id (same file), remote file id or either */ #define ID_LOCAL 1 #define ID_REMOTE 2 #define ID_EITHER 3 /* * dictionary section */ /* blocksize for local memory allocates */ #define LOCALSTORBLOCK 8192 /* dictionary entry for variable name -> unique identifier */ struct dinfo { PseudoKey key; /* psuedokey based on string contents */ char *contents; /* actual key value */ int type; /* class of token */ int value; /* system generated id for object aliases */ }; /* dictionary entry for keyword -> identifier */ struct kinfo { PseudoKey key; /* psuedokey based on string contents */ char *contents; /* actual key value */ int value; /* keyword token id */ }; struct localstor { int bytesleft; /* bytes are left to be allocated; 0==full */ int nextbyte; /* next available byte in block */ struct localstor *next; /* next block like this; NULL for end */ char contents[LOCALSTORBLOCK]; /* actual local storage */ }; struct dict { HashTable dicttab; /* hash table for user strings */ HashTable keytab; /* hash table for keywords */ struct localstor *localdict; /* local storage for strings */ int nextid; /* unique system-allocated ids */ }; /* object ids - either user defined or generated by the system. */ #define USER_ID(x) ((x+1) << 1) #define SYS_ID(x) ((x+1) << 1 | 1) /* * return by name vs. return by number */ struct getby { char *fname; /* remote filename, if needed - must free */ int which; /* import by name or by number */ int num; /* single number */ char **namelist; /* null terminated namelist (uses buf) */ int *numlist; /* -1 terminated numlist (uses buf) */ Pointer *gbuf; /* storage for lists - must free */ int seriesflag; /* which of start/end/delta has been set */ int serieslim[3]; /* start/end/delta frame numbers */ }; /* * values for 'which' */ #define GETBY_NONE 0 /* not set yet */ #define GETBY_NAME 1 /* named object list */ #define GETBY_NUM 2 /* single object number or byte offset */ #define GETBY_NUMLIST 3 /* object number list */ #define GETBY_LINES 4 /* line number offset */ #define GETBY_ID 5 /* internal dictionary id */ #define GETBY_ALLNAMES 6 /* all named objects */ /* * series limit flags */ #define SL_START 0x0001 #define SL_END 0x0002 #define SL_DELTA 0x0004 /* ascii-input-line-number to byte-offset-in-file translation list. * * could be used both ways (for finding a line number given a byte offset), * but right now it's being used for converting a line number to a byte * offset in the file so 'data line #' can be used to say where the * ascii data starts in a file. i don't know how to count lines when * there is binary data follows. praps the default for export ascii should * be line nos and for binary should be bytes. */ struct lines { int bytesalloc; /* allocation size is maxlcount * sizeof(int) */ int lcount; /* current max line count */ int *linelist; /* byte offset of each line from top of file */ }; /* * structure the input tokenizer (lexinput) routine returns. */ typedef union { int id; unsigned char c; int i; float f; double d; } Token; struct tinfo { int class; /* see list below */ int subclass; /* more specific */ Token token; /* value. type depends on class and context */ }; /* token class: subclass: token value: */ #define NUMBER 1 /* number type numeric value */ #define KEYWORD 2 /* none keyword id */ #define BRACKET 3 /* bracket type dictionary id */ #define STRING 4 /* none dictionary id */ #define LEXERROR 5 /* error type none */ #define NOTASCII 6 /* none none */ #define ALIAS 7 /* object id dictionary id */ #define PUNCT 8 /* punctuation type none */ #define IDENTIFIER 9 /* none dictionary id */ #define ENDOFHEADER 10 /* none none */ /* subclasses of number */ #define INTEGER 1 #define FLOAT 2 #define DOUBLE 3 #define CHAR 4 /* subclasses of bracketed strings - not currently used */ #define PAREN 1 #define SQUARE 2 #define CURLY 3 #define ANGLE 4 /* subclasses of error */ #define BADINPUT -1 #define BADQUOTE -2 #define BADNUMBER -3 #define BADCOMMA -4 #define BADBRACKET -5 #define BADLENGTH -6 /* subclasses of punctuation */ #define COMMA 1 #define SEMICOLON 2 #define COLON 3 #define NEWLINE 4 #define OTHER 9 #define UNKNOWN -1 /* info about how to parse. * * maybe this is going to need code for 'identifier' in the mustmatch * section so that file,number or file,name will parse as one dictionary * entry and get one identifier. * */ struct pinfo { int tonextline; /* return at start of next line */ int skippunct; /* punctuation (separators) are ok to skip */ int mustmatch; /* if the next token type is known already */ int nbytes; /* for skip, skip count */ int nodict; /* for string data, don't put in dictionary */ int skipnum; /* for numeric data, don't do the conversion */ char *inbuf; /* one token input buffer */ int incount; /* number of characters in that buffer */ char delim; /* current delimiter (squote, dquote, bracket, etc) */ int byteoffset; /* current byte offset */ int lineno; /* current line offset */ int prevlineno; /* line offset when parse was started */ int startlineno; /* line number where current object defn starts */ struct lines l; /* bytes offset to line number struct */ /* plus what? */ }; /* * one of these structures per open input file */ struct finfo { char *fname; /* input filename */ FILE *fd; /* fopen file descriptor */ struct getby gb; /* list of objects to import, and series limits */ struct tinfo t; /* current input token */ struct pinfo p; /* current parse state */ int recurse; /* recurse level for included files */ int dformat; /* default data format flags */ int denorm_fp; /* i860 binary data only: zero'd denormalized floats */ int bad_fp; /* i860 binary data only: zero'd NaN and Infinities */ int onepass; /* set if we can't seek backwards (eg it's a socket) */ int headerend; /* byte offset of end of header section */ HashTable ht; /* hash table for objects by objectid */ struct objlist *ol; /* list of all objects created or referenced */ struct dict *d; /* dictionary for this file */ int activity; /* whether we are making objects or just parsing ids */ Object curobj; /* object currently under construction */ int curid; /* id of current object */ }; /* * data file format flags */ #define D_BYTES 0x0007 #define D_MSB 0x0001 #define D_LSB 0x0002 #define D_NATIVE 0x0004 #define D_FORMATS 0x0070 #define D_IEEE 0x0010 #define D_XDR 0x0020 #define D_TEXT 0x0040 #define D_FILES 0x0700 #define D_FOLLOWS 0x0100 #define D_ONE 0x0200 #define D_TWO 0x0400 /* activity flag options: * * two pass: * identifying which objects use others and which ones are actually * going to be imported. filling byte offset/line number table. * skipping binary data follows arrays. * * making the used objects * * one pass: * making all objects and discarding unused ones at the end */ #define IDENTIFY_OBJS 1 #define MAKE_USED_OBJS 2 #define MAKE_ALL_OBJS 3 /* * object list ptr and object id from that list. */ struct objectid { struct objlist *ol; int id; }; /* * keywords for dictionary */ /* used in keyword list below. good words > 0, errors < 0 */ #define KW_OBJECT 1 #define KW_GROUP 2 #define KW_ARRAY 3 #define KW_FIELD 4 #define KW_STRING 5 #define KW_TRANSFORM 6 #define KW_MATRIX 7 #define KW_LIGHT 8 #define KW_CLIPPED 9 #define KW_SCREEN 10 #define KW_FILE 11 #define KW_ALIAS 12 #define KW_SERIES 13 #define KW_ATTRIBUTE 14 #define KW_VALUE 15 #define KW_COMPONENT 16 #define KW_MEMBER 17 #define KW_CLASS 18 #define KW_TYPE 19 #define KW_CHAR 20 #define KW_SHORT 21 #define KW_INTEGER 22 /* #define 23 */ #define KW_HYPER 24 #define KW_FLOAT 25 #define KW_DOUBLE 26 #define KW_CATEGORY 27 #define KW_REAL 28 #define KW_COMPLEX 29 #define KW_QUATERNION 30 #define KW_RANK 31 #define KW_SHAPE 32 #define KW_COUNT 33 /* #define 34 */ #define KW_DATA 35 #define KW_XDR 36 #define KW_ASCII 37 #define KW_IEEE 38 #define KW_FOLLOWS 39 #define KW_REGULARARRAY 40 #define KW_PRODUCTARRAY 41 #define KW_MESHARRAY 42 #define KW_PATHARRAY 43 #define KW_CAMERA 44 #define KW_DIRECTION 45 #define KW_LOCATION 46 #define KW_POSITION 47 #define KW_SIZE 48 #define KW_COLOR 49 #define KW_COMPOSITE 50 #define KW_NAME 51 #define KW_XFORM 52 #define KW_OF 53 #define KW_BY 54 #define KW_TIMES 55 #define KW_PLUS 56 #define KW_TERM 57 #define KW_ORIGIN 58 #define KW_DELTAS 59 #define KW_GRID 60 #define KW_GRIDPOSITIONS 61 #define KW_GRIDCONNECTIONS 62 #define KW_DISTANT 63 #define KW_LOCAL 64 #define KW_FROM 65 #define KW_TO 66 #define KW_WIDTH 67 #define KW_HEIGHT 68 #define KW_RESOLUTION 69 #define KW_ASPECT 70 #define KW_UP 71 #define KW_NUMBER 72 #define KW_MSB 73 #define KW_LSB 74 #define KW_MODE 75 #define KW_BINARY 76 #define KW_MESHOFFSETS 77 #define KW_DEFAULT 78 #define KW_LINES 79 #define KW_ANGLE 80 #define KW_AMBIENT 81 #define KW_WORLD 82 #define KW_VIEWPORT 83 #define KW_PIXEL 84 #define KW_BEHIND 85 #define KW_INSIDE 86 #define KW_INFRONT 87 #define KW_STATIONARY 88 #define KW_ORTHOGRAPHIC 89 #define KW_PERSPECTIVE 90 #define KW_NAMED 91 #define KW_CONSTANTARRAY 92 #define KW_SIGNED 93 #define KW_UNSIGNED 94 #define KW_MULTIGRID 95 /* add more here, and match with dict struct */ #define KW_END 9999 #define KW_NULL -1 /* bad return from dictionary lookup */ #define BADINDEX 0 /* force correct casts swab routines */ /* these use the (destination, source, ... ) parm order */ #define SWAB(x,y,z) _dxfByteSwap((void *)x, (void*)y, (int)(z)/2, TYPE_SHORT) #define SWAW(x,y,z) _dxfByteSwap((void *)x, (void*)y, (int)(z)/4, TYPE_INT) #define SWAD(x,y,z) _dxfByteSwap((void *)x, (void*)y, (int)(z)/8, TYPE_DOUBLE) /* Byte order */ typedef enum { BO_UNKNOWN = 1, BO_MSB = 2, BO_LSB = 3 } ByteOrder; extern Error _dxfByteSwap(void *, void*, int, Type); extern ByteOrder _dxfLocalByteOrder(void); #define LOCAL_BYTEORDER _dxfLocalByteOrder() /* shorthand for common routines. should these be real entry points? * these are going to be more efficient but make debugging more complicated. */ #define next_class(f, class) _dxfnexttoken(f, class, NULL, NULL) #define next_subclass(f, subclass) _dxfnexttoken(f, NULL, subclass, NULL) #define next_id(f, id) _dxfnexttoken(f, NULL, NULL, id) #define next_token(f, class, subclass, id) _dxfnexttoken(f, class, subclass, id) #define nextkeywordis(f, keyword) _dxfmatchid(f, KEYWORD, keyword, 1) #define next_string(f) _dxfisnexttoken(f, STRING, NULL, NULL) #define skipkeyword(f) _dxfmatchanysub(f, KEYWORD, NULL, NULL) #define match_keyword(f, keyword) _dxfmatchid(f, KEYWORD, keyword, 0) #define match_punct(f, type) _dxfmatchsaysub(f, PUNCT, type, NULL) #define get_keyword(f, keyword) _dxfmatchanysub(f, KEYWORD, NULL, keyword) #define get_string(f, string) _dxfmatchanysub(f, STRING, NULL, string) #define get_punct(f, type) _dxfmatchanysub(f, PUNCT, type, NULL) #define get_ident(f, id) _dxfmatchanysub(f, IDENTIFIER, NULL, id) #define get_number(f, type, val) _dxfmatchnumber(f, type, val) #define get_byte(f, val) _dxfmatchbyte(f, val) #define get_ubyte(f, val) _dxfmatchubyte(f, val) #define get_short(f, val) _dxfmatchshort(f, val) #define get_ushort(f, val) _dxfmatchushort(f, val) #define get_int(f, val) _dxfmatchint(f, val) #define get_uint(f, val) _dxfmatchuint(f, val) #define get_float(f, val) _dxfmatchfloat(f, val) #define get_double(f, val) _dxfmatchdouble(f, val) /* prototypes */ extern Error _dxfinitparse(struct finfo *f); extern Error _dxfresetparse(struct finfo *f); extern void _dxfdeleteparse(struct finfo *f); extern void _dxfsetstartline(struct finfo *f); extern int _dxfgetstartline(struct finfo *f); extern void _dxfsetprevline(struct finfo *f); extern int _dxfgetprevline(struct finfo *f); extern int _dxfgetlineno(struct finfo *f); extern Error _dxfnextline(struct finfo *f); extern Error _dxfendnotascii(struct finfo *f); extern void _dxfsetnexttype(struct finfo *f, int type); extern void _dxfsetskipnum(struct finfo *f, int type); extern void _dxfsetdictstringmode(struct finfo *f, int value); extern char * _dxfgetstringinfo(struct finfo *f, int *len); extern Error _dxfgetstringnodict(struct finfo *f); extern Error _dxfset_headerend(struct finfo *f); extern Error _dxfsetparse(struct finfo *f, long byteoffset, int lines, int lineno); extern Error _dxfnexttoken(struct finfo *f, int *class, int *subclass, int *id); extern Error _dxfisnexttoken(struct finfo *f, int *class, int *subclass, int *id); extern Error _dxfmatchbyte(struct finfo *f, byte *p); extern Error _dxfmatchubyte(struct finfo *f, ubyte *p); extern Error _dxfmatchshort(struct finfo *f, short *p); extern Error _dxfmatchushort(struct finfo *f, ushort *p); extern Error _dxfmatchint(struct finfo *f, int *p); extern Error _dxfmatchuint(struct finfo *f, uint *p); extern Error _dxfmatchfloat(struct finfo *f, float *p); extern Error _dxfmatchdouble(struct finfo *f, double *p); extern Error _dxfmatchsaysub(struct finfo *f, int class, int subclass, int *id); extern Error _dxfmatchanysub(struct finfo *f, int class, int *subclass, int *id); extern Error _dxfmatchnumber(struct finfo *f, int *subclass, Token *id); extern Error _dxfmatchid(struct finfo *f, int class, int id, int noparse); extern Error _dxfinitfinfo(struct finfo *f); extern void _dxffreefinfo(struct finfo *f); extern void _dxfdupfinfo(struct finfo *f1, struct finfo *f2); extern int _dxfiskeyword(struct dict *d, char *word); extern char * _dxflookkeyword(int id); extern Error _dxfinitdict(struct dict *d); extern Error _dxfdeletedict(struct dict *d); extern int _dxfputdict(struct dict *d, char *word); extern int _dxflookdict(struct dict *d, char *word); extern char * _dxfdictname(struct dict *d, int slot); extern Error _dxfgetdictinfo(struct dict *d, int slot, int *type, int *value); extern Error _dxfsetdictalias(struct dict *d, int slot, int *value); extern Error _dxfgetdictalias(struct dict *d, int alias, int *value); extern int _dxfgetuniqueid(struct dict *d); extern FILE * _dxfopen_dxfile(char *inname, char *auxname, char **outname, char *ext); extern Error _dxfclose_dxfile(FILE *fptr, char *filename); extern Error _dxfparse_file(struct finfo *f, Object *retobj); extern Error _dxfreadarray_binary(struct finfo *f, Array a, int format); extern Error _dxfreadarray_xdr(FILE *fd, Array a); extern Error _dxfreadarray_text(struct finfo *f, Array a); extern Error _dxfskiparray_binary(struct finfo *f, int items, int itemsize); extern Error _dxfskiparray_xdr(FILE *fd, int items, int itemsize); extern Error _dxfskiparray_text(struct finfo *f, int items, Type t); extern Error _dxfreadoffset(struct finfo *f, Array a, int offset, int type); extern Error _dxfreadremote(struct finfo *f, Array a, int id, int type); extern Error _dxfinitobjlist(struct finfo *f); extern Error _dxfdeleteobjlist(struct finfo *f); extern Error _dxfaddobjlist(struct finfo *f, int id, Object o, char *name, int start); extern Error _dxflookobjlist(struct finfo *f, int id, Object *o, char **name); struct getby **_dxfgetobjgb(struct finfo *f, int id); extern Error _dxfsetobjptr(struct finfo *f, int id, Object o); extern Error _dxfsetobjused(struct finfo *f, int id); extern Error _dxfisobjused(struct finfo *f, int id); extern Error _dxfobjusesobj(struct finfo *f, int id, int refd_id); extern Object _dxfnamedobjlist(struct finfo *f, char **namelist); extern Object _dxfmarknamedobjlist(struct finfo *f, char **namelist); extern Object _dxfnumberedobjlist(struct finfo *f, int *numlist, int idflag); extern Object _dxfmarknumberedobjlist(struct finfo *f, int *numlist, int idflag); extern Error _dxflexinput(struct finfo *fp); extern char * _dxfprtoken(struct tinfo *t, struct dict *d); extern Error _dxfskip_object(struct finfo *fp); extern Error _dxfskip_object_or_attr(struct finfo *fp); /* utility routines */ extern Error _dxfValidate(Field f); extern Error DXColorNameToRGB(char *, RGBColor *); #if !defined(DXD_STANDARD_IEEE) /* * Floating point denormalization checks for machines which don't support * IEEE denormalized floating point values. */ extern void _dxfdouble_denorm(int *, int , int *, int *); extern void _dxffloat_denorm(int *, int , int *, int *); #endif /* should debugging messages be compiled in? 0=no, 1=yes */ #define DEBUG_MSG 0