Category : C Source Code
Archive   : POLY3DRS.ZIP
Filename : PARSER.C

 
Output of file : PARSER.C contained in archive : POLY3DRS.ZIP
/*****************************************************************************
* 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
#endif /* __MSDOS__ */

#include
#include
#include
#include
#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


  3 Responses to “Category : C Source Code
Archive   : POLY3DRS.ZIP
Filename : PARSER.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/