home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- * Module to read a graphic data file into the given structure. *
- * *
- * Written by: Gershon Elber Ver 2.0, Mar. 1990 *
- *****************************************************************************/
-
- /* #define DEBUG /* Defines some helpfull printing routines. */
-
- #ifdef __MSDOS__
- #include <stdlib.h>
- #endif /* __MSDOS__ */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <math.h>
- #include <string.h>
- #include "program.h"
- #include "genmat.h"
- #include "parser.h"
-
- 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;
-
- 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 int 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);
-
- #ifdef DEBUG
- void PrintAllBinTrees(FileDescription *FD);
- void PrintBinTree(BinTree *Tree);
- #endif DEBUG
-
- /*****************************************************************************
- * 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 -> PolylinePointer =
- 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:
- ++NumOfVertices;
-
- PVertex = (VertexStruct *) MyMalloc(sizeof(VertexStruct));
- PVertex -> Transform = FALSE; /* If vertex was transformed. */
- PVertex -> HasNormal = FALSE; /* If vertex has normal. */
- PBinTree = AllocBinTree(VERTEX_ENTRY, (VoidPtr) PVertex);
- GetToken(f, PBinTree -> Name); /* Get the 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_NumberExpected, StringToken);
- }
- if ((i=GetToken(f, StringToken)) != TOKEN_CLOSE_PAREN)
- ParserError(P_ERR_CloseParanExpected, StringToken);
- if (!GlblParserError)
- InsertBinTree(&Descriptor -> VertexPointer, PBinTree);
- break;
- case TOKEN_POLYGON:
- fprintf(stderr, "\b\b\b\b\b%5d", ++NumOfPolygons);
-
- PPolygon = (PolygonStruct *) MyMalloc(sizeof(PolygonStruct));
- PPolygon -> Polyline = FALSE;
- PPolygon -> FlipPlaneDir = 1; /* Can be one of 1, -1 only. */
- PBinTree = AllocBinTree(POLYGON_ENTRY, (VoidPtr) PPolygon);
- GetToken(f, PBinTree -> Name); /* Get the name. */
- /* The following handle the optional attributes in record. */
- i = FALSE; /* Let see if polygon has plane defined: */
- if (GetToken(f, StringToken) == TOKEN_OPEN_PAREN)
- i = GetPolygonAttributes(PPolygon, f);
- else UnGetToken(StringToken);
- /* The following handles reading the members list. */
- PPolygon -> PVertex = (VertexStruct *)
- GetLinList(f, Descriptor, VERTEX_ENTRY);
-
- /* Update Plane equation if has non or set the flip plane */
- /* dir if do has one. */
- i = UpdateEqnPolygon(PPolygon, i);
-
- /* Dont put it in if parser error, and clip its vertex list */
- /* if failed to find PLANE equation or polygon is back */
- /* and we are required to delete these (free it if you like).*/
- if (!GlblParserError) {
- if (!i) PPolygon -> PVertex = NULL;
- InsertBinTree(&Descriptor -> PolygonPointer, PBinTree);
- }
- break;
- case TOKEN_POLYLINE:
- fprintf(stderr, "\b\b\b\b\b%5d", ++NumOfPolygons);
-
- PPolygon = (PolygonStruct *) MyMalloc(sizeof(PolygonStruct));
- PPolygon -> Polyline = TRUE;
- PPolygon -> FlipPlaneDir = 1; /* Can be one of 1, -1 only. */
- PBinTree = AllocBinTree(POLYGON_ENTRY, (VoidPtr) PPolygon);
- GetToken(f, PBinTree -> Name); /* Get the 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 -> PolylinePointer, PBinTree);
- break;
- case TOKEN_OBJECT:
- PObject = (ObjectStruct *) MyMalloc(sizeof(ObjectStruct));
- PObject -> Color = ShadingInfo.DefaultColor;
- PBinTree = AllocBinTree(OBJECT_ENTRY, (VoidPtr) PObject);
- GetToken(f, PBinTree -> Name); /* Get the name. */
- /* 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/Polylines only. */
- PObject -> PPolygon = (PolygonStruct *)
- GetLinList(f, Descriptor, POLYGON_ENTRY | POLYLINE_ENTRY);
- /* Make sure no empty polygons exists (such as ones that had */
- /* no PLANE for some reason. */
- PPolygon = PObject -> PPolygon;
- if (PPolygon)
- while (PPolygon -> PVertex == NULL)
- PPolygon = PObject -> PPolygon = PPolygon -> Pnext;
- if (PPolygon)
- while (PPolygon -> Pnext != NULL) {
- if (PPolygon -> Pnext -> PVertex == NULL)
- PPolygon -> Pnext = PPolygon -> Pnext -> Pnext;
- else PPolygon = PPolygon -> Pnext;
- }
-
- if (!GlblParserError)
- InsertBinTree(&Descriptor -> ObjectPointer, PBinTree);
- break;
- default:
- ParserError(P_ERR_UndefExprHeader, 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;
- }
-
- /*****************************************************************************
- * The view file should be 4 by 4 matrix. *
- *****************************************************************************/
- void GetViewFile(FILE *f, int FileExists)
- {
- int i, j;
- char StringToken[LINE_LEN];
- MatrixType PerspMat, Mat;
-
- if (FileExists) {
- for (i=0; i<4; i++)
- for (j=0; j<4; j++)
- if (GetToken(f, StringToken) != TOKEN_OTHER ||
- sscanf(StringToken, "%lf", &GlblViewMat[i][j]) != 1) {
- fprintf(stderr, "Wrong input data in view file, dies\n");
- MyExit(1);
- }
-
- if (GetToken(f, StringToken) == TOKEN_OTHER &&
- sscanf(StringToken, "%lf", &PerspMat[0][0]) == 1) {
- for (i=0; i<4; i++)
- for (j=0; j<4; j++) {
- if (i==0 && j==0) continue; /* Already got first one. */
- if (GetToken(f, StringToken) != TOKEN_OTHER ||
- sscanf(StringToken, "%lf", &PerspMat[i][j]) != 1) {
- fprintf(stderr, "Wrong input data in view file, dies\n");
- MyExit(1);
- }
- }
- MultTwo4by4(GlblViewMat, GlblViewMat, PerspMat);
- }
- }
- else { /* Set default isometric view: */
- /* 90 - 35.2644 = 54.7356. */
- GenMatRotX1(DEG2RAD(-54.7356), Mat);
- GenMatRotZ1(M_PI + M_PI / 4, GlblViewMat);
- MultTwo4by4(GlblViewMat, GlblViewMat, Mat);
- }
- }
-
- /*****************************************************************************
- * Routine to unget one token (on stack of UNGET_STACK_SIZE levels!) *
- *****************************************************************************/
- static void UnGetToken(char *StringToken)
- {
- if (GlblToken >= UNGET_STACK_SIZE) {
- fprintf(stderr, "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, "OBJECT")) return TOKEN_OBJECT;
-
- if (!strcmp(StringToken, "COLOR")) return TOKEN_COLOR;
- if (!strcmp(StringToken, "RGB")) return TOKEN_RGB;
- if (!strcmp(StringToken, "INTERNAL")) return TOKEN_INTERNAL;
- if (!strcmp(StringToken, "NORMAL")) return TOKEN_NORMAL;
- if (!strcmp(StringToken, "PLANE")) return TOKEN_PLANE;
-
- 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: None. *
- *****************************************************************************/
- static void GetVertexAttributes(VertexStruct *PVertex, FILE *f)
- {
- int i;
- char StringToken[LINE_LEN];
- float Size;
-
- do {
- switch (GetToken(f, StringToken)) {
- case TOKEN_NORMAL:
- PVertex -> HasNormal = TRUE;
- /* The following handles reading of 3 coord. of vertex. */
- for (i=0, Size = 0.0; i<3 ;i++) {
- GetToken(f, StringToken);
- if (sscanf(StringToken, "%f", &PVertex -> Normal[i]) != 1)
- ParserError(P_ERR_NumberExpected, StringToken);
- Size += SQR(PVertex -> Normal[i]);
- }
- /* Make sure vector length is one unit: */
- Size = sqrt(Size);
- for (i=0; i<3 ;i++) PVertex -> Normal[i] /= Size;
-
- if (GetToken(f, StringToken) != TOKEN_CLOSE_PAREN)
- ParserError(P_ERR_CloseParanExpected, 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: [PLANE A B C D]. *
- * Returns TRUE if polygon PLANE attribute has been read. *
- *****************************************************************************/
- static int GetPolygonAttributes(PolygonStruct *PPolygon, FILE *f)
- {
- int i, HasPlane = FALSE;
- char StringToken[LINE_LEN];
-
- do {
- switch (GetToken(f, StringToken)) {
- case TOKEN_PLANE:
- for (i=0; i<4; i++) {
- GetToken(f, StringToken);
- if (sscanf(StringToken, "%f", &PPolygon -> Plane[i]) != 1)
- ParserError(P_ERR_NumberExpected, StringToken);
- }
- if (GetToken(f, StringToken) != TOKEN_CLOSE_PAREN)
- ParserError(P_ERR_CloseParanExpected, StringToken);
- HasPlane = TRUE;
- break;
- default:
- while (GetToken(f, StringToken) != TOKEN_CLOSE_PAREN);
- break;
- }
- }
- while (GetToken(f, StringToken) == TOKEN_OPEN_PAREN);
-
- UnGetToken(StringToken);
-
- return HasPlane;
- }
-
- /*****************************************************************************
- * Routine to read from input file f the following [ATTR ...] [ATTR ...]. *
- * Note the '[' was allready read. *
- * Current supported attributes: [COLOR C] [COLOR R G B] - 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_NumberExpected, StringToken);
- if (GetToken(f, StringToken) != TOKEN_CLOSE_PAREN)
- ParserError(P_ERR_CloseParanExpected, StringToken);
- PObject -> Color = i;
- break;
- case TOKEN_RGB:
- PObject -> Color = RGB_COLOR_GIVEN;
- /* The following handles reading of 3 coord. of normal. */
- for (i=0; i<3 ;i++) {
- GetToken(f, StringToken);
- if (sscanf(StringToken, "%d", &PObject -> RGBColor[i]) != 1)
- ParserError(P_ERR_NumberExpected, StringToken);
- }
- if (GetToken(f, StringToken) != TOKEN_CLOSE_PAREN)
- ParserError(P_ERR_CloseParanExpected, StringToken);
- 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;
-
- if (MoreFlag == 0) return; /* Dont print nothing. */
-
- fprintf(stderr, "\nError in line %3d : ", GlblLineCount);
-
- switch (ErrNum) {
- case P_ERR_NumberExpected:
- fprintf(stderr, "Numeric Data Expected, ");
- break;
- case P_ERR_CloseParanExpected:
- fprintf(stderr, "] expected, ");
- break;
- case P_ERR_ListCompUndef:
- fprintf(stderr, "List component undefined -");
- break;
- case P_ERR_UndefExprHeader:
- fprintf(stderr, "Undefined expression header -");
- break;
- default:
- fprintf(stderr, "Unknown error, ");
- break;
- }
- fprintf(stderr, " 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 & POLYLINE_ENTRY) { /* Check in polyline tree. */
- if ((PBin = GetBinTree(Name, FD -> PolylinePointer)) != NULL) {
- if (PBin -> Used) {
- PPolygon = (PolygonStruct *) MyMalloc(sizeof(PolygonStruct));
- GEN_COPY(PPolygon, PBin -> Data.PPolyline, sizeof(PolygonStruct));
- return (LinearListStruct *) PPolygon;
- }
- else {
- PBin -> Used = TRUE;
- return (LinearListStruct *) PBin -> Data.PPolyline;
- }
- }
- }
- 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_ListCompUndef, 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;
- }
-
- #ifdef DEBUG
-
- /*****************************************************************************
- * Routine to Print all the trees in the file description: *
- *****************************************************************************/
- void PrintAllBinTrees(FileDescription *FD)
- {
- fprintf(stderr, "******************* Vertices ******************\n");
- PrintBinTree(FD -> VertexPointer);
- fprintf(stderr, "******************* Polygons ******************\n");
- PrintBinTree(FD -> PolygonPointer);
- fprintf(stderr, "****************** Polyliness *****************\n");
- PrintBinTree(FD -> PolylinePointer);
- fprintf(stderr, "******************* Objects *******************\n");
- PrintBinTree(FD -> ObjectPointer);
- }
-
- /*****************************************************************************
- * Routine to Print the Names in tree in lexicorgaphic order. Used only for *
- * debuging - to see trees content... *
- *****************************************************************************/
- void PrintBinTree(BinTree *Tree)
- {
- /* If the tree is empty - not found, return NULL: */
- if (Tree == (BinTree *) NULL) return;
-
- PrintBinTree(Tree -> right);
- fprintf(stderr, "%s\n", Tree -> Name);
- PrintBinTree(Tree -> left);
- }
-
- #endif DEBUG
-