more eol-style
[xonotic/netradiant.git] / radiant / parse.cpp
1 /*
2 Copyright (C) 1999-2007 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 #include "stdafx.h"
23
24 char      token[MAXTOKEN];
25 qboolean  unget;
26 char*     script_p;
27 int       scriptline;
28
29 // Hydra: added support for GetTokenExtra()
30 char *currentdelimiters;
31 qboolean  script_keepdelimiter;
32
33 void StartTokenParsing (char *data)
34 {
35   scriptline = 1;
36   script_p = data;
37   unget = false;
38
39   // Hydra: added support for GetTokenExtra()
40   currentdelimiters = NULL;
41   script_keepdelimiter = true;
42 }
43
44
45 qboolean GetToken (qboolean crossline)
46 {
47   char    *token_p;
48   
49   if (unget)                         // is a token already waiting?
50   {
51     unget = false;
52     return true;
53   }
54   
55   //
56   // skip space
57   //
58 skipspace:
59   while (*script_p <= 32)
60   {
61     if (!*script_p)
62     {
63       if (!crossline)
64         Sys_Printf("Warning: Line %i is incomplete [01]\n",scriptline);
65       return false;
66     }
67     
68     if (*script_p++ == '\n')
69     {
70       if (!crossline)
71         Sys_Printf("Warning: Line %i is incomplete [02]\n",scriptline);
72       scriptline++;
73     }
74   }
75   
76   if (script_p[0] == '/' && script_p[1] == '/') // comment field
77   {
78     if (!crossline)
79       Sys_Printf("Warning: Line %i is incomplete [03]\n",scriptline);
80     while (*script_p++ != '\n')
81       if (!*script_p)
82       {
83         if (!crossline)
84           Sys_Printf("Warning: Line %i is incomplete [04]\n",scriptline);
85         return false;
86       }
87       scriptline++; // Hydra: fixed bad line numbers problem
88       goto skipspace;
89   }
90   
91   //
92   // copy token
93   //
94   token_p = token;
95   
96   if (*script_p == '"')
97   {
98     script_p++;
99     while ( *script_p != '"' )
100     {
101       if (!*script_p)
102         Error ("EOF inside quoted token");
103       *token_p++ = *script_p++;
104       if (token_p == &token[MAXTOKEN])
105         Error ("Token too large on line %i",scriptline);
106     }
107     script_p++;
108   }
109   else 
110   while ( *script_p > 32 )
111   {
112     // Hydra: added support for GetTokenExtra(), care was taken to maintain speed
113     if((currentdelimiters) && (!script_keepdelimiter) && (strchr(currentdelimiters,*(script_p))))
114       break;
115
116     *token_p++ = *script_p++;
117     if (token_p == &token[MAXTOKEN])
118       Error ("Token too large on line %i",scriptline);
119
120     // Hydra: added support for GetTokenExtra()
121     if((currentdelimiters) && (strchr(currentdelimiters,*(script_p-1))))
122       break;
123
124   }
125   
126   *token_p = 0;
127   
128   return true;
129 }
130
131 void UngetToken (void)
132 {
133   unget = true;
134 }
135
136 /*
137 ==============
138 GetTokenExtra
139
140 This function expands the use of GetToken() so it can be used to parse
141 more complex file formats.
142
143 Hydra - Notes:
144 You can use this function to split a string like this
145
146 string1:("string2")
147
148 into two strings, like this:
149 string1
150 string2
151
152 whilst still checking for the brackets and colons, like this:
153
154 GetTokenExtra(false,":",false);// contains "string1"
155 GetTokenExtra(false,":",true); // contains ":"
156 GetTokenExtra(false,"(",true); // contains "("
157 GetToken(false);               // contains "string2"
158 GetTokenExtra(false,")",true); // contains ")"
159
160 here's what you get, given the same string, with this code:
161
162 GetToken(false); // contains "string1:("string2")"
163
164 Parsing will end if any character in the script matches any one of the
165 characters in the "delimiters" string.
166
167 it's also possible to do things like this:
168
169 source strings:
170 1,2
171 1:2
172 1-2
173 1*2
174
175 code:
176 GetTokenExtra(false,",:-*",false); // token contains "1"
177 GetTokenExtra(false,",:-*",false); // token contains the delimiter that was used
178 GetToken(false);                   // contains "2"
179 ==============
180 */
181 qboolean GetTokenExtra (qboolean crossline,char *delimiters, qboolean keepdelimiter)
182 {
183   qboolean result;
184   char *olddelimiters = currentdelimiters; // store it
185
186   currentdelimiters = delimiters; // change the delimiters
187   script_keepdelimiter = keepdelimiter; // change the global flag
188
189   result = GetToken(crossline);
190   currentdelimiters = olddelimiters; // restore it
191   return(result);
192 }
193
194 /*
195 ==============
196 TokenAvailable
197
198 Returns true if there is another token on the line
199 ==============
200 */
201 qboolean TokenAvailable (void)
202 {
203   char *search_p;
204
205   search_p = script_p;
206
207   while ( *search_p <= 32)
208   {
209     if (*search_p == '\n')
210       return false;
211     if (*search_p == 0)
212       return false;
213     search_p++;
214   }
215
216   if (*search_p == ';')
217     return false;
218
219   return true;
220 }