UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
parse.cpp
Go to the documentation of this file.
1 
6 /*
7 All original material Copyright (C) 2002-2020 UFO: Alien Invasion.
8 
9 Copyright (C) 1997-2001 Id Software, Inc.
10 
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License
13 as published by the Free Software Foundation; either version 2
14 of the License, or (at your option) any later version.
15 
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 
20 See the GNU General Public License for more details.
21 
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 
26 */
27 
28 #include "parse.h"
29 #include "defines.h"
30 #include "ufotypes.h"
31 
32 static char com_token[4096];
33 static bool isUnparsedToken;
35 
43 {
44  isUnparsedToken = true;
45 }
46 
51 const char* Com_GetToken (const char** data_p)
52 {
53  return com_token;
54 }
55 
60 Com_TokenType_t Com_GetType (const char** data_p)
61 {
62  return type;
63 }
64 
69 Com_TokenType_t Com_NextToken (const char** data_p)
70 {
71  Com_Parse(data_p);
72  return type;
73 }
74 
80 int Com_CountTokensInBuffer (const char* buffer)
81 {
82  const char* text = buffer;
83  int n = 0;
84  for (;;) {
85  Com_Parse(&text);
86  if (!text)
87  break;
88  n++;
89  }
90  return n;
91 }
92 
107 const char* Com_Parse (const char* data_p[], char* target, size_t size, bool replaceWhitespaces)
108 {
109  char c;
110  size_t len;
111  const char* data;
112 
113  if (!target) {
114  target = com_token;
115  size = sizeof(com_token);
116  }
117 
118  if (isUnparsedToken) {
119  isUnparsedToken = false;
120  return target;
121  }
122 
123  data = *data_p;
124  len = 0;
125  target[0] = '\0';
126 
127  if (!data) {
128  *data_p = nullptr;
129  type = TT_EOF;
130  return "";
131  }
132 
133  /* skip whitespace */
134 skipwhite:
135  while ((c = *data) <= ' ') {
136  if (c == 0) {
137  *data_p = nullptr;
138  type = TT_EOF;
139  return "";
140  }
141  data++;
142  }
143 
144  if (c == '/' && data[1] == '*') {
145  int clen = 0;
146  data += 2;
147  while (!((data[clen] && data[clen] == '*') && (data[clen + 1] && data[clen + 1] == '/'))) {
148  clen++;
149  }
150  data += clen + 2; /* skip end of multiline comment */
151  goto skipwhite;
152  }
153 
154  /* skip // comments */
155  if (c == '/' && data[1] == '/') {
156  while (*data && *data != '\n')
157  data++;
158  goto skipwhite;
159  }
160 
161  /* handle quoted strings specially */
162  if (c == '\"') {
163  data++;
164  for (;;) {
165  c = *data++;
166  if (c == '\\' && data[0] == 'n') {
167  if (replaceWhitespaces) {
168  c = '\n';
169  data++;
170  }
171  } else if (c == '\\' && data[0] == 't') {
172  if (replaceWhitespaces) {
173  c = '\t';
174  data++;
175  }
176  /* nested quotation */
177  } else if (c == '\\' && data[0] == '\"') {
178  c = '\"';
179  data++;
180  } else if (c == '\"' || !c) {
181  target[len] = '\0';
182  *data_p = data;
184  return target;
185  } else if (c == '\0') {
186  // TODO here the token is wrongly formed
187  break;
188  }
189 
190  if (len < size) {
191  if (c != '\r') {
192  target[len] = c;
193  len++;
194  }
195  } else {
196  /* exceeded com_token size */
197  break;
198  }
199  }
200 
201  if (len == size) {
202  len = 0;
203  }
204 
205  // TODO here the token is wrongly formed
206  target[len] = '\0';
207  *data_p = data;
209  return target;
210  }
211 
212  if (c == '{' || c == '}' || c == '(' || c == ')' || c == ',') {
213  data++;
214  target[len] = c;
215  target[len + 1] = '\0';
216  // Com_TokenType_t contains expected values for this set of characters
217  type = (Com_TokenType_t) c;
218  len++;
219  *data_p = data;
220  return target;
221  }
222 
223  /* parse a regular word */
224  do {
225  if (len < size) {
226  target[len] = c;
227  len++;
228  } else {
229  /* exceeded com_token size */
230  break;
231  }
232  data++;
233  c = *data;
234  if (c == '{' || c == '}' || c == '(' || c == ')' || c == ',')
235  break;
236  } while (c > ' ');
237 
238  if (len == size) {
239  len = 0;
240  }
241  target[len] = '\0';
242 
243  *data_p = data;
244  type = TT_WORD;
245  return target;
246 }
247 
253 void Com_SkipBlock (const char** text)
254 {
255  int depth = 1;
256 
257  do {
258  const char* token = Com_Parse(text);
259  if (*token == '{')
260  depth++;
261  else if (*token == '}')
262  depth--;
263  } while (depth && *text);
264 }
265 
272 int Com_GetBlock (const char** text, const char** start)
273 {
274  const char* token = Com_Parse(text);
275  if (*token != '{')
276  return -1;
277  *start = *text;
278  Com_SkipBlock(text);
279  const char* end = *text - 1; /* The pointer to the end of the block */
280  return end - *start;
281 }
Definition: parse.h:34
Shared parsing functions.
Com_TokenType_t
Definition: parse.h:33
int Com_CountTokensInBuffer(const char *buffer)
Counts the tokens in the given buffer that the Com_Parse function would extract.
Definition: parse.cpp:80
GLsizei size
Definition: r_gl.h:152
Definition: parse.h:42
Defined CONSTANTS (Macros are elsewhere)
static Com_TokenType_t type
Definition: parse.cpp:34
static char com_token[4096]
Definition: parse.cpp:32
int Com_GetBlock(const char **text, const char **start)
Get the start and end point of a block in the given text.
Definition: parse.cpp:272
const char * Com_Parse(const char *data_p[], char *target, size_t size, bool replaceWhitespaces)
Parse a token out of a string.
Definition: parse.cpp:107
static bool isUnparsedToken
Definition: parse.cpp:33
QGL_EXTERN GLuint GLchar GLuint * len
Definition: r_gl.h:99
Com_TokenType_t Com_GetType(const char **data_p)
Get the current token type.
Definition: parse.cpp:60
void Com_UnParseLastToken(void)
Put back the last token into the parser The next call of Com_Parse will return the same token again...
Definition: parse.cpp:42
GLsizei const GLvoid * data
Definition: r_gl.h:152
Com_TokenType_t Com_NextToken(const char **data_p)
Compute the next token.
Definition: parse.cpp:69
Cross-platform type definitions.
const char * Com_GetToken(const char **data_p)
Get the current token value.
Definition: parse.cpp:51
void Com_SkipBlock(const char **text)
Skips a block of {} in our script files.
Definition: parse.cpp:253