2 Copyright (C) 1999-2006 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 //==========================================================================
171 void TK_Init( void ){
174 for ( i = 0; i < 256; i++ )
176 ASCIIToChrCode[i] = CHR_SPECIAL;
178 for ( i = '0'; i <= '9'; i++ )
180 ASCIIToChrCode[i] = CHR_NUMBER;
182 for ( i = 'A'; i <= 'Z'; i++ )
184 ASCIIToChrCode[i] = CHR_LETTER;
186 for ( i = 'a'; i <= 'z'; i++ )
188 ASCIIToChrCode[i] = CHR_LETTER;
190 ASCIIToChrCode[ASCII_QUOTE] = CHR_QUOTE;
191 ASCIIToChrCode[ASCII_UNDERSCORE] = CHR_LETTER;
192 ASCIIToChrCode[EOF_CHARACTER] = CHR_EOF;
193 tk_String = TokenStringBuffer;
194 IncLineNumber = FALSE;
198 //==========================================================================
202 //==========================================================================
204 void TK_OpenSource( char *fileName ){
208 size = LoadFile( fileName, (void **)&FileStart );
209 strcpy( tk_SourceName, fileName );
211 FileEnd = FileStart + size;
218 //==========================================================================
222 //==========================================================================
224 void TK_CloseSource( void ){
231 //==========================================================================
235 //==========================================================================
237 tokenType_t TK_Fetch( void ){
238 while ( Chr == ASCII_SPACE )
243 ProcessNumberToken();
245 else{switch ( ASCIIToChrCode[(byte)Chr] )
251 ProcessLetterToken();
254 ProcessNumberToken();
260 ProcessSpecialToken();
266 //==========================================================================
270 //==========================================================================
272 void TK_Require( tokenType_t tokType ){
273 if ( tokType == TK_FLOATNUMBER && tk_Token == TK_INTNUMBER ) {
274 tk_FloatNumber = (float)tk_IntNumber;
275 tk_Token = TK_FLOATNUMBER;
278 if ( tk_Token != tokType ) {
279 Error( "File '%s', line %d:\nExpected '%s', found '%s'.\n",
280 tk_SourceName, tk_Line, TokenNames[tokType],
281 TokenNames[tk_Token] );
285 void TK_FetchRequire( tokenType_t tokType ){
287 TK_Require( tokType );
290 tokenType_t TK_RequireFetch( tokenType_t tokType ){
291 TK_Require( tokType );
295 tokenType_t TK_FetchRequireFetch( tokenType_t tokType ){
297 TK_Require( tokType );
301 tokenType_t TK_Beyond( tokenType_t tokType ){
302 while ( tk_Token != tokType )
304 if ( TK_Fetch() == TK_EOF ) {
305 Error( "File '%s':\nCould not find token '%s'.\n", // FIXME: TokenNames table not big enuff
306 tk_SourceName, TokenNames[tokType] );
312 void TK_BeyondRequire( tokenType_t bTok, tokenType_t rTok ){
317 tokenType_t TK_Search( tokenType_t tokType ){
318 while ( tk_Token != tokType )
320 if ( TK_Fetch() == TK_EOF ) {
327 tokenType_t TK_Get( tokenType_t tokType ){
328 while ( tk_Token != tokType )
330 if ( TK_Fetch() == TK_EOF ) {
331 Error( "File '%s':\nCould not find token '%s'.\n",
332 tk_SourceName, TokenNames[tokType] );
338 //==========================================================================
340 // ProcessLetterToken
342 //==========================================================================
344 static void ProcessLetterToken( void ){
349 text = TokenStringBuffer;
350 while ( ASCIIToChrCode[(byte)Chr] == CHR_LETTER
351 || ASCIIToChrCode[(byte)Chr] == CHR_NUMBER )
353 if ( ++i == MAX_IDENTIFIER_LENGTH ) {
354 Error( "File '%s', line %d:\nIdentifier too long.\n",
355 tk_SourceName, tk_Line );
361 if ( CheckForKeyword() == FALSE ) {
362 tk_Token = TK_IDENTIFIER;
366 //==========================================================================
370 //==========================================================================
372 static qboolean CheckForKeyword( void ){
375 for ( i = 0; Keywords[i].name != NULL; i++ )
377 if ( strcmp( tk_String, Keywords[i].name ) == 0 ) {
378 tk_Token = Keywords[i].token;
385 //==========================================================================
387 // ProcessNumberToken
389 //==========================================================================
391 static void ProcessNumberToken( void ){
397 while ( ASCIIToChrCode[(byte)Chr] == CHR_NUMBER )
402 if ( Chr == '.' ) { // Float
404 NextChr(); // Skip period
405 while ( ASCIIToChrCode[(byte)Chr] == CHR_NUMBER )
411 tk_FloatNumber = (float)atof( TempBuffer );
412 tk_Token = TK_FLOATNUMBER;
418 tk_IntNumber = atoi( TempBuffer );
419 tk_Token = TK_INTNUMBER;
422 //==========================================================================
426 //==========================================================================
428 static void ProcessQuoteToken( void ){
433 text = TokenStringBuffer;
435 while ( Chr != ASCII_QUOTE )
437 if ( Chr == EOF_CHARACTER ) {
438 Error( "File '%s', line %d:\n<EOF> inside string.\n",
439 tk_SourceName, tk_Line );
441 if ( ++i > MAX_QUOTED_LENGTH - 1 ) {
442 Error( "File '%s', line %d:\nString literal too long.\n",
443 tk_SourceName, tk_Line );
450 tk_Token = TK_STRING;
453 //==========================================================================
455 // ProcessSpecialToken
457 //==========================================================================
459 static void ProcessSpecialToken( void ){
467 tk_Token = TK_LPAREN;
470 tk_Token = TK_RPAREN;
473 tk_Token = TK_LBRACE;
476 tk_Token = TK_RBRACE;
479 tk_Token = TK_LBRACKET;
482 tk_Token = TK_RBRACKET;
488 tk_Token = TK_UNKNOWNCHAR;
493 //==========================================================================
497 //==========================================================================
499 static void NextChr( void ){
500 if ( FilePtr >= FileEnd ) {
504 if ( IncLineNumber == TRUE ) {
506 IncLineNumber = FALSE;
509 if ( Chr < ASCII_SPACE ) {
511 IncLineNumber = TRUE;