]> icculus.org git repositories - theoddone33/hhexen.git/blob - base/sc_man.c
osezer patch 003
[theoddone33/hhexen.git] / base / sc_man.c
1
2 //**************************************************************************
3 //**
4 //** sc_man.c : Heretic 2 : Raven Software, Corp.
5 //**
6 //** $RCSfile$
7 //** $Revision$
8 //** $Date$
9 //** $Author$
10 //**
11 //**************************************************************************
12
13 // HEADER FILES ------------------------------------------------------------
14
15 #include <string.h>
16 #include <stdlib.h>
17 #include "h2def.h"
18
19 // MACROS ------------------------------------------------------------------
20
21 #define MAX_STRING_SIZE 64
22 #define ASCII_COMMENT (';')
23 #define ASCII_QUOTE (34)
24 #define LUMP_SCRIPT 1
25 #define FILE_ZONE_SCRIPT 2
26 #define FILE_CLIB_SCRIPT 3
27
28 // TYPES -------------------------------------------------------------------
29
30 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
31
32 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
33
34 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
35
36 static void CheckOpen(void);
37 static void OpenScript(char *name, int type);
38
39 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
40
41 // PUBLIC DATA DEFINITIONS -------------------------------------------------
42
43 char *sc_String;
44 int sc_Number;
45 int sc_Line;
46 boolean sc_End;
47 boolean sc_Crossed;
48 boolean sc_FileScripts = false;
49 char *sc_ScriptsDir = "";
50
51 // PRIVATE DATA DEFINITIONS ------------------------------------------------
52
53 static char ScriptName[16];
54 static char *ScriptBuffer;
55 static char *ScriptPtr;
56 static char *ScriptEndPtr;
57 static char StringBuffer[MAX_STRING_SIZE];
58 static boolean ScriptOpen = false;
59 static boolean ScriptFreeCLib; // true = de-allocate using free()
60 static int ScriptSize;
61 static boolean AlreadyGot = false;
62
63 // CODE --------------------------------------------------------------------
64
65 //==========================================================================
66 //
67 // SC_Open
68 //
69 //==========================================================================
70
71 void SC_Open(char *name)
72 {
73         char fileName[128];
74
75         if(sc_FileScripts == true)
76         {
77                 sprintf(fileName, "%s%s.txt", sc_ScriptsDir, name);
78                 SC_OpenFile(fileName);
79         }
80         else
81         {
82                 SC_OpenLump(name);
83         }
84 }
85
86 //==========================================================================
87 //
88 // SC_OpenLump
89 //
90 // Loads a script (from the WAD files) and prepares it for parsing.
91 //
92 //==========================================================================
93
94 void SC_OpenLump(char *name)
95 {
96         OpenScript(name, LUMP_SCRIPT);
97 }
98
99 //==========================================================================
100 //
101 // SC_OpenFile
102 //
103 // Loads a script (from a file) and prepares it for parsing.  Uses the
104 // zone memory allocator for memory allocation and de-allocation.
105 //
106 //==========================================================================
107
108 void SC_OpenFile(char *name)
109 {
110         OpenScript(name, FILE_ZONE_SCRIPT);
111 }
112
113 //==========================================================================
114 //
115 // SC_OpenFileCLib
116 //
117 // Loads a script (from a file) and prepares it for parsing.  Uses C
118 // library function calls for memory allocation and de-allocation.
119 //
120 //==========================================================================
121
122 void SC_OpenFileCLib(char *name)
123 {
124         OpenScript(name, FILE_CLIB_SCRIPT);
125 }
126
127 //==========================================================================
128 //
129 // OpenScript
130 //
131 //==========================================================================
132
133 static void OpenScript(char *name, int type)
134 {
135         SC_Close();
136         if(type == LUMP_SCRIPT)
137         { // Lump script
138                 ScriptBuffer = (char *)W_CacheLumpName(name, PU_STATIC);
139                 ScriptSize = W_LumpLength(W_GetNumForName(name));
140                 strcpy(ScriptName, name);
141                 ScriptFreeCLib = false; // De-allocate using Z_Free()
142         }
143         else if(type == FILE_ZONE_SCRIPT)
144         { // File script - zone
145                 ScriptSize = M_ReadFile(name, (byte **)&ScriptBuffer);
146                 M_ExtractFileBase(name, ScriptName);
147                 ScriptFreeCLib = false; // De-allocate using Z_Free()
148         }
149         else
150         { // File script - clib
151                 ScriptSize = M_ReadFileCLib(name, (byte **)&ScriptBuffer);
152                 M_ExtractFileBase(name, ScriptName);
153                 ScriptFreeCLib = true; // De-allocate using free()
154         }
155         ScriptPtr = ScriptBuffer;
156         ScriptEndPtr = ScriptPtr+ScriptSize;
157         sc_Line = 1;
158         sc_End = false;
159         ScriptOpen = true;
160         sc_String = StringBuffer;
161         AlreadyGot = false;
162 }
163
164 //==========================================================================
165 //
166 // SC_Close
167 //
168 //==========================================================================
169
170 void SC_Close(void)
171 {
172         if(ScriptOpen)
173         {
174                 if(ScriptFreeCLib == true)
175                 {
176                         free(ScriptBuffer);
177                 }
178                 else
179                 {
180                         Z_Free(ScriptBuffer);
181                 }
182                 ScriptOpen = false;
183         }
184 }
185
186 //==========================================================================
187 //
188 // SC_GetString
189 //
190 //==========================================================================
191
192 boolean SC_GetString(void)
193 {
194         char *text;
195         boolean foundToken;
196
197         CheckOpen();
198         if(AlreadyGot)
199         {
200                 AlreadyGot = false;
201                 return true;
202         }
203         foundToken = false;
204         sc_Crossed = false;
205         if(ScriptPtr >= ScriptEndPtr)
206         {
207                 sc_End = true;
208                 return false;
209         }
210         while(foundToken == false)
211         {
212                 while(*ScriptPtr <= 32)
213                 {
214                         if(ScriptPtr >= ScriptEndPtr)
215                         {
216                                 sc_End = true;
217                                 return false;
218                         }
219                         if(*ScriptPtr++ == '\n')
220                         {
221                                 sc_Line++;
222                                 sc_Crossed = true;
223                         }
224                 }
225                 if(ScriptPtr >= ScriptEndPtr)
226                 {
227                         sc_End = true;
228                         return false;
229                 }
230                 if(*ScriptPtr != ASCII_COMMENT)
231                 { // Found a token
232                         foundToken = true;
233                 }
234                 else
235                 { // Skip comment
236                         while(*ScriptPtr++ != '\n')
237                         {
238                                 if(ScriptPtr >= ScriptEndPtr)
239                                 {
240                                         sc_End = true;
241                                         return false;
242         
243                         }
244                         }
245                         sc_Line++;
246                         sc_Crossed = true;
247                 }
248         }
249         text = sc_String;
250         if(*ScriptPtr == ASCII_QUOTE)
251         { // Quoted string
252                 ScriptPtr++;
253                 while(*ScriptPtr != ASCII_QUOTE)
254                 {
255                         *text++ = *ScriptPtr++;
256                         if(ScriptPtr == ScriptEndPtr
257                                 || text == &sc_String[MAX_STRING_SIZE-1])
258                         {
259                                 break;
260                         }
261                 }
262                 ScriptPtr++;
263         }
264         else
265         { // Normal string
266                 while((*ScriptPtr > 32) && (*ScriptPtr != ASCII_COMMENT))
267                 {
268                         *text++ = *ScriptPtr++;
269                         if(ScriptPtr == ScriptEndPtr
270                                 || text == &sc_String[MAX_STRING_SIZE-1])
271                         {
272                                 break;
273                         }
274                 }
275         }
276         *text = 0;
277         return true;
278 }
279
280 //==========================================================================
281 //
282 // SC_MustGetString
283 //
284 //==========================================================================
285
286 void SC_MustGetString(void)
287 {
288         if(SC_GetString() == false)
289         {
290                 SC_ScriptError("Missing string.");
291         }
292 }
293
294 //==========================================================================
295 //
296 // SC_MustGetStringName
297 //
298 //==========================================================================
299
300 void SC_MustGetStringName(char *name)
301 {
302         SC_MustGetString();
303         if(SC_Compare(name) == false)
304         {
305                 SC_ScriptError(NULL);
306         }
307 }
308
309 //==========================================================================
310 //
311 // SC_GetNumber
312 //
313 //==========================================================================
314
315 boolean SC_GetNumber(void)
316 {
317         char *stopper;
318
319         CheckOpen();
320         if(SC_GetString())
321         {
322                 sc_Number = strtol(sc_String, &stopper, 0);
323                 if(*stopper != 0)
324                 {
325                         I_Error("SC_GetNumber: Bad numeric constant \"%s\".\n"
326                                 "Script %s, Line %d", sc_String, ScriptName, sc_Line);
327                 }
328                 return true;
329         }
330         else
331         {
332                 return false;
333         }
334 }
335
336 //==========================================================================
337 //
338 // SC_MustGetNumber
339 //
340 //==========================================================================
341
342 void SC_MustGetNumber(void)
343 {
344         if(SC_GetNumber() == false)
345         {
346                 SC_ScriptError("Missing integer.");
347         }
348 }
349
350 //==========================================================================
351 //
352 // SC_UnGet
353 //
354 // Assumes there is a valid string in sc_String.
355 //
356 //==========================================================================
357
358 void SC_UnGet(void)
359 {
360         AlreadyGot = true;
361 }
362
363 //==========================================================================
364 //
365 // SC_Check
366 //
367 // Returns true if another token is on the current line.
368 //
369 //==========================================================================
370
371 /*
372 boolean SC_Check(void)
373 {
374         char *text;
375
376         CheckOpen();
377         text = ScriptPtr;
378         if(text >= ScriptEndPtr)
379         {
380                 return false;
381         }
382         while(*text <= 32)
383         {
384                 if(*text == '\n')
385                 {
386                         return false;
387                 }
388                 text++;
389                 if(text == ScriptEndPtr)
390                 {
391                         return false;
392                 }
393         }
394         if(*text == ASCII_COMMENT)
395         {
396                 return false;
397         }
398         return true;
399 }
400 */
401
402 //==========================================================================
403 //
404 // SC_MatchString
405 //
406 // Returns the index of the first match to sc_String from the passed
407 // array of strings, or -1 if not found.
408 //
409 //==========================================================================
410
411 int SC_MatchString(char **strings)
412 {
413         int i;
414
415         for(i = 0; *strings != NULL; i++)
416         {
417                 if(SC_Compare(*strings++))
418                 {
419                         return i;
420                 }
421         }
422         return -1;
423 }
424
425 //==========================================================================
426 //
427 // SC_MustMatchString
428 //
429 //==========================================================================
430
431 int SC_MustMatchString(char **strings)
432 {
433         int i;
434
435         i = SC_MatchString(strings);
436         if(i == -1)
437         {
438                 SC_ScriptError(NULL);
439         }
440         return i;
441 }
442
443 //==========================================================================
444 //
445 // SC_Compare
446 //
447 //==========================================================================
448
449 boolean SC_Compare(char *text)
450 {
451         if(strcasecmp(text, sc_String) == 0)
452         {
453                 return true;
454         }
455         return false;
456 }
457
458 //==========================================================================
459 //
460 // SC_ScriptError
461 //
462 //==========================================================================
463
464 void SC_ScriptError(char *message)
465 {
466         if(message == NULL)
467         {
468                 message = "Bad syntax.";
469         }
470         I_Error("Script error, \"%s\" line %d: %s", ScriptName,
471                 sc_Line, message);
472 }
473
474 //==========================================================================
475 //
476 // CheckOpen
477 //
478 //==========================================================================
479
480 static void CheckOpen(void)
481 {
482         if(ScriptOpen == false)
483         {
484                 I_Error("SC_ call before SC_Open().");
485         }
486 }
487