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