]> de.git.xonotic.org Git - voretournament/voretournament.git/blob - misc/mediasource/extra/netradiant-src/tools/quake2/qdata_heretic2/common/token.c
Include netRadiant source in this GIT
[voretournament/voretournament.git] / misc / mediasource / extra / netradiant-src / tools / quake2 / qdata_heretic2 / common / token.c
1 /*
2 Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5 This file is part of GtkRadiant.
6
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.
11
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.
16
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
20 */
21
22
23 //**************************************************************************
24 //**
25 //** token.c
26 //**
27 //**************************************************************************
28
29 // HEADER FILES ------------------------------------------------------------
30
31 #include "token.h"
32 #include "inout.h"
33
34 // MACROS ------------------------------------------------------------------
35
36 // TYPES -------------------------------------------------------------------
37
38 typedef enum
39 {
40         CHR_EOF,
41         CHR_LETTER,
42         CHR_NUMBER,
43         CHR_QUOTE,
44         CHR_SPECIAL
45 } chr_t;
46
47 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
48
49 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
50
51 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
52
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);
59
60 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
61
62 // PUBLIC DATA DEFINITIONS -------------------------------------------------
63
64 tokenType_t tk_Token;
65 int tk_Line;
66 int tk_IntNumber;
67 float tk_FloatNumber;
68 char *tk_String;
69 char tk_SourceName[MAX_FILE_NAME_LENGTH];
70
71 // PRIVATE DATA DEFINITIONS ------------------------------------------------
72
73 static char Chr;
74 static char *FileStart;
75 static char *FilePtr;
76 static char *FileEnd;
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];
82
83 static struct
84 {
85         char *name;
86         tokenType_t token;
87 } Keywords[] =
88 {
89         "model",                        TK_MODEL,
90         "mesh",                         TK_MESH,
91         "vertices",                     TK_VERTICES,
92         "edges",                        TK_EDGES,
93         "position",                     TK_POSITION,
94         "polygons",                     TK_POLYGONS,
95         "nodes",                        TK_NODES,
96         "rotation",                     TK_ROTATION,
97         "scaling",                      TK_SCALING,
98         "translation",          TK_TRANSLATION,
99         "vertex",                       TK_VERTEX,
100         "HRCH",                         TK_HRCH,
101         "Softimage",            TK_SOFTIMAGE,
102         "material",                     TK_MATERIAL,
103         "spline",                       TK_SPLINE,
104
105         "Named",                        TK_C_NAMED,
106         "object",                       TK_OBJECT,
107         "Tri",                          TK_C_TRI,
108         "Vertices",                     TK_C_VERTICES,
109         "Faces",                        TK_C_FACES,
110         "Vertex",                       TK_C_VERTEX,
111         "list",                         TK_LIST,
112         "Face",                         TK_C_FACE,
113
114         "Hexen",                        TK_C_HEXEN,
115         "Triangles",            TK_C_TRIANGLES,
116         "Version",                      TK_C_VERSION,
117         "faces",                        TK_FACES,
118         "face",                         TK_FACE,
119         "origin",                       TK_ORIGIN,
120
121         "DK_clusters",          TK_CLUSTERS,
122         "DK_cluster_ncvs",      TK_NUM_CLUSTER_VERTICES,
123         "name",                         TK_NAME,
124         "DK_cluster_name",      TK_CLUSTER_NAME,
125         "DK_cluster_state",     TK_CLUSTER_STATE,
126
127         "actor_data",           TK_ACTOR_DATA,
128         "uvTexture",            TK_UVTEXTURE,
129
130         NULL,                           -1
131 };
132
133 static char *TokenNames[] =
134 {
135         "<nothing>",
136         "<unknown_char>",
137         "<EOF>",
138         "<identifier>",
139         "<string>",
140         "<int_number>",
141         "<float_number>",
142         "(",
143         ")",
144         "{",
145         "}",
146         "[",
147         "]",
148         ":",
149         "mesh",
150         "model",
151         "nodes",
152         "rotation",
153         "scaling",
154         "translation",
155         "polygons",
156         "position",
157         "vertex",
158         "vertices",
159         "HRCH",
160         "Softimage"
161 };
162
163 // CODE --------------------------------------------------------------------
164
165 //==========================================================================
166 //
167 // TK_Init
168 //
169 //==========================================================================
170
171 void TK_Init(void)
172 {
173         int i;
174
175         for(i = 0; i < 256; i++)
176         {
177                 ASCIIToChrCode[i] = CHR_SPECIAL;
178         }
179         for(i = '0'; i <= '9'; i++)
180         {
181                 ASCIIToChrCode[i] = CHR_NUMBER;
182         }
183         for(i = 'A'; i <= 'Z'; i++)
184         {
185                 ASCIIToChrCode[i] = CHR_LETTER;
186         }
187         for(i = 'a'; i <= 'z'; i++)
188         {
189                 ASCIIToChrCode[i] = CHR_LETTER;
190         }
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;
196         SourceOpen = FALSE;
197 }
198
199 //==========================================================================
200 //
201 // TK_OpenSource
202 //
203 //==========================================================================
204
205 void TK_OpenSource(char *fileName)
206 {
207         int size;
208
209         TK_CloseSource();
210         size = LoadFile(fileName, (void **)&FileStart);
211         strcpy(tk_SourceName, fileName);
212         SourceOpen = TRUE;
213         FileEnd = FileStart+size;
214         FilePtr = FileStart;
215         tk_Line = 1;
216         tk_Token = TK_NONE;
217         NextChr();
218 }
219
220 //==========================================================================
221 //
222 // TK_CloseSource
223 //
224 //==========================================================================
225
226 void TK_CloseSource(void)
227 {
228         if(SourceOpen)
229         {
230                 free(FileStart);
231                 SourceOpen = FALSE;
232         }
233 }
234
235 //==========================================================================
236 //
237 // TK_Fetch
238 //
239 //==========================================================================
240
241 tokenType_t TK_Fetch(void)
242 {
243         while(Chr == ASCII_SPACE)
244         {
245                 NextChr();
246         }
247         if(Chr == '-')
248         {
249                 ProcessNumberToken();
250         }
251         else switch(ASCIIToChrCode[(byte)Chr])
252         {
253                 case CHR_EOF:
254                         tk_Token = TK_EOF;
255                         break;
256                 case CHR_LETTER:
257                         ProcessLetterToken();
258                         break;
259                 case CHR_NUMBER:
260                         ProcessNumberToken();
261                         break;
262                 case CHR_QUOTE:
263                         ProcessQuoteToken();
264                         break;
265                 default:
266                         ProcessSpecialToken();
267                         break;
268         }
269         return tk_Token;
270 }
271
272 //==========================================================================
273 //
274 // TK_Require
275 //
276 //==========================================================================
277
278 void TK_Require(tokenType_t tokType)
279 {
280         if(tokType == TK_FLOATNUMBER && tk_Token == TK_INTNUMBER)
281         {
282                 tk_FloatNumber = (float)tk_IntNumber;
283                 tk_Token = TK_FLOATNUMBER;
284                 return;
285         }
286         if(tk_Token != tokType)
287         {
288                 Error("File '%s', line %d:\nExpected '%s', found '%s'.\n",
289                         tk_SourceName, tk_Line, TokenNames[tokType],
290                         TokenNames[tk_Token]);
291         }
292 }
293
294 void TK_FetchRequire(tokenType_t tokType)
295 {
296         TK_Fetch();
297         TK_Require(tokType);
298 }
299
300 tokenType_t TK_RequireFetch(tokenType_t tokType)
301 {
302         TK_Require(tokType);
303         return TK_Fetch();
304 }
305
306 tokenType_t TK_FetchRequireFetch(tokenType_t tokType)
307 {
308         TK_Fetch();
309         TK_Require(tokType);
310         return TK_Fetch();
311 }
312
313 tokenType_t TK_Beyond(tokenType_t tokType)
314 {
315         while(tk_Token != tokType)
316         {
317                 if(TK_Fetch() == TK_EOF)
318                 {
319                         Error("File '%s':\nCould not find token '%s'.\n",               // FIXME: TokenNames table not big enuff 
320                                 tk_SourceName, TokenNames[tokType]);
321                 }
322         }
323         return TK_Fetch();
324 }
325
326 void TK_BeyondRequire(tokenType_t bTok, tokenType_t rTok)
327 {
328         TK_Beyond(bTok);
329         TK_Require(rTok);
330 }
331
332 tokenType_t TK_Search(tokenType_t tokType)
333 {
334         while(tk_Token != tokType)
335         {
336                 if(TK_Fetch() == TK_EOF)
337                 {
338                         return TK_EOF;
339                 }
340         }
341         return TK_Fetch();
342 }
343
344 tokenType_t TK_Get(tokenType_t tokType)
345 {
346         while(tk_Token != tokType)
347         {
348                 if(TK_Fetch() == TK_EOF)
349                 {
350                         Error("File '%s':\nCould not find token '%s'.\n",
351                                 tk_SourceName, TokenNames[tokType]);
352                 }
353         }
354         return tk_Token;
355 }
356
357 //==========================================================================
358 //
359 // ProcessLetterToken
360 //
361 //==========================================================================
362
363 static void ProcessLetterToken(void)
364 {
365         int i;
366         char *text;
367
368         i = 0;
369         text = TokenStringBuffer;
370         while(ASCIIToChrCode[(byte)Chr] == CHR_LETTER
371                 || ASCIIToChrCode[(byte)Chr] == CHR_NUMBER)
372         {
373                 if(++i == MAX_IDENTIFIER_LENGTH)
374                 {
375                         Error("File '%s', line %d:\nIdentifier too long.\n",
376                                 tk_SourceName, tk_Line);
377                 }
378                 *text++ = Chr;
379                 NextChr();
380         }
381         *text = 0;
382         if(CheckForKeyword() == FALSE)
383         {
384                 tk_Token = TK_IDENTIFIER;
385         }
386 }
387
388 //==========================================================================
389 //
390 // CheckForKeyword
391 //
392 //==========================================================================
393
394 static qboolean CheckForKeyword(void)
395 {
396         int i;
397
398         for(i = 0; Keywords[i].name != NULL; i++)
399         {
400                 if(strcmp(tk_String, Keywords[i].name) == 0)
401                 {
402                         tk_Token = Keywords[i].token;
403                         return TRUE;
404                 }
405         }
406         return FALSE;
407 }
408
409 //==========================================================================
410 //
411 // ProcessNumberToken
412 //
413 //==========================================================================
414
415 static void ProcessNumberToken(void)
416 {
417         char *buffer;
418
419         buffer = TempBuffer;
420         *buffer++ = Chr;
421         NextChr();
422         while(ASCIIToChrCode[(byte)Chr] == CHR_NUMBER)
423         {
424                 *buffer++ = Chr;
425                 NextChr();
426         }
427         if(Chr == '.')
428         { // Float
429                 *buffer++ = Chr;
430                 NextChr(); // Skip period
431                 while(ASCIIToChrCode[(byte)Chr] == CHR_NUMBER)
432                 {
433                         *buffer++ = Chr;
434                         NextChr();
435                 }
436                 *buffer = 0;
437                 tk_FloatNumber = (float)atof(TempBuffer);
438                 tk_Token = TK_FLOATNUMBER;
439                 return;
440         }
441
442         // Integer
443         *buffer = 0;
444         tk_IntNumber = atoi(TempBuffer);
445         tk_Token = TK_INTNUMBER;
446 }
447
448 //==========================================================================
449 //
450 // ProcessQuoteToken
451 //
452 //==========================================================================
453
454 static void ProcessQuoteToken(void)
455 {
456         int i;
457         char *text;
458
459         i = 0;
460         text = TokenStringBuffer;
461         NextChr();
462         while(Chr != ASCII_QUOTE)
463         {
464                 if(Chr == EOF_CHARACTER)
465                 {
466                         Error("File '%s', line %d:\n<EOF> inside string.\n",
467                                 tk_SourceName, tk_Line);
468                 }
469                 if(++i > MAX_QUOTED_LENGTH-1)
470                 {
471                         Error("File '%s', line %d:\nString literal too long.\n",
472                                 tk_SourceName, tk_Line);
473                 }
474                 *text++ = Chr;
475                 NextChr();
476         }
477         *text = 0;
478         NextChr();
479         tk_Token = TK_STRING;
480 }
481
482 //==========================================================================
483 //
484 // ProcessSpecialToken
485 //
486 //==========================================================================
487
488 static void ProcessSpecialToken(void)
489 {
490         char c;
491
492         c = Chr;
493         NextChr();
494         switch(c)
495         {
496                 case '(':
497                         tk_Token = TK_LPAREN;
498                         break;
499                 case ')':
500                         tk_Token = TK_RPAREN;
501                         break;
502                 case '{':
503                         tk_Token = TK_LBRACE;
504                         break;
505                 case '}':
506                         tk_Token = TK_RBRACE;
507                         break;
508                 case '[':
509                         tk_Token = TK_LBRACKET;
510                         break;
511                 case ']':
512                         tk_Token = TK_RBRACKET;
513                         break;
514                 case ':':
515                         tk_Token = TK_COLON;
516                         break;
517                 default:
518                         tk_Token = TK_UNKNOWNCHAR;
519                         break;
520         }
521 }
522
523 //==========================================================================
524 //
525 // NextChr
526 //
527 //==========================================================================
528
529 static void NextChr(void)
530 {
531         if(FilePtr >= FileEnd)
532         {
533                 Chr = EOF_CHARACTER;
534                 return;
535         }
536         if(IncLineNumber == TRUE)
537         {
538                 tk_Line++;
539                 IncLineNumber = FALSE;
540         }
541         Chr = *FilePtr++;
542         if(Chr < ASCII_SPACE)
543         {
544                 if(Chr == '\n')
545                 {
546                         IncLineNumber = TRUE;
547                 }
548                 Chr = ASCII_SPACE;
549         }
550 }