-/*\r
-Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
-For a list of contributors, see the accompanying CONTRIBUTORS file.\r
-\r
-This file is part of GtkRadiant.\r
-\r
-GtkRadiant is free software; you can redistribute it and/or modify\r
-it under the terms of the GNU General Public License as published by\r
-the Free Software Foundation; either version 2 of the License, or\r
-(at your option) any later version.\r
-\r
-GtkRadiant is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
-GNU General Public License for more details.\r
-\r
-You should have received a copy of the GNU General Public License\r
-along with GtkRadiant; if not, write to the Free Software\r
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\r
-*/\r
-\r
-\r
-//**************************************************************************\r
-//**\r
-//** token.c\r
-//**\r
-//**************************************************************************\r
-\r
-// HEADER FILES ------------------------------------------------------------\r
-\r
-#include "token.h"\r
-#include "inout.h"\r
-\r
-// MACROS ------------------------------------------------------------------\r
-\r
-// TYPES -------------------------------------------------------------------\r
-\r
-typedef enum\r
-{\r
- CHR_EOF,\r
- CHR_LETTER,\r
- CHR_NUMBER,\r
- CHR_QUOTE,\r
- CHR_SPECIAL\r
-} chr_t;\r
-\r
-// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------\r
-\r
-// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------\r
-\r
-// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------\r
-\r
-static void ProcessLetterToken(void);\r
-static void ProcessNumberToken(void);\r
-static void ProcessQuoteToken(void);\r
-static void ProcessSpecialToken(void);\r
-static qboolean CheckForKeyword(void);\r
-static void NextChr(void);\r
-\r
-// EXTERNAL DATA DECLARATIONS ----------------------------------------------\r
-\r
-// PUBLIC DATA DEFINITIONS -------------------------------------------------\r
-\r
-tokenType_t tk_Token;\r
-int tk_Line;\r
-int tk_IntNumber;\r
-float tk_FloatNumber;\r
-char *tk_String;\r
-char tk_SourceName[MAX_FILE_NAME_LENGTH];\r
-\r
-// PRIVATE DATA DEFINITIONS ------------------------------------------------\r
-\r
-static char Chr;\r
-static char *FileStart;\r
-static char *FilePtr;\r
-static char *FileEnd;\r
-static qboolean SourceOpen;\r
-static char ASCIIToChrCode[256];\r
-static char TokenStringBuffer[MAX_QUOTED_LENGTH];\r
-static qboolean IncLineNumber;\r
-static char TempBuffer[2048];\r
-\r
-static struct\r
-{\r
- char *name;\r
- tokenType_t token;\r
-} Keywords[] =\r
-{\r
- "model", TK_MODEL,\r
- "mesh", TK_MESH,\r
- "vertices", TK_VERTICES,\r
- "edges", TK_EDGES,\r
- "position", TK_POSITION,\r
- "polygons", TK_POLYGONS,\r
- "nodes", TK_NODES,\r
- "rotation", TK_ROTATION,\r
- "scaling", TK_SCALING,\r
- "translation", TK_TRANSLATION,\r
- "vertex", TK_VERTEX,\r
- "HRCH", TK_HRCH,\r
- "Softimage", TK_SOFTIMAGE,\r
- "material", TK_MATERIAL,\r
- "spline", TK_SPLINE,\r
-\r
- "Named", TK_C_NAMED,\r
- "object", TK_OBJECT,\r
- "Tri", TK_C_TRI,\r
- "Vertices", TK_C_VERTICES,\r
- "Faces", TK_C_FACES,\r
- "Vertex", TK_C_VERTEX,\r
- "list", TK_LIST,\r
- "Face", TK_C_FACE,\r
-\r
- "Hexen", TK_C_HEXEN,\r
- "Triangles", TK_C_TRIANGLES,\r
- "Version", TK_C_VERSION,\r
- "faces", TK_FACES,\r
- "face", TK_FACE,\r
- "origin", TK_ORIGIN,\r
-\r
- "DK_clusters", TK_CLUSTERS,\r
- "DK_cluster_ncvs", TK_NUM_CLUSTER_VERTICES,\r
- "name", TK_NAME,\r
- "DK_cluster_name", TK_CLUSTER_NAME,\r
- "DK_cluster_state", TK_CLUSTER_STATE,\r
-\r
- "actor_data", TK_ACTOR_DATA,\r
- "uvTexture", TK_UVTEXTURE,\r
-\r
- NULL, -1\r
-};\r
-\r
-static char *TokenNames[] =\r
-{\r
- "<nothing>",\r
- "<unknown_char>",\r
- "<EOF>",\r
- "<identifier>",\r
- "<string>",\r
- "<int_number>",\r
- "<float_number>",\r
- "(",\r
- ")",\r
- "{",\r
- "}",\r
- "[",\r
- "]",\r
- ":",\r
- "mesh",\r
- "model",\r
- "nodes",\r
- "rotation",\r
- "scaling",\r
- "translation",\r
- "polygons",\r
- "position",\r
- "vertex",\r
- "vertices",\r
- "HRCH",\r
- "Softimage"\r
-};\r
-\r
-// CODE --------------------------------------------------------------------\r
-\r
-//==========================================================================\r
-//\r
-// TK_Init\r
-//\r
-//==========================================================================\r
-\r
-void TK_Init(void)\r
-{\r
- int i;\r
-\r
- for(i = 0; i < 256; i++)\r
- {\r
- ASCIIToChrCode[i] = CHR_SPECIAL;\r
- }\r
- for(i = '0'; i <= '9'; i++)\r
- {\r
- ASCIIToChrCode[i] = CHR_NUMBER;\r
- }\r
- for(i = 'A'; i <= 'Z'; i++)\r
- {\r
- ASCIIToChrCode[i] = CHR_LETTER;\r
- }\r
- for(i = 'a'; i <= 'z'; i++)\r
- {\r
- ASCIIToChrCode[i] = CHR_LETTER;\r
- }\r
- ASCIIToChrCode[ASCII_QUOTE] = CHR_QUOTE;\r
- ASCIIToChrCode[ASCII_UNDERSCORE] = CHR_LETTER;\r
- ASCIIToChrCode[EOF_CHARACTER] = CHR_EOF;\r
- tk_String = TokenStringBuffer;\r
- IncLineNumber = FALSE;\r
- SourceOpen = FALSE;\r
-}\r
-\r
-//==========================================================================\r
-//\r
-// TK_OpenSource\r
-//\r
-//==========================================================================\r
-\r
-void TK_OpenSource(char *fileName)\r
-{\r
- int size;\r
-\r
- TK_CloseSource();\r
- size = LoadFile(fileName, (void **)&FileStart);\r
- strcpy(tk_SourceName, fileName);\r
- SourceOpen = TRUE;\r
- FileEnd = FileStart+size;\r
- FilePtr = FileStart;\r
- tk_Line = 1;\r
- tk_Token = TK_NONE;\r
- NextChr();\r
-}\r
-\r
-//==========================================================================\r
-//\r
-// TK_CloseSource\r
-//\r
-//==========================================================================\r
-\r
-void TK_CloseSource(void)\r
-{\r
- if(SourceOpen)\r
- {\r
- free(FileStart);\r
- SourceOpen = FALSE;\r
- }\r
-}\r
-\r
-//==========================================================================\r
-//\r
-// TK_Fetch\r
-//\r
-//==========================================================================\r
-\r
-tokenType_t TK_Fetch(void)\r
-{\r
- while(Chr == ASCII_SPACE)\r
- {\r
- NextChr();\r
- }\r
- if(Chr == '-')\r
- {\r
- ProcessNumberToken();\r
- }\r
- else switch(ASCIIToChrCode[(byte)Chr])\r
- {\r
- case CHR_EOF:\r
- tk_Token = TK_EOF;\r
- break;\r
- case CHR_LETTER:\r
- ProcessLetterToken();\r
- break;\r
- case CHR_NUMBER:\r
- ProcessNumberToken();\r
- break;\r
- case CHR_QUOTE:\r
- ProcessQuoteToken();\r
- break;\r
- default:\r
- ProcessSpecialToken();\r
- break;\r
- }\r
- return tk_Token;\r
-}\r
-\r
-//==========================================================================\r
-//\r
-// TK_Require\r
-//\r
-//==========================================================================\r
-\r
-void TK_Require(tokenType_t tokType)\r
-{\r
- if(tokType == TK_FLOATNUMBER && tk_Token == TK_INTNUMBER)\r
- {\r
- tk_FloatNumber = (float)tk_IntNumber;\r
- tk_Token = TK_FLOATNUMBER;\r
- return;\r
- }\r
- if(tk_Token != tokType)\r
- {\r
- Error("File '%s', line %d:\nExpected '%s', found '%s'.\n",\r
- tk_SourceName, tk_Line, TokenNames[tokType],\r
- TokenNames[tk_Token]);\r
- }\r
-}\r
-\r
-void TK_FetchRequire(tokenType_t tokType)\r
-{\r
- TK_Fetch();\r
- TK_Require(tokType);\r
-}\r
-\r
-tokenType_t TK_RequireFetch(tokenType_t tokType)\r
-{\r
- TK_Require(tokType);\r
- return TK_Fetch();\r
-}\r
-\r
-tokenType_t TK_FetchRequireFetch(tokenType_t tokType)\r
-{\r
- TK_Fetch();\r
- TK_Require(tokType);\r
- return TK_Fetch();\r
-}\r
-\r
-tokenType_t TK_Beyond(tokenType_t tokType)\r
-{\r
- while(tk_Token != tokType)\r
- {\r
- if(TK_Fetch() == TK_EOF)\r
- {\r
- Error("File '%s':\nCould not find token '%s'.\n", // FIXME: TokenNames table not big enuff \r
- tk_SourceName, TokenNames[tokType]);\r
- }\r
- }\r
- return TK_Fetch();\r
-}\r
-\r
-void TK_BeyondRequire(tokenType_t bTok, tokenType_t rTok)\r
-{\r
- TK_Beyond(bTok);\r
- TK_Require(rTok);\r
-}\r
-\r
-tokenType_t TK_Search(tokenType_t tokType)\r
-{\r
- while(tk_Token != tokType)\r
- {\r
- if(TK_Fetch() == TK_EOF)\r
- {\r
- return TK_EOF;\r
- }\r
- }\r
- return TK_Fetch();\r
-}\r
-\r
-tokenType_t TK_Get(tokenType_t tokType)\r
-{\r
- while(tk_Token != tokType)\r
- {\r
- if(TK_Fetch() == TK_EOF)\r
- {\r
- Error("File '%s':\nCould not find token '%s'.\n",\r
- tk_SourceName, TokenNames[tokType]);\r
- }\r
- }\r
- return tk_Token;\r
-}\r
-\r
-//==========================================================================\r
-//\r
-// ProcessLetterToken\r
-//\r
-//==========================================================================\r
-\r
-static void ProcessLetterToken(void)\r
-{\r
- int i;\r
- char *text;\r
-\r
- i = 0;\r
- text = TokenStringBuffer;\r
- while(ASCIIToChrCode[(byte)Chr] == CHR_LETTER\r
- || ASCIIToChrCode[(byte)Chr] == CHR_NUMBER)\r
- {\r
- if(++i == MAX_IDENTIFIER_LENGTH)\r
- {\r
- Error("File '%s', line %d:\nIdentifier too long.\n",\r
- tk_SourceName, tk_Line);\r
- }\r
- *text++ = Chr;\r
- NextChr();\r
- }\r
- *text = 0;\r
- if(CheckForKeyword() == FALSE)\r
- {\r
- tk_Token = TK_IDENTIFIER;\r
- }\r
-}\r
-\r
-//==========================================================================\r
-//\r
-// CheckForKeyword\r
-//\r
-//==========================================================================\r
-\r
-static qboolean CheckForKeyword(void)\r
-{\r
- int i;\r
-\r
- for(i = 0; Keywords[i].name != NULL; i++)\r
- {\r
- if(strcmp(tk_String, Keywords[i].name) == 0)\r
- {\r
- tk_Token = Keywords[i].token;\r
- return TRUE;\r
- }\r
- }\r
- return FALSE;\r
-}\r
-\r
-//==========================================================================\r
-//\r
-// ProcessNumberToken\r
-//\r
-//==========================================================================\r
-\r
-static void ProcessNumberToken(void)\r
-{\r
- char *buffer;\r
-\r
- buffer = TempBuffer;\r
- *buffer++ = Chr;\r
- NextChr();\r
- while(ASCIIToChrCode[(byte)Chr] == CHR_NUMBER)\r
- {\r
- *buffer++ = Chr;\r
- NextChr();\r
- }\r
- if(Chr == '.')\r
- { // Float\r
- *buffer++ = Chr;\r
- NextChr(); // Skip period\r
- while(ASCIIToChrCode[(byte)Chr] == CHR_NUMBER)\r
- {\r
- *buffer++ = Chr;\r
- NextChr();\r
- }\r
- *buffer = 0;\r
- tk_FloatNumber = (float)atof(TempBuffer);\r
- tk_Token = TK_FLOATNUMBER;\r
- return;\r
- }\r
-\r
- // Integer\r
- *buffer = 0;\r
- tk_IntNumber = atoi(TempBuffer);\r
- tk_Token = TK_INTNUMBER;\r
-}\r
-\r
-//==========================================================================\r
-//\r
-// ProcessQuoteToken\r
-//\r
-//==========================================================================\r
-\r
-static void ProcessQuoteToken(void)\r
-{\r
- int i;\r
- char *text;\r
-\r
- i = 0;\r
- text = TokenStringBuffer;\r
- NextChr();\r
- while(Chr != ASCII_QUOTE)\r
- {\r
- if(Chr == EOF_CHARACTER)\r
- {\r
- Error("File '%s', line %d:\n<EOF> inside string.\n",\r
- tk_SourceName, tk_Line);\r
- }\r
- if(++i > MAX_QUOTED_LENGTH-1)\r
- {\r
- Error("File '%s', line %d:\nString literal too long.\n",\r
- tk_SourceName, tk_Line);\r
- }\r
- *text++ = Chr;\r
- NextChr();\r
- }\r
- *text = 0;\r
- NextChr();\r
- tk_Token = TK_STRING;\r
-}\r
-\r
-//==========================================================================\r
-//\r
-// ProcessSpecialToken\r
-//\r
-//==========================================================================\r
-\r
-static void ProcessSpecialToken(void)\r
-{\r
- char c;\r
-\r
- c = Chr;\r
- NextChr();\r
- switch(c)\r
- {\r
- case '(':\r
- tk_Token = TK_LPAREN;\r
- break;\r
- case ')':\r
- tk_Token = TK_RPAREN;\r
- break;\r
- case '{':\r
- tk_Token = TK_LBRACE;\r
- break;\r
- case '}':\r
- tk_Token = TK_RBRACE;\r
- break;\r
- case '[':\r
- tk_Token = TK_LBRACKET;\r
- break;\r
- case ']':\r
- tk_Token = TK_RBRACKET;\r
- break;\r
- case ':':\r
- tk_Token = TK_COLON;\r
- break;\r
- default:\r
- tk_Token = TK_UNKNOWNCHAR;\r
- break;\r
- }\r
-}\r
-\r
-//==========================================================================\r
-//\r
-// NextChr\r
-//\r
-//==========================================================================\r
-\r
-static void NextChr(void)\r
-{\r
- if(FilePtr >= FileEnd)\r
- {\r
- Chr = EOF_CHARACTER;\r
- return;\r
- }\r
- if(IncLineNumber == TRUE)\r
- {\r
- tk_Line++;\r
- IncLineNumber = FALSE;\r
- }\r
- Chr = *FilePtr++;\r
- if(Chr < ASCII_SPACE)\r
- {\r
- if(Chr == '\n')\r
- {\r
- IncLineNumber = TRUE;\r
- }\r
- Chr = ASCII_SPACE;\r
- }\r
-}\r
+/*
+Copyright (C) 1999-2007 id Software, Inc. and contributors.
+For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+This file is part of GtkRadiant.
+
+GtkRadiant is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+GtkRadiant is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GtkRadiant; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+
+//**************************************************************************
+//**
+//** token.c
+//**
+//**************************************************************************
+
+// HEADER FILES ------------------------------------------------------------
+
+#include "token.h"
+#include "inout.h"
+
+// MACROS ------------------------------------------------------------------
+
+// TYPES -------------------------------------------------------------------
+
+typedef enum
+{
+ CHR_EOF,
+ CHR_LETTER,
+ CHR_NUMBER,
+ CHR_QUOTE,
+ CHR_SPECIAL
+} chr_t;
+
+// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
+
+// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
+
+// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
+
+static void ProcessLetterToken(void);
+static void ProcessNumberToken(void);
+static void ProcessQuoteToken(void);
+static void ProcessSpecialToken(void);
+static qboolean CheckForKeyword(void);
+static void NextChr(void);
+
+// EXTERNAL DATA DECLARATIONS ----------------------------------------------
+
+// PUBLIC DATA DEFINITIONS -------------------------------------------------
+
+tokenType_t tk_Token;
+int tk_Line;
+int tk_IntNumber;
+float tk_FloatNumber;
+char *tk_String;
+char tk_SourceName[MAX_FILE_NAME_LENGTH];
+
+// PRIVATE DATA DEFINITIONS ------------------------------------------------
+
+static char Chr;
+static char *FileStart;
+static char *FilePtr;
+static char *FileEnd;
+static qboolean SourceOpen;
+static char ASCIIToChrCode[256];
+static char TokenStringBuffer[MAX_QUOTED_LENGTH];
+static qboolean IncLineNumber;
+static char TempBuffer[2048];
+
+static struct
+{
+ char *name;
+ tokenType_t token;
+} Keywords[] =
+{
+ "model", TK_MODEL,
+ "mesh", TK_MESH,
+ "vertices", TK_VERTICES,
+ "edges", TK_EDGES,
+ "position", TK_POSITION,
+ "polygons", TK_POLYGONS,
+ "nodes", TK_NODES,
+ "rotation", TK_ROTATION,
+ "scaling", TK_SCALING,
+ "translation", TK_TRANSLATION,
+ "vertex", TK_VERTEX,
+ "HRCH", TK_HRCH,
+ "Softimage", TK_SOFTIMAGE,
+ "material", TK_MATERIAL,
+ "spline", TK_SPLINE,
+
+ "Named", TK_C_NAMED,
+ "object", TK_OBJECT,
+ "Tri", TK_C_TRI,
+ "Vertices", TK_C_VERTICES,
+ "Faces", TK_C_FACES,
+ "Vertex", TK_C_VERTEX,
+ "list", TK_LIST,
+ "Face", TK_C_FACE,
+
+ "Hexen", TK_C_HEXEN,
+ "Triangles", TK_C_TRIANGLES,
+ "Version", TK_C_VERSION,
+ "faces", TK_FACES,
+ "face", TK_FACE,
+ "origin", TK_ORIGIN,
+
+ "DK_clusters", TK_CLUSTERS,
+ "DK_cluster_ncvs", TK_NUM_CLUSTER_VERTICES,
+ "name", TK_NAME,
+ "DK_cluster_name", TK_CLUSTER_NAME,
+ "DK_cluster_state", TK_CLUSTER_STATE,
+
+ "actor_data", TK_ACTOR_DATA,
+ "uvTexture", TK_UVTEXTURE,
+
+ NULL, -1
+};
+
+static char *TokenNames[] =
+{
+ "<nothing>",
+ "<unknown_char>",
+ "<EOF>",
+ "<identifier>",
+ "<string>",
+ "<int_number>",
+ "<float_number>",
+ "(",
+ ")",
+ "{",
+ "}",
+ "[",
+ "]",
+ ":",
+ "mesh",
+ "model",
+ "nodes",
+ "rotation",
+ "scaling",
+ "translation",
+ "polygons",
+ "position",
+ "vertex",
+ "vertices",
+ "HRCH",
+ "Softimage"
+};
+
+// CODE --------------------------------------------------------------------
+
+//==========================================================================
+//
+// TK_Init
+//
+//==========================================================================
+
+void TK_Init(void)
+{
+ int i;
+
+ for(i = 0; i < 256; i++)
+ {
+ ASCIIToChrCode[i] = CHR_SPECIAL;
+ }
+ for(i = '0'; i <= '9'; i++)
+ {
+ ASCIIToChrCode[i] = CHR_NUMBER;
+ }
+ for(i = 'A'; i <= 'Z'; i++)
+ {
+ ASCIIToChrCode[i] = CHR_LETTER;
+ }
+ for(i = 'a'; i <= 'z'; i++)
+ {
+ ASCIIToChrCode[i] = CHR_LETTER;
+ }
+ ASCIIToChrCode[ASCII_QUOTE] = CHR_QUOTE;
+ ASCIIToChrCode[ASCII_UNDERSCORE] = CHR_LETTER;
+ ASCIIToChrCode[EOF_CHARACTER] = CHR_EOF;
+ tk_String = TokenStringBuffer;
+ IncLineNumber = FALSE;
+ SourceOpen = FALSE;
+}
+
+//==========================================================================
+//
+// TK_OpenSource
+//
+//==========================================================================
+
+void TK_OpenSource(char *fileName)
+{
+ int size;
+
+ TK_CloseSource();
+ size = LoadFile(fileName, (void **)&FileStart);
+ strcpy(tk_SourceName, fileName);
+ SourceOpen = TRUE;
+ FileEnd = FileStart+size;
+ FilePtr = FileStart;
+ tk_Line = 1;
+ tk_Token = TK_NONE;
+ NextChr();
+}
+
+//==========================================================================
+//
+// TK_CloseSource
+//
+//==========================================================================
+
+void TK_CloseSource(void)
+{
+ if(SourceOpen)
+ {
+ free(FileStart);
+ SourceOpen = FALSE;
+ }
+}
+
+//==========================================================================
+//
+// TK_Fetch
+//
+//==========================================================================
+
+tokenType_t TK_Fetch(void)
+{
+ while(Chr == ASCII_SPACE)
+ {
+ NextChr();
+ }
+ if(Chr == '-')
+ {
+ ProcessNumberToken();
+ }
+ else switch(ASCIIToChrCode[(byte)Chr])
+ {
+ case CHR_EOF:
+ tk_Token = TK_EOF;
+ break;
+ case CHR_LETTER:
+ ProcessLetterToken();
+ break;
+ case CHR_NUMBER:
+ ProcessNumberToken();
+ break;
+ case CHR_QUOTE:
+ ProcessQuoteToken();
+ break;
+ default:
+ ProcessSpecialToken();
+ break;
+ }
+ return tk_Token;
+}
+
+//==========================================================================
+//
+// TK_Require
+//
+//==========================================================================
+
+void TK_Require(tokenType_t tokType)
+{
+ if(tokType == TK_FLOATNUMBER && tk_Token == TK_INTNUMBER)
+ {
+ tk_FloatNumber = (float)tk_IntNumber;
+ tk_Token = TK_FLOATNUMBER;
+ return;
+ }
+ if(tk_Token != tokType)
+ {
+ Error("File '%s', line %d:\nExpected '%s', found '%s'.\n",
+ tk_SourceName, tk_Line, TokenNames[tokType],
+ TokenNames[tk_Token]);
+ }
+}
+
+void TK_FetchRequire(tokenType_t tokType)
+{
+ TK_Fetch();
+ TK_Require(tokType);
+}
+
+tokenType_t TK_RequireFetch(tokenType_t tokType)
+{
+ TK_Require(tokType);
+ return TK_Fetch();
+}
+
+tokenType_t TK_FetchRequireFetch(tokenType_t tokType)
+{
+ TK_Fetch();
+ TK_Require(tokType);
+ return TK_Fetch();
+}
+
+tokenType_t TK_Beyond(tokenType_t tokType)
+{
+ while(tk_Token != tokType)
+ {
+ if(TK_Fetch() == TK_EOF)
+ {
+ Error("File '%s':\nCould not find token '%s'.\n", // FIXME: TokenNames table not big enuff
+ tk_SourceName, TokenNames[tokType]);
+ }
+ }
+ return TK_Fetch();
+}
+
+void TK_BeyondRequire(tokenType_t bTok, tokenType_t rTok)
+{
+ TK_Beyond(bTok);
+ TK_Require(rTok);
+}
+
+tokenType_t TK_Search(tokenType_t tokType)
+{
+ while(tk_Token != tokType)
+ {
+ if(TK_Fetch() == TK_EOF)
+ {
+ return TK_EOF;
+ }
+ }
+ return TK_Fetch();
+}
+
+tokenType_t TK_Get(tokenType_t tokType)
+{
+ while(tk_Token != tokType)
+ {
+ if(TK_Fetch() == TK_EOF)
+ {
+ Error("File '%s':\nCould not find token '%s'.\n",
+ tk_SourceName, TokenNames[tokType]);
+ }
+ }
+ return tk_Token;
+}
+
+//==========================================================================
+//
+// ProcessLetterToken
+//
+//==========================================================================
+
+static void ProcessLetterToken(void)
+{
+ int i;
+ char *text;
+
+ i = 0;
+ text = TokenStringBuffer;
+ while(ASCIIToChrCode[(byte)Chr] == CHR_LETTER
+ || ASCIIToChrCode[(byte)Chr] == CHR_NUMBER)
+ {
+ if(++i == MAX_IDENTIFIER_LENGTH)
+ {
+ Error("File '%s', line %d:\nIdentifier too long.\n",
+ tk_SourceName, tk_Line);
+ }
+ *text++ = Chr;
+ NextChr();
+ }
+ *text = 0;
+ if(CheckForKeyword() == FALSE)
+ {
+ tk_Token = TK_IDENTIFIER;
+ }
+}
+
+//==========================================================================
+//
+// CheckForKeyword
+//
+//==========================================================================
+
+static qboolean CheckForKeyword(void)
+{
+ int i;
+
+ for(i = 0; Keywords[i].name != NULL; i++)
+ {
+ if(strcmp(tk_String, Keywords[i].name) == 0)
+ {
+ tk_Token = Keywords[i].token;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+//==========================================================================
+//
+// ProcessNumberToken
+//
+//==========================================================================
+
+static void ProcessNumberToken(void)
+{
+ char *buffer;
+
+ buffer = TempBuffer;
+ *buffer++ = Chr;
+ NextChr();
+ while(ASCIIToChrCode[(byte)Chr] == CHR_NUMBER)
+ {
+ *buffer++ = Chr;
+ NextChr();
+ }
+ if(Chr == '.')
+ { // Float
+ *buffer++ = Chr;
+ NextChr(); // Skip period
+ while(ASCIIToChrCode[(byte)Chr] == CHR_NUMBER)
+ {
+ *buffer++ = Chr;
+ NextChr();
+ }
+ *buffer = 0;
+ tk_FloatNumber = (float)atof(TempBuffer);
+ tk_Token = TK_FLOATNUMBER;
+ return;
+ }
+
+ // Integer
+ *buffer = 0;
+ tk_IntNumber = atoi(TempBuffer);
+ tk_Token = TK_INTNUMBER;
+}
+
+//==========================================================================
+//
+// ProcessQuoteToken
+//
+//==========================================================================
+
+static void ProcessQuoteToken(void)
+{
+ int i;
+ char *text;
+
+ i = 0;
+ text = TokenStringBuffer;
+ NextChr();
+ while(Chr != ASCII_QUOTE)
+ {
+ if(Chr == EOF_CHARACTER)
+ {
+ Error("File '%s', line %d:\n<EOF> inside string.\n",
+ tk_SourceName, tk_Line);
+ }
+ if(++i > MAX_QUOTED_LENGTH-1)
+ {
+ Error("File '%s', line %d:\nString literal too long.\n",
+ tk_SourceName, tk_Line);
+ }
+ *text++ = Chr;
+ NextChr();
+ }
+ *text = 0;
+ NextChr();
+ tk_Token = TK_STRING;
+}
+
+//==========================================================================
+//
+// ProcessSpecialToken
+//
+//==========================================================================
+
+static void ProcessSpecialToken(void)
+{
+ char c;
+
+ c = Chr;
+ NextChr();
+ switch(c)
+ {
+ case '(':
+ tk_Token = TK_LPAREN;
+ break;
+ case ')':
+ tk_Token = TK_RPAREN;
+ break;
+ case '{':
+ tk_Token = TK_LBRACE;
+ break;
+ case '}':
+ tk_Token = TK_RBRACE;
+ break;
+ case '[':
+ tk_Token = TK_LBRACKET;
+ break;
+ case ']':
+ tk_Token = TK_RBRACKET;
+ break;
+ case ':':
+ tk_Token = TK_COLON;
+ break;
+ default:
+ tk_Token = TK_UNKNOWNCHAR;
+ break;
+ }
+}
+
+//==========================================================================
+//
+// NextChr
+//
+//==========================================================================
+
+static void NextChr(void)
+{
+ if(FilePtr >= FileEnd)
+ {
+ Chr = EOF_CHARACTER;
+ return;
+ }
+ if(IncLineNumber == TRUE)
+ {
+ tk_Line++;
+ IncLineNumber = FALSE;
+ }
+ Chr = *FilePtr++;
+ if(Chr < ASCII_SPACE)
+ {
+ if(Chr == '\n')
+ {
+ IncLineNumber = TRUE;
+ }
+ Chr = ASCII_SPACE;
+ }
+}