home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * CONVDATA.C is an unsupported tool to help convert old (*.ply) data files *
- * to the new (*.dat) format. This tool will be retired in future releases. *
- * *
- * To compile: *
- * *
- * Under MSDOS, using Borland/Turbo C: 'tcc -ml convdata.c' *
- * *
- * Under UNIX: 'cc -i convdata convdata.c' *
- * *
- * Usage: *
- * *
- * convdata < oldfile.ply > newfile.dat *
- * *
- * or *
- * *
- * convdata oldfile.ply > newfile.dat *
- *****************************************************************************/
-
- #ifdef __MSDOS__
- #include <stdlib.h>
- #include <conio.h>
- #endif /* __MSDOS__ */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <math.h>
- #include <string.h>
-
- #ifdef NO_VOID_PTR
- #define VoidPtr char *
- #else
- #define VoidPtr void *
- #endif /* NO_VOID_PTR */
-
- #ifndef LINE_LEN
- #define LINE_LEN 255
- #endif LINE_LEN
-
- #define NAME_LEN 6
-
- #ifndef TRUE
- #define TRUE 1
- #define FALSE 0
- #endif
-
- #ifndef NULL
- #define NULL 0
- #endif
-
- #define FILE_TYPE_DATA 1
- #define FILE_TYPE_VIEW 2
-
- #define GEN_COPY(Dest, Src, Size) memcpy(Dest, Src, Size)
-
- #define UNGET_STACK_SIZE 5
-
- /*****************************************************************************
- * Tokens definitions goes into here *
- *****************************************************************************/
- #define TOKEN_OPEN_PAREN 1
- #define TOKEN_CLOSE_PAREN 2
-
- #define TOKEN_NUMBER 10 /* Not used as number & names are decoded */
- /* according to their places in grammer. */
-
- #define TOKEN_VERTEX 20
- #define TOKEN_POLYGON 21
- #define TOKEN_POLYLINE 22
- #define TOKEN_POINTLIST 23
- #define TOKEN_OBJECT 24
- #define TOKEN_COLOR 25
- #define TOKEN_INTERNAL 26
- #define TOKEN_NORMAL 27
- #define TOKEN_PLANE 28
- #define TOKEN_CBEZIER 29
- #define TOKEN_SBEZIER 30
- #define TOKEN_CNURB 31
- #define TOKEN_SNURB 32
-
- #define TOKEN_OTHER 100 /* Probably names & numbers. */
- #define TOKEN_EOF -1
-
- #define VERTEX_ENTRY 0x0001 /* Entry type, up to 16 types. */
- #define POLYGON_ENTRY 0x0002
- #define POLYLINE_ENTRY 0x0004
- #define OBJECT_ENTRY 0x0008
- #define COLOR_ENTRY 0x0010
-
- #define POLYGON 1
- #define POLYLINE 2
- #define POINTLIST 3
-
- /*****************************************************************************
- * Parser error codes are following: *
- *****************************************************************************/
- #define P_ERR_NUMBER_EXPECTED 1
- #define P_ERR_OPEN_PAREN_EXPECTED 2
- #define P_ERR_CLOSE_PAREN_EXPECTED 3
- #define P_ERR_LIST_COMP_UNDEF 4
- #define P_ERR_UNDEF_EXPR_HEADER 5
- #define P_ERR_NAME_TOO_LONG 6
- #define P_ERR_PT_TYPE_EXPECTED 7
-
- #define P_WRN_OBJ_NAME_TRUNC 100
-
- /*****************************************************************************
- * And some more definitions ... *
- *****************************************************************************/
-
- typedef unsigned char Byte;
-
- typedef struct BinTree { /* The entries are saved as binary trees. */
- struct BinTree *right, *left; /* Classic, isnt it !? */
- union {
- VoidPtr PVoid;
- struct VertexStruct *PVertex;
- struct PolygonStruct *PPolygon;
- struct ObjectStruct *PObject;
- } Data;
- char Name[NAME_LEN];
- Byte EntryType; /* Kind of pointer in union. */
- Byte Used; /* TRUE if allready has been used (multi - referenced). */
- } BinTree;
-
- typedef struct FileDescription { /* Each data file loaded gets such struct. */
- BinTree *VertexPointer, /* Pointers on the binary trees ... */
- *PolygonPointer,
- *ObjectPointer;
- } FileDescription;
-
- /* Use the following structure if linear list operations are to be performed */
- /* on VertexStruct/PolygonStruct/ObjectStruct (Virtual functions...). */
- typedef struct LinearListStruct {
- struct LinearListStruct *Pnext;
- } LinearListStruct;
-
- typedef struct VertexStruct {
- struct VertexStruct *Pnext;
- float Coord[3]; /* The 3D coords. */
- float Normal[3]; /* The 3D normal. */
- Byte Transform;
- Byte Internal; /* If edge is Internal (IRIT output). */
- Byte HasNormal; /* If edge has a normal defined. */
- } VertexStruct;
-
- typedef struct PolygonStruct {
- struct PolygonStruct *Pnext;
- VertexStruct *PVertex; /* The polygon vertices. */
- float Plane[4]; /* The Polygon plane equation. */
- Byte PolyType; /* One of POLYGON, POLYLINE, POINTLIST. */
- Byte HasPlane; /* If polygon has a plane defined. */
- } PolygonStruct;
-
- typedef struct ObjectStruct {
- struct ObjectStruct *Pnext;
- PolygonStruct *PPolygon; /* The objects polygons. */
- int Color;
- } ObjectStruct;
-
- /* And function prototypes: */
-
- FileDescription *GetDataFile(FILE *f);
- void GetViewFile(FILE *f, int FileExists);
- BinTree *GetBinTree(char *RecName, BinTree *Tree);
-
- extern unsigned int _stklen = 32766; /* Increase default stack size. */
-
- static int GlblToken = 0, /* Used by the parser, to unget token. */
- GlblLineCount = 1, /* Used to locate errors in input file. */
- GlblParserError = 0; /* Save last error number found. */
- static char GlblStringToken[UNGET_STACK_SIZE][LINE_LEN];/* Save unget tokens.*/
- static struct FileDescription *Descriptor;
-
- char *Real2Str(double R);
- static struct BinTree *AllocBinTree(int Entry, VoidPtr Data);
- static void UnGetToken(char *StringToken);
- static void GetStringToken(FILE *f, char *StringToken);
- static int GetToken(FILE *f, char *StringToken);
- static void GetVertexAttributes(VertexStruct *PVertex, FILE *f);
- static void GetPolygonAttributes(PolygonStruct *PPolygon, FILE *f);
- static void GetObjectAttributes(ObjectStruct *PObject, FILE *f);
- static void EliminateComments(FILE *f);
- static void ParserError(int ErrNum, char *Msg);
- static void InsertBinTree(BinTree **Tree, BinTree *PNewRecord);
- static LinearListStruct *GetNameFromFD(char *Name, FileDescription *FD,
- int EntryTypes);
- static VoidPtr GetLinList(FILE *f, FileDescription *FD, int EntryTypes);
- static char *MyMalloc(unsigned size);
- static void MyExit(int ExitCode);
-
- /*****************************************************************************
- * *
- *****************************************************************************/
- void main(int argc, char **argv)
- {
- FILE *f = NULL;
-
- if (argc == 2 && (f = fopen(argv[1], "rt")) != NULL)
- GetDataFile(f);
- else GetDataFile(stdin);
-
- if (f) fclose(f);
-
- MyExit(0);
-
- printf("%lf", exp((double) argc));
- }
-
- /*****************************************************************************
- * Dump out the new format (simpler, isnt it!?). *
- *****************************************************************************/
- void DumpOutObject(BinTree *T)
- {
- int i;
- struct ObjectStruct *PObject = T -> Data.PObject;
- struct PolygonStruct *PPolygon = PObject -> PPolygon;
- struct VertexStruct *PVertex;
-
- printf("[OBJECT [COLOR %d] %s\n", PObject -> Color, T -> Name);
-
- while (PPolygon) {
- for (i = 0, PVertex = PPolygon -> PVertex;
- PVertex != NULL;
- i++, PVertex = PVertex -> Pnext);
-
- printf(" [%s", PPolygon -> PolyType == POLYLINE ? "POLYLINE" :
- PPolygon -> PolyType == POLYGON ? "POLYGON" : "POINTLIST");
- if (PPolygon -> HasPlane)
- printf(" [PLANE %s %s %s %s]",
- Real2Str(PPolygon -> Plane[0]),
- Real2Str(PPolygon -> Plane[1]),
- Real2Str(PPolygon -> Plane[2]),
- Real2Str(PPolygon -> Plane[3]));
- printf(" %d\n", i);
-
- PVertex = PPolygon -> PVertex;
- while (PVertex) {
- printf("\t[");
- if (PVertex -> Internal)
- printf("[INTERNAL] ");
- if (PVertex -> HasNormal)
- printf("[NORMAL %s %s %s] ",
- Real2Str(PVertex->Normal[0]),
- Real2Str(PVertex->Normal[1]),
- Real2Str(PVertex->Normal[2]));
- printf("%s %s %s]\n",
- Real2Str(PVertex->Coord[0]),
- Real2Str(PVertex->Coord[1]),
- Real2Str(PVertex->Coord[2]));
-
- PVertex = PVertex -> Pnext;
- }
-
- printf(" ]\n");
- PPolygon = PPolygon -> Pnext;
- }
- printf("] /* OBJECT %s */\n", T -> Name);
- }
-
- /*****************************************************************************
- * Convert a real number into a string. *
- *****************************************************************************/
- char *Real2Str(double R)
- {
- static int i = 0;
- static char Buffer[10][LINE_LEN];
- int j, k;
-
- sprintf(Buffer[i], "%-8.6lg", R);
-
- for (k = 0; !isdigit(Buffer[i][k]) && k < LINE_LEN; k++);
- if (k >= LINE_LEN) {
- fprintf(stderr, "Conversion of real number failed.\n");
- MyExit(3);
- }
-
- for (j = strlen(Buffer[i]) - 1; Buffer[i][j] == ' ' && j > k; j--);
- if (strchr(Buffer[i], '.') != NULL)
- for (; Buffer[i][j] == '0' && j > k; j--);
- Buffer[i][j+1] = 0;
-
- j = i;
- i = (i + 1) % 10;
- return Buffer[j];
- }
-
- /*****************************************************************************
- * Routine to read the data from a given file and update the data structures *
- * Descriptor (which returned) from it. *
- * If MoreFlag is on then more printed staff will be given... *
- *****************************************************************************/
- FileDescription *GetDataFile(FILE *f)
- {
- int i;
- char StringToken[LINE_LEN];
- struct VertexStruct *PVertex;
- struct PolygonStruct *PPolygon;
- struct ObjectStruct *PObject;
- struct BinTree *PBinTree;
-
- GlblToken = 0;
-
- Descriptor = (FileDescription *) MyMalloc(sizeof(FileDescription));
- /* As all the trees are empty set the following: */
- Descriptor -> VertexPointer =
- Descriptor -> PolygonPointer =
- Descriptor -> ObjectPointer = (BinTree *) NULL;
-
- GlblLineCount = 1; /* Reset line counter. */
- EliminateComments(f); /* Skip all comments including '['. */
- while (!feof(f)) {
- GlblParserError = 0; /* Reset errors. */
- switch (GetToken(f, StringToken)) {
- case TOKEN_VERTEX:
- PVertex = (VertexStruct *) MyMalloc(sizeof(VertexStruct));
- PVertex -> Transform = FALSE; /* Flag if vertex transformed. */
- PVertex -> Internal = FALSE; /* Flag if vertex is internal. */
- PVertex -> HasNormal = FALSE; /* Flag if vertex has normal. */
- PBinTree = AllocBinTree(VERTEX_ENTRY, (VoidPtr) PVertex);
- GetToken(f, PBinTree -> Name); /* Get the name. */
- if (strlen(PBinTree -> Name) >= NAME_LEN)
- ParserError(P_ERR_NAME_TOO_LONG, PBinTree -> Name);
- /* The following handle the optional attributes in record. */
- if (GetToken(f, StringToken) == TOKEN_OPEN_PAREN)
- GetVertexAttributes(PVertex, f); /* Get attributes. */
- else UnGetToken(StringToken);
- /* The following handles reading of 3 coord. of vertex. */
- for (i=0; i<3 ;i++) {
- GetToken(f, StringToken);
- if (sscanf(StringToken, "%f", &PVertex -> Coord[i]) != 1)
- ParserError(P_ERR_NUMBER_EXPECTED, StringToken);
- }
- if ((i=GetToken(f, StringToken)) != TOKEN_CLOSE_PAREN)
- ParserError(P_ERR_CLOSE_PAREN_EXPECTED, StringToken);
- if (!GlblParserError)
- InsertBinTree(&Descriptor -> VertexPointer, PBinTree);
- break;
- case TOKEN_POLYGON:
- PPolygon = (PolygonStruct *) MyMalloc(sizeof(PolygonStruct));
- PPolygon -> PolyType = POLYGON;
- PPolygon -> HasPlane = FALSE;
- PBinTree = AllocBinTree(POLYGON_ENTRY, (VoidPtr) PPolygon);
- GetToken(f, PBinTree -> Name); /* Get the name. */
- if (strlen(PBinTree -> Name) >= NAME_LEN)
- ParserError(P_ERR_NAME_TOO_LONG, PBinTree -> Name);
- /* The following handle the optional attributes in record. */
- if (GetToken(f, StringToken) == TOKEN_OPEN_PAREN)
- GetPolygonAttributes(PPolygon, f);
- else UnGetToken(StringToken);
- /* The following handles reading the members list. */
- PPolygon -> PVertex = (VertexStruct *)
- GetLinList(f, Descriptor, VERTEX_ENTRY);
- if (!GlblParserError)
- InsertBinTree(&Descriptor -> PolygonPointer, PBinTree);
- break;
- case TOKEN_POLYLINE:
- PPolygon = (PolygonStruct *) MyMalloc(sizeof(PolygonStruct));
- PPolygon -> PolyType = POLYLINE;
- PPolygon -> HasPlane = FALSE;
- PBinTree = AllocBinTree(POLYGON_ENTRY, (VoidPtr) PPolygon);
- GetToken(f, PBinTree -> Name); /* Get the name. */
- if (strlen(PBinTree -> Name) >= NAME_LEN)
- ParserError(P_ERR_NAME_TOO_LONG, PBinTree -> Name);
- /* The following handle the optional attributes in record. */
- if (GetToken(f, StringToken) == TOKEN_OPEN_PAREN)
- GetPolygonAttributes(PPolygon, f);
- else UnGetToken(StringToken);
- /* The following handles reading the members list. */
- PPolygon -> PVertex = (VertexStruct *)
- GetLinList(f, Descriptor, VERTEX_ENTRY);
- if (!GlblParserError)
- InsertBinTree(&Descriptor -> PolygonPointer, PBinTree);
- break;
- case TOKEN_POINTLIST:
- PPolygon = (PolygonStruct *) MyMalloc(sizeof(PolygonStruct));
- PPolygon -> PolyType = POINTLIST;
- PPolygon -> HasPlane = FALSE;
- PBinTree = AllocBinTree(POLYGON_ENTRY, (VoidPtr) PPolygon);
- GetToken(f, PBinTree -> Name); /* Get the name. */
- if (strlen(PBinTree -> Name) >= NAME_LEN)
- ParserError(P_ERR_NAME_TOO_LONG, PBinTree -> Name);
- /* The following handle the optional attributes in record. */
- if (GetToken(f, StringToken) == TOKEN_OPEN_PAREN)
- GetPolygonAttributes(PPolygon, f);
- else UnGetToken(StringToken);
- /* The following handles reading the members list. */
- PPolygon -> PVertex = (VertexStruct *)
- GetLinList(f, Descriptor, VERTEX_ENTRY);
- if (!GlblParserError)
- InsertBinTree(&Descriptor -> PolygonPointer, PBinTree);
- break;
- case TOKEN_OBJECT:
- PObject = (ObjectStruct *) MyMalloc(sizeof(ObjectStruct));
- PObject-> Color = 1;
- PBinTree = AllocBinTree(OBJECT_ENTRY, (VoidPtr) PObject);
- GetToken(f, PBinTree -> Name); /* Get the name. */
- if (strlen(PBinTree -> Name) >= NAME_LEN) {
- /* Although this may be considered an error, no one */
- /* reference objects, so we can simply truncate it. */
- PBinTree -> Name[NAME_LEN - 1] = 0;
- }
- /* The following handle the optional attributes in record. */
- if (GetToken(f, StringToken) == TOKEN_OPEN_PAREN)
- GetObjectAttributes(PObject, f);
- else UnGetToken(StringToken);
- /* The following handles reading the polygon list. */
- /* Note an object might be created from Polygons only. */
- PObject -> PPolygon = (PolygonStruct *)
- GetLinList(f, Descriptor, POLYGON_ENTRY);
- if (!GlblParserError)
- InsertBinTree(&Descriptor -> ObjectPointer, PBinTree);
- DumpOutObject(PBinTree);
- break;
- default:
- ParserError(P_ERR_UNDEF_EXPR_HEADER, StringToken);
- break;
- } /* Of switch. */
- if (!feof(f)) EliminateComments(f); /* Skip comments including '['. */
- } /* Of while !eof. */
-
- return Descriptor;
- }
-
- /*****************************************************************************
- * Routine to allocate one BinTree Item: *
- *****************************************************************************/
- static struct BinTree *AllocBinTree(int Entry, VoidPtr Data)
- {
- struct BinTree *PBinTree;
-
- PBinTree = (BinTree *) MyMalloc(sizeof(BinTree));
- PBinTree -> EntryType = Entry;
- PBinTree -> Used = FALSE;
- PBinTree -> Data.PVoid = Data;
- PBinTree -> right = PBinTree -> left = (BinTree *) NULL;
-
- return PBinTree;
- }
-
- /*****************************************************************************
- * Routine to unget one token (on stack of UNGET_STACK_SIZE levels!) *
- *****************************************************************************/
- static void UnGetToken(char *StringToken)
- {
- if (GlblToken >= UNGET_STACK_SIZE) {
- printf("Parser Internal stack overflow...\n");
- MyExit(1);
- }
-
- strcpy(GlblStringToken[GlblToken], StringToken);
- GlblToken++; /* GlblToken exists - Something in it (no overflow check). */
- }
-
- /*****************************************************************************
- * Routine to get the next token out of the input file f. *
- * Returns the next token found, as StringToken. *
- * Note: StringToken must be allocated before calling this routine! *
- *****************************************************************************/
- static void GetStringToken(FILE *f, char *StringToken)
- {
- int len;
- char c, *LocalStringToken;
-
- if (GlblToken) { /* get first the unget token */
- GlblToken--;
- strcpy(StringToken, GlblStringToken[GlblToken]);
- return;
- }
- /* skip white spaces: */
- while ((!feof(f))
- && (((c = getc(f)) == ' ') || (c == '\t') || (c == '\n')))
- if (c == '\n') GlblLineCount++; /* Count the lines. */
-
- LocalStringToken = StringToken;
- if (c == '[') /* Its a token by itself so return it. */
- *LocalStringToken++ = c; /* Copy the token into string. */
- else {
- if (!feof(f))
- do *LocalStringToken++ = c; /* Copy the token into string. */
- while ((!feof(f)) &&
- ((c = getc(f)) != ' ') && (c != '\t') && (c != '\n'));
- if (c == '\n') ungetc(c, f); /* Save it to be counted next time. */
- }
- *LocalStringToken = NULL; /* Put eos. */
-
- /* The following handles the spacial case were we have XXXX] - we must */
- /* split it into two token XXXX and ], UnGetToken(']') and return XXXX: */
- if ((StringToken[len = strlen(StringToken)-1] == ']') && (len > 0)) {
- /* Return CloseParan */
- UnGetToken(&StringToken[len]); /* Save next token. */
- StringToken[len] = NULL; /* Set end of string on "]". */
- }
- }
-
- /*****************************************************************************
- * Routine to get the next token out of the input file f as token number. *
- * Returns the next token number found, with numeric result in NumericToken *
- * if TokenType is TOKEN_NUMBER. *
- * Note: StringToken must be allocated before calling this routine! *
- *****************************************************************************/
- static int GetToken(FILE *f, char *StringToken)
- {
- GetStringToken(f, StringToken);
-
- if (feof(f)) return TOKEN_EOF;
-
- if (!strcmp(StringToken, "[")) return TOKEN_OPEN_PAREN;
- if (!strcmp(StringToken, "]")) return TOKEN_CLOSE_PAREN;
-
- if (!strcmp(StringToken, "VERTEX")) return TOKEN_VERTEX;
- if (!strcmp(StringToken, "POLYGON")) return TOKEN_POLYGON;
- if (!strcmp(StringToken, "POLYLINE")) return TOKEN_POLYLINE;
- if (!strcmp(StringToken, "POINTLIST")) return TOKEN_POINTLIST;
- if (!strcmp(StringToken, "OBJECT")) return TOKEN_OBJECT;
-
- if (!strcmp(StringToken, "COLOR")) return TOKEN_COLOR;
- if (!strcmp(StringToken, "INTERNAL")) return TOKEN_INTERNAL;
- if (!strcmp(StringToken, "NORMAL")) return TOKEN_NORMAL;
- if (!strcmp(StringToken, "PLANE")) return TOKEN_PLANE;
-
- if (!strcmp(StringToken, "CBEZIER")) return TOKEN_CBEZIER;
- if (!strcmp(StringToken, "SBEZIER")) return TOKEN_SBEZIER;
- if (!strcmp(StringToken, "CNURB")) return TOKEN_CNURB;
- if (!strcmp(StringToken, "SNURB")) return TOKEN_SNURB;
-
- return TOKEN_OTHER; /* Must be number or name. */
- }
-
- /*****************************************************************************
- * Routine to read from input file f the following [ATTR ...] [ATTR ...]. *
- * Note the '[' was allready read. *
- * Current supported attributes: [INTERNAL] - internal edge (IRIT output) *
- *****************************************************************************/
- static void GetVertexAttributes(VertexStruct *PVertex, FILE *f)
- {
- int i;
- char StringToken[LINE_LEN];
-
-
- do {
- switch (GetToken(f, StringToken)) {
- case TOKEN_INTERNAL:
- PVertex -> Internal = TRUE;
- if (GetToken(f, StringToken) != TOKEN_CLOSE_PAREN)
- ParserError(P_ERR_CLOSE_PAREN_EXPECTED, StringToken);
- break;
- case TOKEN_NORMAL:
- PVertex -> HasNormal = TRUE;
- /* The following handles reading of 3 coord. of normal. */
- for (i=0; i<3 ;i++) {
- GetToken(f, StringToken);
- if (sscanf(StringToken, "%f", &PVertex -> Normal[i]) != 1)
- ParserError(P_ERR_NUMBER_EXPECTED, StringToken);
- }
- if (GetToken(f, StringToken) != TOKEN_CLOSE_PAREN)
- ParserError(P_ERR_CLOSE_PAREN_EXPECTED, StringToken);
- break;
- default: /* Ignore this option! */
- while (GetToken(f, StringToken) != TOKEN_CLOSE_PAREN);
- break;
- }
- }
- while (GetToken(f, StringToken) == TOKEN_OPEN_PAREN);
-
- UnGetToken(StringToken);
- }
-
- /*****************************************************************************
- * Routine to read from input file f the following [ATTR ...] [ATTR ...]. *
- * Note the '[' was allready read. *
- * Current supported attributes: None *
- *****************************************************************************/
- static void GetPolygonAttributes(PolygonStruct *PPolygon, FILE *f)
- {
- int i;
- char StringToken[LINE_LEN];
-
- do {
- switch (GetToken(f, StringToken)) {
- case TOKEN_PLANE:
- PPolygon -> HasPlane = TRUE;
- /* The following handles reading of 4 coord. of plane eqn.. */
- for (i=0; i<4 ;i++) {
- GetToken(f, StringToken);
- if (sscanf(StringToken, "%f", &PPolygon -> Plane[i]) != 1)
- ParserError(P_ERR_NUMBER_EXPECTED, StringToken);
- }
- if (GetToken(f, StringToken) != TOKEN_CLOSE_PAREN)
- ParserError(P_ERR_CLOSE_PAREN_EXPECTED, StringToken);
- break;
- default:
- while (GetToken(f, StringToken) != TOKEN_CLOSE_PAREN);
- break;
- }
- }
- while (GetToken(f, StringToken) == TOKEN_OPEN_PAREN);
-
- UnGetToken(StringToken);
- }
-
- /*****************************************************************************
- * Routine to read from input file f the following [ATTR ...] [ATTR ...]. *
- * Note the '[' was allready read. *
- * Current supported attributes: [COLOR C] - set color. *
- *****************************************************************************/
- static void GetObjectAttributes(ObjectStruct *PObject, FILE *f)
- {
- int i;
- char StringToken[LINE_LEN];
-
- do {
- switch (GetToken(f, StringToken)) {
- case TOKEN_COLOR:
- GetToken(f, StringToken);
- if (sscanf(StringToken, "%d", &i) != 1)
- ParserError(P_ERR_NUMBER_EXPECTED, StringToken);
- if (GetToken(f, StringToken) != TOKEN_CLOSE_PAREN)
- ParserError(P_ERR_CLOSE_PAREN_EXPECTED, StringToken);
- PObject -> Color = i;
- break;
- default:
- while (GetToken(f, StringToken) != TOKEN_CLOSE_PAREN);
- break;
- }
- }
- while (GetToken(f, StringToken) == TOKEN_OPEN_PAREN);
-
- UnGetToken(StringToken);
- }
-
- /*****************************************************************************
- * Routine to read the input tokens up to a '[' token - skip comments. *
- * Note the routine reads the '[' token, so next is the expression itself. *
- *****************************************************************************/
- static void EliminateComments(FILE *f)
- {
- char StringToken[LINE_LEN];
-
- while ((!feof(f)) && (GetToken(f, StringToken) != TOKEN_OPEN_PAREN));
- }
-
- /*****************************************************************************
- * Routine to print pasring error according to ErrNum and set GlblParserError.*
- *****************************************************************************/
- static void ParserError(int ErrNum, char *Msg)
- {
- GlblParserError = TRUE;
-
- printf("Error in line %3d : ", GlblLineCount);
-
- switch (ErrNum) {
- case P_ERR_NUMBER_EXPECTED:
- printf("Numeric data expected, ");
- break;
- case P_ERR_OPEN_PAREN_EXPECTED:
- printf("[ expected, ");
- break;
- case P_ERR_CLOSE_PAREN_EXPECTED:
- printf("] expected, ");
- break;
- case P_ERR_LIST_COMP_UNDEF:
- printf("List component undefined - ");
- break;
- case P_ERR_UNDEF_EXPR_HEADER:
- printf("Undefined expression header - ");
- break;
- case P_ERR_NAME_TOO_LONG:
- printf("Object Name too long (Max %d) - ", NAME_LEN - 1);
- break;
- case P_ERR_PT_TYPE_EXPECTED:
- printf("Point type expected, ");
- break;
- default:
- printf("Unknown error, ");
- break;
- }
- printf("found %s.\n", Msg);
- }
-
- /*****************************************************************************
- * Routine to insert new element into a binary tree. If the element already *
- * exists then the new one replace it. *
- *****************************************************************************/
- static void InsertBinTree(BinTree **Tree, BinTree *PNewRecord)
- {
- int Comparison;
- BinTree *PBin;
-
- if (*Tree == (BinTree *) NULL) /* Only might happen if the tree empty. */
- *Tree = PNewRecord;
- else { /* Search for the new place to put it. */
- /* Test for Match - if so replace old by new: */
- if ((Comparison = strcmp((*Tree) -> Name, PNewRecord -> Name)) == 0) {
- PBin = *Tree;
- *Tree = PNewRecord; /* Replace. */
- switch (PBin -> EntryType) { /* Free the data area (union). */
- case VERTEX_ENTRY:
- free((char *) PBin -> Data.PVertex);
- break;
- case POLYGON_ENTRY:
- free((char *) PBin -> Data.PPolygon);
- break;
- case OBJECT_ENTRY:
- free((char *) PBin -> Data.PObject);
- break;
- default:
- /* Should not be, unless was not updated here... */
- break;
- }
- free((char *) PBin);
- }
- else if (Comparison > 0) /* Go to right side - its bigger. */
- if ((*Tree) -> right != (BinTree *) NULL) /* Only if exist. */
- InsertBinTree(&((*Tree) -> right), PNewRecord);
- else (*Tree) -> right = PNewRecord; /* Put record in place. */
- else if ((*Tree) -> left != (BinTree *) NULL) /* Only if exist. */
- InsertBinTree(&((*Tree) -> left), PNewRecord);/*Smaller. */
- else (*Tree) -> left = PNewRecord; /* Put record in place. */
- }
- }
-
- /*****************************************************************************
- * Routine to Get an element from binary tree. If the element is found a *
- * pointer to it BinTree record is return, NULL else... *
- *****************************************************************************/
- BinTree *GetBinTree(char *RecName, BinTree *Tree)
- {
- int Comparison;
-
- /* If the tree is empty - not found, return NULL: */
- if (Tree == (BinTree *) NULL) return (BinTree *) NULL;
-
- /* Test for Match - if so return that record: */
- if ((Comparison = strcmp(Tree -> Name, RecName)) == 0)
- return Tree; /* Found it - so return it ... */
- else if (Comparison > 0)
- return GetBinTree(RecName, Tree -> right);
- else return GetBinTree(RecName, Tree -> left);
- }
-
- /*****************************************************************************
- * Routine to search for Name in the trees, allowed by EntryTypes, of the *
- * file descrition FD. NULL returned if not found. The order of search is: *
- * VERTEX , POLYGON , OBJECT. *
- * Once found, if was already used (multi-reference) it is copied fresh. *
- *****************************************************************************/
- static LinearListStruct *GetNameFromFD(char *Name, FileDescription *FD,
- int EntryTypes)
- {
- BinTree *PBin;
- VertexStruct *PVertex;
- PolygonStruct *PPolygon;
- ObjectStruct *PObject;
-
- if (EntryTypes & VERTEX_ENTRY) { /* Check in vertices tree. */
- if ((PBin = GetBinTree(Name, FD -> VertexPointer)) != NULL) {
- if (PBin -> Used) {
- PVertex = (VertexStruct *) MyMalloc(sizeof(VertexStruct));
- GEN_COPY(PVertex, PBin -> Data.PVertex, sizeof(VertexStruct));
- return (LinearListStruct *) PVertex;
- }
- else {
- PBin -> Used = TRUE;
- return (LinearListStruct *) PBin -> Data.PVertex;
- }
- }
- }
- if (EntryTypes & POLYGON_ENTRY) { /* Check in polygon tree. */
- if ((PBin = GetBinTree(Name, FD -> PolygonPointer)) != NULL) {
- if (PBin -> Used) {
- PPolygon = (PolygonStruct *) MyMalloc(sizeof(PolygonStruct));
- GEN_COPY(PPolygon, PBin -> Data.PPolygon, sizeof(PolygonStruct));
- return (LinearListStruct *) PPolygon;
- }
- else {
- PBin -> Used = TRUE;
- return (LinearListStruct *) PBin -> Data.PPolygon;
- }
- }
- }
- if (EntryTypes & OBJECT_ENTRY) { /* Check in object tree. */
- if ((PBin = GetBinTree(Name, FD -> ObjectPointer)) != NULL) {
- if (PBin -> Used) {
- PObject = (ObjectStruct *) MyMalloc(sizeof(ObjectStruct));
- GEN_COPY(PObject, PBin -> Data.PObject, sizeof(ObjectStruct));
- return (LinearListStruct *) PObject;
- }
- else {
- PBin -> Used = TRUE;
- return (LinearListStruct *) PBin -> Data.PObject;
- }
- }
- }
-
- return NULL; /* Not found. */
- }
-
- /*****************************************************************************
- * Routine to get linear list of names from file f until ']' is detected. *
- * search for that names in file description FD unter the trees allowed *
- * according to EntryTypes (1 bit per entry, see ?????Entry is parser.h). *
- * Create a linear list of pointers to them. Return that linear list. *
- *****************************************************************************/
- static VoidPtr GetLinList(FILE *f, FileDescription *FD, int EntryTypes)
- {
- char StringToken[LINE_LEN];
- struct LinearListStruct *PLinHead = NULL, *PLinTail = NULL, *PItem;
-
- while (GetToken(f, StringToken) != TOKEN_CLOSE_PAREN) {
- if ((PItem = GetNameFromFD(StringToken, FD, EntryTypes)) == NULL) {
- ParserError(P_ERR_LIST_COMP_UNDEF, StringToken);/* Record undef. */
- continue; /* To next component to search for. */
- }
- if (PLinHead == NULL) /* Its first record. */
- PLinHead = PLinTail = PItem;
- else { /* Its record in the middle. */
- PLinTail -> Pnext = PItem;
- PLinTail = PItem;
- }
- }
- if (PLinTail != NULL) PLinTail -> Pnext = NULL; /* Mark end of list. */
-
- return (VoidPtr) PLinHead;
- }
-
- /*****************************************************************************
- * My Routine to allocate dynamic memory. All program requests must call this *
- * routine (no direct call to malloc). Dies if no memory. *
- *****************************************************************************/
- static char *MyMalloc(unsigned size)
- {
- char *p;
-
- if ((p = malloc(size)) != NULL) return p;
-
- printf("Not enough memory, exit\n");
- MyExit(2);
-
- return NULL; /* Make warnings silent. */
- }
-
- /*****************************************************************************
- * MyExit routine. Note it might call to CloseGraph without calling *
- * InitGraph(), or call MouseClose() without MouseInit() etc. and it is the *
- * responsibility of the individual modules to do nothing in these cases. *
- *****************************************************************************/
- static void MyExit(int ExitCode)
- {
- exit(ExitCode);
- }
-