]> git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake2/qdata_heretic2/common/scriplib.c
transfer from internal tree r5311 branches/1.4-gpl
[xonotic/netradiant.git] / tools / quake2 / qdata_heretic2 / common / scriplib.c
1 /*\r
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
3 For a list of contributors, see the accompanying CONTRIBUTORS file.\r
4 \r
5 This file is part of GtkRadiant.\r
6 \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
11 \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
16 \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
20 */\r
21 \r
22 // scriplib.c\r
23 \r
24 #include "cmdlib.h"\r
25 #include "inout.h"\r
26 #include "scriplib.h"\r
27 \r
28 /*\r
29 =============================================================================\r
30 \r
31                                                 PARSING STUFF\r
32 \r
33 =============================================================================\r
34 */\r
35 \r
36 typedef struct\r
37 {\r
38         char    filename[1024];\r
39         char    *buffer,*script_p,*end_p;\r
40         int     line;\r
41 } script_t;\r
42 \r
43 #define MAX_INCLUDES    8\r
44 script_t        scriptstack[MAX_INCLUDES];\r
45 script_t        *script;\r
46 int                     scriptline;\r
47 \r
48 char    token[MAXTOKEN];\r
49 qboolean endofscript;\r
50 qboolean tokenready;                     // only true if UnGetScriptToken was just called\r
51 \r
52 /*\r
53 ==============\r
54 AddScriptToStack\r
55 ==============\r
56 */\r
57 void AddScriptToStack (char *filename)\r
58 {\r
59         int            size;\r
60 \r
61         script++;\r
62         if (script == &scriptstack[MAX_INCLUDES])\r
63                 Error ("script file exceeded MAX_INCLUDES");\r
64         strcpy (script->filename, ExpandPath (filename) );\r
65 \r
66         size = LoadFile (script->filename, (void **)&script->buffer);\r
67 \r
68         printf ("entering %s\n", script->filename);\r
69 \r
70         script->line = 1;\r
71 \r
72         script->script_p = script->buffer;\r
73         script->end_p = script->buffer + size;\r
74 }\r
75 \r
76 \r
77 /*\r
78 ==============\r
79 LoadScriptFile\r
80 ==============\r
81 */\r
82 void LoadScriptFile (char *filename)\r
83 {\r
84         script = scriptstack;\r
85         AddScriptToStack (filename);\r
86 \r
87         endofscript = false;\r
88         tokenready = false;\r
89 }\r
90 \r
91 \r
92 /*\r
93 ==============\r
94 ParseFromMemory\r
95 ==============\r
96 */\r
97 void ParseFromMemory (char *buffer, int size)\r
98 {\r
99         script = scriptstack;\r
100         script++;\r
101         if (script == &scriptstack[MAX_INCLUDES])\r
102                 Error ("script file exceeded MAX_INCLUDES");\r
103         strcpy (script->filename, "memory buffer" );\r
104 \r
105         script->buffer = buffer;\r
106         script->line = 1;\r
107         script->script_p = script->buffer;\r
108         script->end_p = script->buffer + size;\r
109 \r
110         endofscript = false;\r
111         tokenready = false;\r
112 }\r
113 \r
114 \r
115 /*\r
116 ==============\r
117 UnGetScriptToken\r
118 \r
119 Signals that the current token was not used, and should be reported\r
120 for the next GetScriptToken.  Note that\r
121 \r
122 GetScriptToken (true);\r
123 UnGetScriptToken ();\r
124 GetScriptToken (false);\r
125 \r
126 could cross a line boundary.\r
127 ==============\r
128 */\r
129 void UnGetScriptToken (void)\r
130 {\r
131         tokenready = true;\r
132 }\r
133 \r
134 \r
135 qboolean EndOfScript (qboolean crossline)\r
136 {\r
137         if (!crossline)\r
138                 Error ("Line %i is incomplete\n",scriptline);\r
139 \r
140         if (!strcmp (script->filename, "memory buffer"))\r
141         {\r
142                 endofscript = true;\r
143                 return false;\r
144         }\r
145 \r
146         free (script->buffer);\r
147         if (script == scriptstack+1)\r
148         {\r
149                 endofscript = true;\r
150                 return false;\r
151         }\r
152         script--;\r
153         scriptline = script->line;\r
154         printf ("returning to %s\n", script->filename);\r
155         return GetScriptToken (crossline);\r
156 }\r
157 \r
158 /*\r
159 ==============\r
160 GetScriptToken\r
161 ==============\r
162 */\r
163 qboolean GetScriptToken (qboolean crossline)\r
164 {\r
165         char    *token_p;\r
166 \r
167         if (tokenready)                         // is a token allready waiting?\r
168         {\r
169                 tokenready = false;\r
170                 return true;\r
171         }\r
172 \r
173         if (script->script_p >= script->end_p)\r
174                 return EndOfScript (crossline);\r
175 \r
176 //\r
177 // skip space\r
178 //\r
179 skipspace:\r
180         while (*script->script_p <= 32)\r
181         {\r
182                 if (script->script_p >= script->end_p)\r
183                         return EndOfScript (crossline);\r
184                 if (*script->script_p++ == '\n')\r
185                 {\r
186                         if (!crossline)\r
187                                 Error ("Line %i is incomplete\n",scriptline);\r
188                         scriptline = script->line++;\r
189                 }\r
190         }\r
191 \r
192         if (script->script_p >= script->end_p)\r
193                 return EndOfScript (crossline);\r
194 \r
195         // ; # // comments\r
196         if (*script->script_p == ';' || *script->script_p == '#'\r
197                 || ( script->script_p[0] == '/' && script->script_p[1] == '/') )\r
198         {\r
199                 if (!crossline)\r
200                         Error ("Line %i is incomplete\n",scriptline);\r
201                 while (*script->script_p++ != '\n')\r
202                         if (script->script_p >= script->end_p)\r
203                                 return EndOfScript (crossline);\r
204                 goto skipspace;\r
205         }\r
206 \r
207         // /* */ comments\r
208         if (script->script_p[0] == '/' && script->script_p[1] == '*')\r
209         {\r
210                 if (!crossline)\r
211                         Error ("Line %i is incomplete\n",scriptline);\r
212                 script->script_p+=2;\r
213                 while (script->script_p[0] != '*' && script->script_p[1] != '/')\r
214                 {\r
215                         script->script_p++;\r
216                         if (script->script_p >= script->end_p)\r
217                                 return EndOfScript (crossline);\r
218                 }\r
219                 script->script_p += 2;\r
220                 goto skipspace;\r
221         }\r
222 \r
223 //\r
224 // copy token\r
225 //\r
226         token_p = token;\r
227 \r
228         if (*script->script_p == '"')\r
229         {\r
230                 // quoted token\r
231                 script->script_p++;\r
232                 while (*script->script_p != '"')\r
233                 {\r
234                         *token_p++ = *script->script_p++;\r
235                         if (script->script_p == script->end_p)\r
236                                 break;\r
237                         if (token_p == &token[MAXTOKEN])\r
238                                 Error ("Token too large on line %i\n",scriptline);\r
239                 }\r
240                 script->script_p++;\r
241         }\r
242         else    // regular token\r
243         while ( *script->script_p > 32 && *script->script_p != ';')\r
244         {\r
245                 *token_p++ = *script->script_p++;\r
246                 if (script->script_p == script->end_p)\r
247                         break;\r
248                 if (token_p == &token[MAXTOKEN])\r
249                         Error ("Token too large on line %i\n",scriptline);\r
250         }\r
251 \r
252         *token_p = 0;\r
253 \r
254         if (!strcmp (token, "$include"))\r
255         {\r
256                 GetScriptToken (false);\r
257                 AddScriptToStack (token);\r
258                 return GetScriptToken (crossline);\r
259         }\r
260 \r
261         return true;\r
262 }\r
263 \r
264 \r
265 /*\r
266 ==============\r
267 ScriptTokenAvailable\r
268 \r
269 Returns true if there is another token on the line\r
270 ==============\r
271 */\r
272 qboolean ScriptTokenAvailable (void)\r
273 {\r
274         char    *search_p;\r
275 \r
276         search_p = script->script_p;\r
277 \r
278         if (search_p >= script->end_p)\r
279                 return false;\r
280 \r
281         while ( *search_p <= 32)\r
282         {\r
283                 if (*search_p == '\n')\r
284                         return false;\r
285                 search_p++;\r
286                 if (search_p == script->end_p)\r
287                         return false;\r
288 \r
289         }\r
290 \r
291         if (*search_p == ';')\r
292                 return false;\r
293 \r
294         return true;\r
295 }\r
296 \r
297 \r