]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/bobtoolz/ScriptParser.cpp
ok
[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 "StdAfx.h"
21 #include "ScriptParser.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                 } else if ( c=='/' && m_pScriptSection[1] == '*' ) { // C++ style comments
101                         m_pScriptSection += 2;
102                         while ( *m_pScriptSection && ( *m_pScriptSection != '*' || m_pScriptSection[1] != '/' ) ) {
103                                 m_pScriptSection++;
104                         }
105                         if ( *m_pScriptSection ) {
106                                 m_pScriptSection += 2;
107                         }
108                 } else {
109                         break;
110                 }
111         }
112
113         if (c == '\"') {
114                 m_pScriptSection++;
115                 while ( true ) {
116                         c = *m_pScriptSection++;
117                         if (c=='\"' || !c) {
118                                 token[len] = 0;
119                                 return MakeToken(token);
120                         }
121                         if (len < MAX_TOKEN_STRING) {
122                                 token[len] = c;
123                                 len++;
124                         }
125                 }
126         }
127
128         do {
129                 if(len > 0 && IsBreakChar(*m_pScriptSection)) {
130                         break;
131                 }
132
133                 if (len < MAX_TOKEN_STRING) {
134                         token[len] = c;
135                         len++;
136                 }
137                 m_pScriptSection++;
138
139                 if(IsBreakChar(c)) {
140                         break;
141                 }
142
143                 c = *m_pScriptSection;
144         } while (c > 32);
145
146         if (len == MAX_TOKEN_STRING) {
147                 len = 0;
148         }
149         token[len] = 0;
150
151         return MakeToken(token);
152 }
153
154 void CScriptParser::SkipWhitespace(bool* pbNewLines) {
155         int c;
156
157         if(!m_pScript || !m_pScriptSection) {
158                 return;
159         }
160
161         while( (c = *m_pScriptSection) <= ' ') {
162                 if( !c ) {
163                         return;
164                 }
165                 if( c == '\n' ) {
166                         *pbNewLines = true;
167                 }
168                 m_pScriptSection++;
169         }
170 }
171
172 void CScriptParser::SkipBracedSection(void) {
173         const char              *token;
174         int                             depth;
175
176         depth = 0;
177         do {
178                 token = GetToken( true );
179                 if( token[1] == 0 ) {
180                         if( *token == '{' ) {
181                                 depth++;
182                         } else if( *token == '}' ) {
183                                 depth--;
184                         }
185                 }
186         } while( depth && *m_pScriptSection );
187 }
188
189 void CScriptParser::SkipRestOfLine(void) {
190         char    *p;
191         int             c;
192
193         p = m_pScriptSection;
194         while ( (c = *p++) != 0 ) {
195                 if ( c == '\n' ) {
196                         break;
197                 }
198         }
199         m_pScriptSection = p;
200 }
201
202 void CScriptParser::UndoGetToken(void) {
203         if(!m_pLastScriptSection) {
204                 return;
205         }
206         m_pScriptSection = m_pLastScriptSection;
207         m_pLastScriptSection = NULL;
208 }
209
210 void CScriptParser::ResetParseSession(void) {
211         if(!m_pScript) {
212                 return;
213         }
214
215         m_pScriptSection = m_pScript;
216         m_pLastScriptSection = NULL;
217 }
218
219 char* CScriptParser::GetBufferCopy(void) {
220         if(!m_pScript) {
221                 return NULL;
222         }
223
224         int len = static_cast<int>(strlen(m_pScript));
225         char* pBuffer = new char[len + 1];
226         strcpy(pBuffer, m_pScript);
227         return pBuffer;
228 }
229
230 int CScriptParser::GetTokenOffset(void) {
231         if(!m_pScript || !m_pScriptSection) {
232                 return 0;
233         }
234
235         return static_cast<int>(m_pScriptSection - m_pScript);
236 }
237
238 void CScriptParser::LoadScript(const char* pScript) {
239         ClearBuffer();
240
241         int len = static_cast<int>(strlen(pScript));
242         if(len <= 0) {
243                 return;
244         }
245
246         m_pScript = new char[len + 1];
247         m_pScript[len] = '\0';
248
249         strcpy(m_pScript, pScript);
250         m_pScriptSection = m_pScript;
251 }
252
253 void CScriptParser::AddBreakChar(char c) {
254         for(int i = 0; i < SP_MAX_BREAKCHARS; i++) {
255                 if(!m_breakChars[i]) {
256                         m_breakChars[i] = c;
257                         return;
258                 }
259         }
260
261         // TODO: Error: max break chars hit
262 }
263
264 bool CScriptParser::IsBreakChar(char c) {
265         for(int i = 0; i < SP_MAX_BREAKCHARS; i++) {
266                 if(!m_breakChars[i]) {
267                         return false;
268                 }
269                 if(m_breakChars[i] == c) {
270                         return true;
271                 }
272         }
273         return false;
274 }
275
276 void CScriptParser::SetScript(char* pScript) {
277         ClearBuffer();
278
279         int len = static_cast<int>(strlen(pScript));
280         if(len <= 0) {
281                 return;
282         }
283
284         m_pScript = pScript;
285         m_pScriptSection = m_pScript;
286 }