]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/bobtoolz/ScriptParser.cpp
my own uncrustify run
[xonotic/netradiant.git] / contrib / bobtoolz / ScriptParser.cpp
1 /*
2    BobToolz plugin for GtkRadiant
3    Copyright (C) 2001 Gordon Biggans
4
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with this library; if not, write to the Free Software
17    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19
20 #include "ScriptParser.h"
21 #include <string.h>
22
23 CScriptParser::CScriptParser( void ) :
24         m_pScript( NULL ),
25         m_pScriptSection( NULL ),
26         m_pLastScriptSection( NULL ),
27         m_pToken( NULL ) {
28         ClearBuffer();
29 }
30
31 CScriptParser::~CScriptParser( void ) {
32         ClearBuffer();
33 }
34
35 void CScriptParser::ClearBuffer( void ) {
36         if ( m_pScript ) {
37                 delete[] m_pScript;
38                 m_pScript = NULL;
39         }
40         if ( m_pToken ) {
41                 delete[] m_pToken;
42                 m_pToken = NULL;
43         }
44         m_pScriptSection = NULL;
45         m_pLastScriptSection = NULL;
46         memset( m_breakChars, 0, sizeof( m_breakChars ) );
47 }
48
49 const char* CScriptParser::MakeToken( const char* pToken ) {
50         if ( m_pToken ) {
51                 delete[] m_pToken;
52                 m_pToken = NULL;
53         }
54
55         if ( !pToken ) {
56                 pToken = "";
57         }
58
59         int len = static_cast<int>( strlen( pToken ) );
60
61         m_pToken = new char[len + 1];
62         m_pToken[len] = '\0';
63         strcpy( m_pToken, pToken );
64
65         return m_pToken;
66 }
67
68 #define MAX_TOKEN_STRING 1024
69 // Should NEVER return NULL
70 const char* CScriptParser::GetToken( bool bAllowLinebreaks ) {
71         int c = 0, len;
72         char token[MAX_TOKEN_STRING];
73         bool bNewLines = false;
74
75         m_pLastScriptSection = m_pScriptSection;
76
77         len = 0;
78         *token = '\0';
79
80         if ( !m_pScript || !m_pScriptSection ) {
81                 return MakeToken( token );
82         }
83
84         while ( true ) {
85                 SkipWhitespace( &bNewLines );
86                 if ( !*m_pScriptSection ) {
87                         return MakeToken( token );
88                 }
89                 if ( bNewLines && !bAllowLinebreaks ) {
90                         return MakeToken( token );
91                 }
92
93                 c = *m_pScriptSection;
94
95                 if ( c == '/' && m_pScriptSection[1] == '/' ) { // C style comments
96                         m_pScriptSection += 2;
97                         while ( *m_pScriptSection && *m_pScriptSection != '\n' ) {
98                                 m_pScriptSection++;
99                         }
100                 }
101                 else if ( c == '/' && m_pScriptSection[1] == '*' ) { // C++ style comments
102                         m_pScriptSection += 2;
103                         while ( *m_pScriptSection && ( *m_pScriptSection != '*' || m_pScriptSection[1] != '/' ) ) {
104                                 m_pScriptSection++;
105                         }
106                         if ( *m_pScriptSection ) {
107                                 m_pScriptSection += 2;
108                         }
109                 }
110                 else {
111                         break;
112                 }
113         }
114
115         if ( c == '\"' ) {
116                 m_pScriptSection++;
117                 while ( true ) {
118                         c = *m_pScriptSection++;
119                         if ( c == '\"' || !c ) {
120                                 token[len] = 0;
121                                 return MakeToken( token );
122                         }
123                         if ( len < MAX_TOKEN_STRING ) {
124                                 token[len] = c;
125                                 len++;
126                         }
127                 }
128         }
129
130         do {
131                 if ( len > 0 && IsBreakChar( *m_pScriptSection ) ) {
132                         break;
133                 }
134
135                 if ( len < MAX_TOKEN_STRING ) {
136                         token[len] = c;
137                         len++;
138                 }
139                 m_pScriptSection++;
140
141                 if ( IsBreakChar( c ) ) {
142                         break;
143                 }
144
145                 c = *m_pScriptSection;
146         } while ( c > 32 );
147
148         if ( len == MAX_TOKEN_STRING ) {
149                 len = 0;
150         }
151         token[len] = 0;
152
153         return MakeToken( token );
154 }
155
156 void CScriptParser::SkipWhitespace( bool* pbNewLines ) {
157         int c;
158
159         if ( !m_pScript || !m_pScriptSection ) {
160                 return;
161         }
162
163         while ( ( c = *m_pScriptSection ) <= ' ' ) {
164                 if ( !c ) {
165                         return;
166                 }
167                 if ( c == '\n' ) {
168                         *pbNewLines = true;
169                 }
170                 m_pScriptSection++;
171         }
172 }
173
174 void CScriptParser::SkipBracedSection( void ) {
175         const char      *token;
176         int depth;
177
178         depth = 0;
179         do {
180                 token = GetToken( true );
181                 if ( token[1] == 0 ) {
182                         if ( *token == '{' ) {
183                                 depth++;
184                         }
185                         else if ( *token == '}' ) {
186                                 depth--;
187                         }
188                 }
189         } while ( depth && *m_pScriptSection );
190 }
191
192 void CScriptParser::SkipRestOfLine( void ) {
193         char    *p;
194         int c;
195
196         p = m_pScriptSection;
197         while ( ( c = *p++ ) != 0 ) {
198                 if ( c == '\n' ) {
199                         break;
200                 }
201         }
202         m_pScriptSection = p;
203 }
204
205 void CScriptParser::UndoGetToken( void ) {
206         if ( !m_pLastScriptSection ) {
207                 return;
208         }
209         m_pScriptSection = m_pLastScriptSection;
210         m_pLastScriptSection = NULL;
211 }
212
213 void CScriptParser::ResetParseSession( void ) {
214         if ( !m_pScript ) {
215                 return;
216         }
217
218         m_pScriptSection = m_pScript;
219         m_pLastScriptSection = NULL;
220 }
221
222 char* CScriptParser::GetBufferCopy( void ) {
223         if ( !m_pScript ) {
224                 return NULL;
225         }
226
227         int len = static_cast<int>( strlen( m_pScript ) );
228         char* pBuffer = new char[len + 1];
229         strcpy( pBuffer, m_pScript );
230         return pBuffer;
231 }
232
233 int CScriptParser::GetTokenOffset( void ) {
234         if ( !m_pScript || !m_pScriptSection ) {
235                 return 0;
236         }
237
238         return static_cast<int>( m_pScriptSection - m_pScript );
239 }
240
241 void CScriptParser::LoadScript( const char* pScript ) {
242         ClearBuffer();
243
244         int len = static_cast<int>( strlen( pScript ) );
245         if ( len <= 0 ) {
246                 return;
247         }
248
249         m_pScript = new char[len + 1];
250         m_pScript[len] = '\0';
251
252         strcpy( m_pScript, pScript );
253         m_pScriptSection = m_pScript;
254 }
255
256 void CScriptParser::AddBreakChar( char c ) {
257         for ( int i = 0; i < SP_MAX_BREAKCHARS; i++ ) {
258                 if ( !m_breakChars[i] ) {
259                         m_breakChars[i] = c;
260                         return;
261                 }
262         }
263
264         // TODO: Error: max break chars hit
265 }
266
267 bool CScriptParser::IsBreakChar( char c ) {
268         for ( int i = 0; i < SP_MAX_BREAKCHARS; i++ ) {
269                 if ( !m_breakChars[i] ) {
270                         return false;
271                 }
272                 if ( m_breakChars[i] == c ) {
273                         return true;
274                 }
275         }
276         return false;
277 }
278
279 void CScriptParser::SetScript( char* pScript ) {
280         ClearBuffer();
281
282         int len = static_cast<int>( strlen( pScript ) );
283         if ( len <= 0 ) {
284                 return;
285         }
286
287         m_pScript = pScript;
288         m_pScriptSection = m_pScript;
289 }