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