2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
\r
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
\r
5 This file is part of GtkRadiant.
\r
7 GtkRadiant is free software; you can redistribute it and/or modify
\r
8 it under the terms of the GNU General Public License as published by
\r
9 the Free Software Foundation; either version 2 of the License, or
\r
10 (at your option) any later version.
\r
12 GtkRadiant is distributed in the hope that it will be useful,
\r
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
15 GNU General Public License for more details.
\r
17 You should have received a copy of the GNU General Public License
\r
18 along with GtkRadiant; if not, write to the Free Software
\r
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\r
23 //**************************************************************************
\r
27 //**************************************************************************
\r
29 // HEADER FILES ------------------------------------------------------------
\r
34 // MACROS ------------------------------------------------------------------
\r
36 // TYPES -------------------------------------------------------------------
\r
47 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
\r
49 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
\r
51 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
\r
53 static void ProcessLetterToken(void);
\r
54 static void ProcessNumberToken(void);
\r
55 static void ProcessQuoteToken(void);
\r
56 static void ProcessSpecialToken(void);
\r
57 static qboolean CheckForKeyword(void);
\r
58 static void NextChr(void);
\r
60 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
\r
62 // PUBLIC DATA DEFINITIONS -------------------------------------------------
\r
64 tokenType_t tk_Token;
\r
67 float tk_FloatNumber;
\r
69 char tk_SourceName[MAX_FILE_NAME_LENGTH];
\r
71 // PRIVATE DATA DEFINITIONS ------------------------------------------------
\r
74 static char *FileStart;
\r
75 static char *FilePtr;
\r
76 static char *FileEnd;
\r
77 static qboolean SourceOpen;
\r
78 static char ASCIIToChrCode[256];
\r
79 static char TokenStringBuffer[MAX_QUOTED_LENGTH];
\r
80 static qboolean IncLineNumber;
\r
81 static char TempBuffer[2048];
\r
91 "vertices", TK_VERTICES,
\r
93 "position", TK_POSITION,
\r
94 "polygons", TK_POLYGONS,
\r
96 "rotation", TK_ROTATION,
\r
97 "scaling", TK_SCALING,
\r
98 "translation", TK_TRANSLATION,
\r
99 "vertex", TK_VERTEX,
\r
101 "Softimage", TK_SOFTIMAGE,
\r
102 "material", TK_MATERIAL,
\r
103 "spline", TK_SPLINE,
\r
105 "Named", TK_C_NAMED,
\r
106 "object", TK_OBJECT,
\r
108 "Vertices", TK_C_VERTICES,
\r
109 "Faces", TK_C_FACES,
\r
110 "Vertex", TK_C_VERTEX,
\r
114 "Hexen", TK_C_HEXEN,
\r
115 "Triangles", TK_C_TRIANGLES,
\r
116 "Version", TK_C_VERSION,
\r
119 "origin", TK_ORIGIN,
\r
121 "DK_clusters", TK_CLUSTERS,
\r
122 "DK_cluster_ncvs", TK_NUM_CLUSTER_VERTICES,
\r
124 "DK_cluster_name", TK_CLUSTER_NAME,
\r
125 "DK_cluster_state", TK_CLUSTER_STATE,
\r
127 "actor_data", TK_ACTOR_DATA,
\r
128 "uvTexture", TK_UVTEXTURE,
\r
133 static char *TokenNames[] =
\r
163 // CODE --------------------------------------------------------------------
\r
165 //==========================================================================
\r
169 //==========================================================================
\r
175 for(i = 0; i < 256; i++)
\r
177 ASCIIToChrCode[i] = CHR_SPECIAL;
\r
179 for(i = '0'; i <= '9'; i++)
\r
181 ASCIIToChrCode[i] = CHR_NUMBER;
\r
183 for(i = 'A'; i <= 'Z'; i++)
\r
185 ASCIIToChrCode[i] = CHR_LETTER;
\r
187 for(i = 'a'; i <= 'z'; i++)
\r
189 ASCIIToChrCode[i] = CHR_LETTER;
\r
191 ASCIIToChrCode[ASCII_QUOTE] = CHR_QUOTE;
\r
192 ASCIIToChrCode[ASCII_UNDERSCORE] = CHR_LETTER;
\r
193 ASCIIToChrCode[EOF_CHARACTER] = CHR_EOF;
\r
194 tk_String = TokenStringBuffer;
\r
195 IncLineNumber = FALSE;
\r
196 SourceOpen = FALSE;
\r
199 //==========================================================================
\r
203 //==========================================================================
\r
205 void TK_OpenSource(char *fileName)
\r
210 size = LoadFile(fileName, (void **)&FileStart);
\r
211 strcpy(tk_SourceName, fileName);
\r
213 FileEnd = FileStart+size;
\r
214 FilePtr = FileStart;
\r
216 tk_Token = TK_NONE;
\r
220 //==========================================================================
\r
224 //==========================================================================
\r
226 void TK_CloseSource(void)
\r
231 SourceOpen = FALSE;
\r
235 //==========================================================================
\r
239 //==========================================================================
\r
241 tokenType_t TK_Fetch(void)
\r
243 while(Chr == ASCII_SPACE)
\r
249 ProcessNumberToken();
\r
251 else switch(ASCIIToChrCode[(byte)Chr])
\r
257 ProcessLetterToken();
\r
260 ProcessNumberToken();
\r
263 ProcessQuoteToken();
\r
266 ProcessSpecialToken();
\r
272 //==========================================================================
\r
276 //==========================================================================
\r
278 void TK_Require(tokenType_t tokType)
\r
280 if(tokType == TK_FLOATNUMBER && tk_Token == TK_INTNUMBER)
\r
282 tk_FloatNumber = (float)tk_IntNumber;
\r
283 tk_Token = TK_FLOATNUMBER;
\r
286 if(tk_Token != tokType)
\r
288 Error("File '%s', line %d:\nExpected '%s', found '%s'.\n",
\r
289 tk_SourceName, tk_Line, TokenNames[tokType],
\r
290 TokenNames[tk_Token]);
\r
294 void TK_FetchRequire(tokenType_t tokType)
\r
297 TK_Require(tokType);
\r
300 tokenType_t TK_RequireFetch(tokenType_t tokType)
\r
302 TK_Require(tokType);
\r
306 tokenType_t TK_FetchRequireFetch(tokenType_t tokType)
\r
309 TK_Require(tokType);
\r
313 tokenType_t TK_Beyond(tokenType_t tokType)
\r
315 while(tk_Token != tokType)
\r
317 if(TK_Fetch() == TK_EOF)
\r
319 Error("File '%s':\nCould not find token '%s'.\n", // FIXME: TokenNames table not big enuff
\r
320 tk_SourceName, TokenNames[tokType]);
\r
326 void TK_BeyondRequire(tokenType_t bTok, tokenType_t rTok)
\r
332 tokenType_t TK_Search(tokenType_t tokType)
\r
334 while(tk_Token != tokType)
\r
336 if(TK_Fetch() == TK_EOF)
\r
344 tokenType_t TK_Get(tokenType_t tokType)
\r
346 while(tk_Token != tokType)
\r
348 if(TK_Fetch() == TK_EOF)
\r
350 Error("File '%s':\nCould not find token '%s'.\n",
\r
351 tk_SourceName, TokenNames[tokType]);
\r
357 //==========================================================================
\r
359 // ProcessLetterToken
\r
361 //==========================================================================
\r
363 static void ProcessLetterToken(void)
\r
369 text = TokenStringBuffer;
\r
370 while(ASCIIToChrCode[(byte)Chr] == CHR_LETTER
\r
371 || ASCIIToChrCode[(byte)Chr] == CHR_NUMBER)
\r
373 if(++i == MAX_IDENTIFIER_LENGTH)
\r
375 Error("File '%s', line %d:\nIdentifier too long.\n",
\r
376 tk_SourceName, tk_Line);
\r
382 if(CheckForKeyword() == FALSE)
\r
384 tk_Token = TK_IDENTIFIER;
\r
388 //==========================================================================
\r
392 //==========================================================================
\r
394 static qboolean CheckForKeyword(void)
\r
398 for(i = 0; Keywords[i].name != NULL; i++)
\r
400 if(strcmp(tk_String, Keywords[i].name) == 0)
\r
402 tk_Token = Keywords[i].token;
\r
409 //==========================================================================
\r
411 // ProcessNumberToken
\r
413 //==========================================================================
\r
415 static void ProcessNumberToken(void)
\r
419 buffer = TempBuffer;
\r
422 while(ASCIIToChrCode[(byte)Chr] == CHR_NUMBER)
\r
430 NextChr(); // Skip period
\r
431 while(ASCIIToChrCode[(byte)Chr] == CHR_NUMBER)
\r
437 tk_FloatNumber = (float)atof(TempBuffer);
\r
438 tk_Token = TK_FLOATNUMBER;
\r
444 tk_IntNumber = atoi(TempBuffer);
\r
445 tk_Token = TK_INTNUMBER;
\r
448 //==========================================================================
\r
450 // ProcessQuoteToken
\r
452 //==========================================================================
\r
454 static void ProcessQuoteToken(void)
\r
460 text = TokenStringBuffer;
\r
462 while(Chr != ASCII_QUOTE)
\r
464 if(Chr == EOF_CHARACTER)
\r
466 Error("File '%s', line %d:\n<EOF> inside string.\n",
\r
467 tk_SourceName, tk_Line);
\r
469 if(++i > MAX_QUOTED_LENGTH-1)
\r
471 Error("File '%s', line %d:\nString literal too long.\n",
\r
472 tk_SourceName, tk_Line);
\r
479 tk_Token = TK_STRING;
\r
482 //==========================================================================
\r
484 // ProcessSpecialToken
\r
486 //==========================================================================
\r
488 static void ProcessSpecialToken(void)
\r
497 tk_Token = TK_LPAREN;
\r
500 tk_Token = TK_RPAREN;
\r
503 tk_Token = TK_LBRACE;
\r
506 tk_Token = TK_RBRACE;
\r
509 tk_Token = TK_LBRACKET;
\r
512 tk_Token = TK_RBRACKET;
\r
515 tk_Token = TK_COLON;
\r
518 tk_Token = TK_UNKNOWNCHAR;
\r
523 //==========================================================================
\r
527 //==========================================================================
\r
529 static void NextChr(void)
\r
531 if(FilePtr >= FileEnd)
\r
533 Chr = EOF_CHARACTER;
\r
536 if(IncLineNumber == TRUE)
\r
539 IncLineNumber = FALSE;
\r
542 if(Chr < ASCII_SPACE)
\r
546 IncLineNumber = TRUE;
\r