]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/bobtoolz/ScriptParser.cpp
uncrustify! now the code is only ugly on the *inside*
[xonotic/netradiant.git] / contrib / bobtoolz / ScriptParser.cpp
1 #include "StdAfx.h"
2 #include "ScriptParser.h"
3
4 CScriptParser::CScriptParser( void ) :
5         m_pScript( NULL ),
6         m_pScriptSection( NULL ),
7         m_pLastScriptSection( NULL ),
8         m_pToken( NULL ) {
9         ClearBuffer();
10 }
11
12 CScriptParser::~CScriptParser( void ) {
13         ClearBuffer();
14 }
15
16 void CScriptParser::ClearBuffer( void ) {
17         if ( m_pScript ) {
18                 delete[] m_pScript;
19                 m_pScript = NULL;
20         }
21         if ( m_pToken ) {
22                 delete[] m_pToken;
23                 m_pToken = NULL;
24         }
25         m_pScriptSection = NULL;
26         m_pLastScriptSection = NULL;
27         memset( m_breakChars, 0, sizeof( m_breakChars ) );
28 }
29
30 const char* CScriptParser::MakeToken( const char* pToken ) {
31         if ( m_pToken ) {
32                 delete[] m_pToken;
33                 m_pToken = NULL;
34         }
35
36         if ( !pToken ) {
37                 pToken = "";
38         }
39
40         int len = static_cast<int>( strlen( pToken ) );
41
42         m_pToken = new char[len + 1];
43         m_pToken[len] = '\0';
44         strcpy( m_pToken, pToken );
45
46         return m_pToken;
47 }
48
49 #define MAX_TOKEN_STRING 1024
50 // Should NEVER return NULL
51 const char* CScriptParser::GetToken( bool bAllowLinebreaks ) {
52         int c = 0, len;
53         char token[MAX_TOKEN_STRING];
54         bool bNewLines = false;
55
56         m_pLastScriptSection = m_pScriptSection;
57
58         len = 0;
59         *token = '\0';
60
61         if ( !m_pScript || !m_pScriptSection ) {
62                 return MakeToken( token );
63         }
64
65         while ( true ) {
66                 SkipWhitespace( &bNewLines );
67                 if ( !*m_pScriptSection ) {
68                         return MakeToken( token );
69                 }
70                 if ( bNewLines && !bAllowLinebreaks ) {
71                         return MakeToken( token );
72                 }
73
74                 c = *m_pScriptSection;
75
76                 if ( c == '/' && m_pScriptSection[1] == '/' ) { // C style comments
77                         m_pScriptSection += 2;
78                         while ( *m_pScriptSection && *m_pScriptSection != '\n' ) {
79                                 m_pScriptSection++;
80                         }
81                 }
82                 else if ( c == '/' && m_pScriptSection[1] == '*' ) { // C++ style comments
83                         m_pScriptSection += 2;
84                         while ( *m_pScriptSection && ( *m_pScriptSection != '*' || m_pScriptSection[1] != '/' ) ) {
85                                 m_pScriptSection++;
86                         }
87                         if ( *m_pScriptSection ) {
88                                 m_pScriptSection += 2;
89                         }
90                 }
91                 else {
92                         break;
93                 }
94         }
95
96         if ( c == '\"' ) {
97                 m_pScriptSection++;
98                 while ( true ) {
99                         c = *m_pScriptSection++;
100                         if ( c == '\"' || !c ) {
101                                 token[len] = 0;
102                                 return MakeToken( token );
103                         }
104                         if ( len < MAX_TOKEN_STRING ) {
105                                 token[len] = c;
106                                 len++;
107                         }
108                 }
109         }
110
111         do {
112                 if ( len > 0 && IsBreakChar( *m_pScriptSection ) ) {
113                         break;
114                 }
115
116                 if ( len < MAX_TOKEN_STRING ) {
117                         token[len] = c;
118                         len++;
119                 }
120                 m_pScriptSection++;
121
122                 if ( IsBreakChar( c ) ) {
123                         break;
124                 }
125
126                 c = *m_pScriptSection;
127         } while ( c > 32 );
128
129         if ( len == MAX_TOKEN_STRING ) {
130                 len = 0;
131         }
132         token[len] = 0;
133
134         return MakeToken( token );
135 }
136
137 void CScriptParser::SkipWhitespace( bool* pbNewLines ) {
138         int c;
139
140         if ( !m_pScript || !m_pScriptSection ) {
141                 return;
142         }
143
144         while ( ( c = *m_pScriptSection ) <= ' ' ) {
145                 if ( !c ) {
146                         return;
147                 }
148                 if ( c == '\n' ) {
149                         *pbNewLines = true;
150                 }
151                 m_pScriptSection++;
152         }
153 }
154
155 void CScriptParser::SkipBracedSection( void ) {
156         const char      *token;
157         int depth;
158
159         depth = 0;
160         do {
161                 token = GetToken( true );
162                 if ( token[1] == 0 ) {
163                         if ( *token == '{' ) {
164                                 depth++;
165                         }
166                         else if ( *token == '}' ) {
167                                 depth--;
168                         }
169                 }
170         } while ( depth && *m_pScriptSection );
171 }
172
173 void CScriptParser::SkipRestOfLine( void ) {
174         char    *p;
175         int c;
176
177         p = m_pScriptSection;
178         while ( ( c = *p++ ) != 0 ) {
179                 if ( c == '\n' ) {
180                         break;
181                 }
182         }
183         m_pScriptSection = p;
184 }
185
186 void CScriptParser::UndoGetToken( void ) {
187         if ( !m_pLastScriptSection ) {
188                 return;
189         }
190         m_pScriptSection = m_pLastScriptSection;
191         m_pLastScriptSection = NULL;
192 }
193
194 void CScriptParser::ResetParseSession( void ) {
195         if ( !m_pScript ) {
196                 return;
197         }
198
199         m_pScriptSection = m_pScript;
200         m_pLastScriptSection = NULL;
201 }
202
203 char* CScriptParser::GetBufferCopy( void ) {
204         if ( !m_pScript ) {
205                 return NULL;
206         }
207
208         int len = static_cast<int>( strlen( m_pScript ) );
209         char* pBuffer = new char[len + 1];
210         strcpy( pBuffer, m_pScript );
211         return pBuffer;
212 }
213
214 int CScriptParser::GetTokenOffset( void ) {
215         if ( !m_pScript || !m_pScriptSection ) {
216                 return 0;
217         }
218
219         return static_cast<int>( m_pScriptSection - m_pScript );
220 }
221
222 void CScriptParser::LoadScript( const char* pScript ) {
223         ClearBuffer();
224
225         int len = static_cast<int>( strlen( pScript ) );
226         if ( len <= 0 ) {
227                 return;
228         }
229
230         m_pScript = new char[len + 1];
231         m_pScript[len] = '\0';
232
233         strcpy( m_pScript, pScript );
234         m_pScriptSection = m_pScript;
235 }
236
237 void CScriptParser::AddBreakChar( char c ) {
238         for ( int i = 0; i < SP_MAX_BREAKCHARS; i++ ) {
239                 if ( !m_breakChars[i] ) {
240                         m_breakChars[i] = c;
241                         return;
242                 }
243         }
244
245         // TODO: Error: max break chars hit
246 }
247
248 bool CScriptParser::IsBreakChar( char c ) {
249         for ( int i = 0; i < SP_MAX_BREAKCHARS; i++ ) {
250                 if ( !m_breakChars[i] ) {
251                         return false;
252                 }
253                 if ( m_breakChars[i] == c ) {
254                         return true;
255                 }
256         }
257         return false;
258 }
259
260 void CScriptParser::SetScript( char* pScript ) {
261         ClearBuffer();
262
263         int len = static_cast<int>( strlen( pScript ) );
264         if ( len <= 0 ) {
265                 return;
266         }
267
268         m_pScript = pScript;
269         m_pScriptSection = m_pScript;
270 }