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