From d1839943c909be95b7b0974c0dd72124ab5ed54b Mon Sep 17 00:00:00 2001 From: Kevin Shanahan Date: Sun, 17 Feb 2013 11:49:00 +1030 Subject: [PATCH] qbsp: make parser state non-global Signed-off-by: Kevin Shanahan --- qbsp/map.c | 110 +++++++++++++++++++++++++------------------------- qbsp/parser.c | 81 +++++++++++++++++-------------------- qbsp/parser.h | 18 +++++---- 3 files changed, 104 insertions(+), 105 deletions(-) diff --git a/qbsp/map.c b/qbsp/map.c index 73b29e85..5e2618b6 100644 --- a/qbsp/map.c +++ b/qbsp/map.c @@ -100,7 +100,7 @@ FindTexinfo(texinfo_t *t) static void -ParseEpair(mapentity_t *ent) +ParseEpair(parser_t *parser, mapentity_t *ent) { epair_t *epair; @@ -108,13 +108,13 @@ ParseEpair(mapentity_t *ent) epair->next = ent->epairs; ent->epairs = epair; - if (strlen(token) >= MAX_KEY - 1) - Error(errEpairTooLong, linenum); - epair->key = copystring(token); - ParseToken(PARSE_SAMELINE); - if (strlen(token) >= MAX_VALUE - 1) - Error(errEpairTooLong, linenum); - epair->value = copystring(token); + if (strlen(parser->token) >= MAX_KEY - 1) + Error(errEpairTooLong, parser->linenum); + epair->key = copystring(parser->token); + ParseToken(parser, PARSE_SAMELINE); + if (strlen(parser->token) >= MAX_VALUE - 1) + Error(errEpairTooLong, parser->linenum); + epair->value = copystring(parser->token); if (!strcasecmp(epair->key, "origin")) { GetVectorForKey(ent, epair->key, ent->origin); @@ -171,15 +171,15 @@ typedef enum { } texcoord_style_t; static texcoord_style_t -ParseExtendedTX(void) +ParseExtendedTX(parser_t *parser) { texcoord_style_t style = TX_ORIGINAL; - if (ParseToken(PARSE_COMMENT)) { - if (!strncmp(token, "//TX", 4)) { - if (token[4] == '1') + if (ParseToken(parser, PARSE_COMMENT)) { + if (!strncmp(parser->token, "//TX", 4)) { + if (parser->token[4] == '1') style = TX_QUARK_TYPE1; - else if (token[4] == '2') + else if (parser->token[4] == '2') style = TX_QUARK_TYPE2; } } @@ -259,7 +259,8 @@ SetTexinfo_QuakeEd(const plane_t *plane, const int shift[2], int rotate, } static void -SetTexinfo_QuArK(vec3_t planepts[3], texcoord_style_t style, texinfo_t *out) +SetTexinfo_QuArK(parser_t *parser, vec3_t planepts[3], texcoord_style_t style, + texinfo_t *out) { int i; vec3_t vecs[2]; @@ -302,7 +303,7 @@ SetTexinfo_QuArK(vec3_t planepts[3], texcoord_style_t style, texinfo_t *out) */ determinant = a * d - b * c; if (fabs(determinant) < ZERO_EPSILON) { - Message(msgWarning, warnDegenerateQuArKTX, linenum); + Message(msgWarning, warnDegenerateQuArKTX, parser->linenum); for (i = 0; i < 3; i++) out->vecs[0][i] = out->vecs[1][i] = 0; } else { @@ -323,7 +324,7 @@ SetTexinfo_QuArK(vec3_t planepts[3], texcoord_style_t style, texinfo_t *out) static void -ParseBrush(mapbrush_t *brush) +ParseBrush(parser_t *parser, mapbrush_t *brush) { vec3_t planepts[3]; vec3_t t1, t2, t3; @@ -337,41 +338,41 @@ ParseBrush(mapbrush_t *brush) mapface_t *face, *checkface; brush->faces = face = map.faces + map.numfaces; - while (ParseToken(PARSE_NORMAL)) { - if (!strcmp(token, "}")) + while (ParseToken(parser, PARSE_NORMAL)) { + if (!strcmp(parser->token, "}")) break; // read the three point plane definition for (i = 0; i < 3; i++) { if (i != 0) - ParseToken(PARSE_NORMAL); - if (strcmp(token, "(")) - Error(errInvalidMapPlane, linenum); + ParseToken(parser, PARSE_NORMAL); + if (strcmp(parser->token, "(")) + Error(errInvalidMapPlane, parser->linenum); for (j = 0; j < 3; j++) { - ParseToken(PARSE_SAMELINE); - planepts[i][j] = atof(token); + ParseToken(parser, PARSE_SAMELINE); + planepts[i][j] = atof(parser->token); } - ParseToken(PARSE_SAMELINE); - if (strcmp(token, ")")) - Error(errInvalidMapPlane, linenum); + ParseToken(parser, PARSE_SAMELINE); + if (strcmp(parser->token, ")")) + Error(errInvalidMapPlane, parser->linenum); } // read the texturedef memset(&tx, 0, sizeof(tx)); - ParseToken(PARSE_SAMELINE); - tx.miptex = FindMiptex(token); - ParseToken(PARSE_SAMELINE); - shift[0] = atoi(token); - ParseToken(PARSE_SAMELINE); - shift[1] = atoi(token); - ParseToken(PARSE_SAMELINE); - rotate = atoi(token); - ParseToken(PARSE_SAMELINE); - scale[0] = atof(token); - ParseToken(PARSE_SAMELINE); - scale[1] = atof(token); + ParseToken(parser, PARSE_SAMELINE); + tx.miptex = FindMiptex(parser->token); + ParseToken(parser, PARSE_SAMELINE); + shift[0] = atoi(parser->token); + ParseToken(parser, PARSE_SAMELINE); + shift[1] = atoi(parser->token); + ParseToken(parser, PARSE_SAMELINE); + rotate = atoi(parser->token); + ParseToken(parser, PARSE_SAMELINE); + scale[0] = atof(parser->token); + ParseToken(parser, PARSE_SAMELINE); + scale[1] = atof(parser->token); // if the three points are all on a previous plane, it is a // duplicate plane @@ -386,7 +387,7 @@ ParseBrush(mapbrush_t *brush) break; } if (checkface < face) { - Message(msgWarning, warnBrushDuplicatePlane, linenum); + Message(msgWarning, warnBrushDuplicatePlane, parser->linenum); continue; } @@ -403,17 +404,17 @@ ParseBrush(mapbrush_t *brush) plane = &face->plane; CrossProduct(t1, t2, plane->normal); if (VectorCompare(plane->normal, vec3_origin)) { - Message(msgWarning, warnNoPlaneNormal, linenum); + Message(msgWarning, warnNoPlaneNormal, parser->linenum); continue; } VectorNormalize(plane->normal); plane->dist = DotProduct(t3, plane->normal); - tx_type = ParseExtendedTX(); + tx_type = ParseExtendedTX(parser); switch (tx_type) { case TX_QUARK_TYPE1: case TX_QUARK_TYPE2: - SetTexinfo_QuArK(&planepts[0], tx_type, &tx); + SetTexinfo_QuArK(parser, &planepts[0], tx_type, &tx); break; default: SetTexinfo_QuakeEd(plane, shift, rotate, scale, &tx); @@ -432,32 +433,32 @@ ParseBrush(mapbrush_t *brush) } static bool -ParseEntity(mapentity_t *ent) +ParseEntity(parser_t *parser, mapentity_t *ent) { mapbrush_t *brush; - if (!ParseToken(PARSE_NORMAL)) + if (!ParseToken(parser, PARSE_NORMAL)) return false; - if (strcmp(token, "{")) - Error(errParseEntity, linenum); + if (strcmp(parser->token, "{")) + Error(errParseEntity, parser->linenum); if (map.numentities == map.maxentities) Error(errLowEntCount); ent->mapbrushes = brush = map.brushes + map.numbrushes; do { - if (!ParseToken(PARSE_NORMAL)) + if (!ParseToken(parser, PARSE_NORMAL)) Error(errUnexpectedEOF); - if (!strcmp(token, "}")) + if (!strcmp(parser->token, "}")) break; - else if (!strcmp(token, "{")) { + else if (!strcmp(parser->token, "{")) { if (map.numbrushes == map.maxbrushes) Error(errLowMapbrushCount); - ParseBrush(brush++); + ParseBrush(parser, brush++); map.numbrushes++; } else - ParseEpair(ent); + ParseEpair(parser, ent); } while (1); ent->nummapbrushes = brush - ent->mapbrushes; @@ -469,7 +470,7 @@ ParseEntity(mapentity_t *ent) static void -PreParseFile(char *buf) +PreParseFile(const char *buf) { int braces = 0; struct lumpdata *texinfo; @@ -528,6 +529,7 @@ PreParseFile(char *buf) void LoadMapFile(void) { + parser_t parser; char *buf; int i, j, length, cAxis; void *pTemp; @@ -540,11 +542,11 @@ LoadMapFile(void) length = LoadFile(options.szMapName, &buf, true); PreParseFile(buf); - ParserInit(buf); + ParserInit(&parser, buf); map.numfaces = map.numbrushes = map.numentities = 0; ent = map.entities; - while (ParseEntity(ent)) { + while (ParseEntity(&parser, ent)) { if (ent->nummapbrushes) { ent->lumps[BSPMODEL].data = AllocMem(BSPMODEL, 1, true); ent->lumps[BSPMODEL].count = 1; diff --git a/qbsp/parser.c b/qbsp/parser.c index 7a81a278..79808ec6 100644 --- a/qbsp/parser.c +++ b/qbsp/parser.c @@ -22,65 +22,58 @@ #include "qbsp.h" #include "parser.h" -int linenum; -char token[MAXTOKEN]; - -static bool unget; -static char *script; - - void -ParserInit(char *data) +ParserInit(parser_t *p, const char *data) { - linenum = 1; - script = data; - unget = false; + p->linenum = 1; + p->pos = data; + p->unget = false; } bool -ParseToken(int flags) +ParseToken(parser_t *p, parseflags_t flags) { char *token_p; /* is a token already waiting? */ - if (unget) { - unget = false; + if (p->unget) { + p->unget = false; return true; } skipspace: /* skip space */ - while (*script <= 32) { - if (!*script) { + while (*p->pos <= 32) { + if (!*p->pos) { if (flags & PARSE_SAMELINE) - Error(errLineIncomplete, linenum); + Error(errLineIncomplete, p->linenum); return false; } - if (*script++ == '\n') { + if (*p->pos++ == '\n') { if (flags & PARSE_SAMELINE) - Error(errLineIncomplete, linenum); - linenum++; + Error(errLineIncomplete, p->linenum); + p->linenum++; } } /* comment field */ - if (script[0] == '/' && script[1] == '/') { + if (p->pos[0] == '/' && p->pos[1] == '/') { if (flags & PARSE_COMMENT) { - token_p = token; - while (*script && *script != '\n') { - *token_p++ = *script++; - if (token_p > &token[MAXTOKEN - 1]) - Error(errTokenTooLarge, linenum); + token_p = p->token; + while (*p->pos && *p->pos != '\n') { + *token_p++ = *p->pos++; + if (token_p > &p->token[MAXTOKEN - 1]) + Error(errTokenTooLarge, p->linenum); } goto out; } if (flags & PARSE_SAMELINE) - Error(errLineIncomplete, linenum); - while (*script++ != '\n') - if (!*script) { + Error(errLineIncomplete, p->linenum); + while (*p->pos++ != '\n') + if (!*p->pos) { if (flags & PARSE_SAMELINE) - Error(errLineIncomplete, linenum); + Error(errLineIncomplete, p->linenum); return false; } goto skipspace; @@ -89,23 +82,23 @@ ParseToken(int flags) return false; /* copy token */ - token_p = token; + token_p = p->token; - if (*script == '"') { - script++; - while (*script != '"') { - if (!*script) - Error(errEOFInQuotes, linenum); - *token_p++ = *script++; - if (token_p > &token[MAXTOKEN - 1]) - Error(errTokenTooLarge, linenum); + if (*p->pos == '"') { + p->pos++; + while (*p->pos != '"') { + if (!*p->pos) + Error(errEOFInQuotes, p->linenum); + *token_p++ = *p->pos++; + if (token_p > &p->token[MAXTOKEN - 1]) + Error(errTokenTooLarge, p->linenum); } - script++; + p->pos++; } else - while (*script > 32) { - *token_p++ = *script++; - if (token_p > &token[MAXTOKEN - 1]) - Error(errTokenTooLarge, linenum); + while (*p->pos > 32) { + *token_p++ = *p->pos++; + if (token_p > &p->token[MAXTOKEN - 1]) + Error(errTokenTooLarge, p->linenum); } out: *token_p = 0; diff --git a/qbsp/parser.h b/qbsp/parser.h index f47a9836..8ec671e8 100644 --- a/qbsp/parser.h +++ b/qbsp/parser.h @@ -26,16 +26,20 @@ #define MAXTOKEN 256 -extern int linenum; -extern char token[MAXTOKEN]; - -enum parseflags { +typedef enum parseflags { PARSE_NORMAL = 0, PARSE_SAMELINE = 1, /* The next token must be on the current line */ PARSE_COMMENT = 2 /* Return a // comment as the next token */ -}; +} parseflags_t; -bool ParseToken(int flags); -void ParserInit(char *data); +typedef struct parser { + bool unget; + const char *pos; + int linenum; + char token[MAXTOKEN]; +} parser_t; + +bool ParseToken(parser_t *p, parseflags_t flags); +void ParserInit(parser_t *p, const char *data); #endif /* PARSER_H */