]> git.xonotic.org Git - xonotic/netradiant.git/blobdiff - tools/quake2/qdata_heretic2/common/token.c
transfer from internal tree r5311 branches/1.4-gpl
[xonotic/netradiant.git] / tools / quake2 / qdata_heretic2 / common / token.c
diff --git a/tools/quake2/qdata_heretic2/common/token.c b/tools/quake2/qdata_heretic2/common/token.c
new file mode 100644 (file)
index 0000000..7fe8871
--- /dev/null
@@ -0,0 +1,550 @@
+/*\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