File: consoleparse.h

package info (click to toggle)
freespace2 3.7.4%2Brepack-1.1
  • links: PTS, VCS
  • area: non-free
  • in suites: bullseye
  • size: 22,268 kB
  • sloc: cpp: 393,535; ansic: 4,106; makefile: 1,091; xml: 181; sh: 137
file content (460 lines) | stat: -rw-r--r-- 15,314 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
#ifndef _CONSOLEPARSE_H
#define _CONSOLEPARSE_H
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Command-line parsing functions for z64555's debug console, created for the FreeSpace Source Code project
//
// Portions of this source code are based on works by Volition, Inc. circa 1999. You may not sell or otherwise
// commercially exploit the source or things you created based on the source.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/**
 * @file consoleparse.h
 * @brief Parsing functions for the command line. Previously known as the command line scanner
 *
 * @details A lot of functions here are blatently copied from parselo.h :D
  */

#include "debugconsole/console.h"
#include "globalincs/pstypes.h"

#include <cstdarg>

#define MAX_CLI_LEN 512
#define MAX_TOKEN_LENGTH 255

enum dc_token {
	DCT_NONE = 0,   //!< No token
	DCT_STRING,     //!< String
	DCT_FLOAT,      //!< Floating point
	DCT_INT,        //!< Integral
	DCT_UINT,       //!< Unsigned Integral
	DCT_BYTE,       //!< Integral with values between -128 and 127
	DCT_UBYTE,      //!< Integral with values between 0 and 255
	DCT_BOOL,       //!< Integral or string evaluated as a boolean

	DCT_MAX_ITEMS   //!< Maximum number of dc_token elements. Primarily used as an end value in loops
};

/**
 * @class errParse
 *
 * @brief Class thrown when a required token is not found
 *
 *  @details This is a basic parser error, it contains the token (a single word) that was found, and the expected token
 *      type. Some DCT's, such as the DCT_STRING's, have their own specific requirements for error handling, and as
 *      such get their own class derived from errParse. The catching routines should be able to catch the derived error
 *      objects, but if not, they can be caught by a routine looking for the base class and then be casted to their
 *      proper type.
 */
class errParse {
public:
	SCP_string found_token;
	dc_token expected_type;

	/**
	*  @brief Invalid/Unexpected token constructor
	*  @param [in] found_str The token that was found
	*  @param [in] expected_dct The token type that was expected
	*/
	errParse(const char *found_str, dc_token expected_dct)
		: found_token(found_str), expected_type(expected_dct)
	{
	}
};

/**
 * @class errParseString
 *
 * @brief Class thrown when an expected string was not found. Can/should contain all of the expected strings.
 */
class errParseString : public errParse
{
public:
	SCP_vector<SCP_string> expected_tokens;

	/**
	 *  @brief Invalid/Unexpected token constructor.
	 *  
	 *  @param [in] found_str The string that was found
	 *  @param [in] str The token that was expected
	 */
	errParseString(const char *found_str, char *str)
	    : errParse(found_str, DCT_STRING)
	{
		expected_tokens.push_back(str);
	}

	/**
	 *  @brief Invalid/Unexpected token constructor.
	 *  
	 *  @param [in] found_str The string that was found
	 *  @param [in] str1 The first token that was expected
	 *  @param [in] str2 The second token that was expected
	 */
	errParseString(const char *found_str, char *str1, char *str2)
	    : errParse(found_str, DCT_STRING)
	{
		expected_tokens.push_back(str1);
		expected_tokens.push_back(str2);
	}

	/**
	 *  @brief Invalid/Unexpected token constructor.
	 *  
	 *  @param [in] found_str The string that was found
	 *  @param [in] strings The strings that were expected
	 */
	errParseString(const char *found_str, SCP_vector<SCP_string> &strings)
	    : errParse(found_str, DCT_STRING), expected_tokens(strings)
	{
	}
};

/**
 * @class errParseOverflow
 *
 * @brief Class thrown when the parsed string or token could not be stuffed into the smaller destination container
 *
 * @var found_str Contains the first 'len' valid characters.
 */
class errParseOverflow : public errParse
{
public:
	size_t len;		//!< The size of the destination container

	errParseOverflow(const char *found_str, size_t _len)
		: errParse(found_str, DCT_STRING), len(_len)
	{
	}
};

/**
 * @brief Initializes the DC command line parser
 */
void dc_parse_init(SCP_string &str);

/**
 * @brief Advances the parser past whitespace characters
 */
void dc_ignore_white_space(void);

/**
 * @brief Advances the parser past grayspace characters
 */
void dc_ignore_gray_space(void);

// Required/Optional Token
/**
 * @brief Searches for a specified required string, throwing an errParse if not found.
 *
 * @param[in] pstr The string to search for
 *
 * @throws errParseString with the required string
 */
void dc_required_string(char *pstr);

/**
 * @brief Searchs for either of the specified required strings, throwing an errParse if neither are found
 *
 * @param[in] str1 The first string to search for
 * @param[in] str2 The second string to search for
 *
 * @retval 0 if str1 was found, or
 * @retval 1 if str2 was found
 *
 * @throws errParseString with the required strings
 */
int dc_required_string_either(char *str1, char *str2);

/**
 * @brief Searches for specified required strings
 *
 * @param[in] n The number of char[] or c_str's given
 * @param[in] ... A comma delimited list of one or more required strings.
 *
 * @returns The index of the specified required strings (as if they were an array)
 *
 * @throws errParseString with the required strings
 */
uint dc_required_string_any(const uint n, ...);

/**
 * @brief Searches for an optional string
 *
 * @param[in] pstr The char[] to look for
 *
 * @retval true if the string was found,
 * @retval false otherwise
 */
bool dc_optional_string(const char *pstr);

/**
 * @brief Searches for an optional string and it's alias
 *
 * @param[in] str1 The char[] to look for
 * @param[in] str2 The alternative char[] to look for
 *
 * @retval true if the string was found,
 * @retval false otherwise
 */
bool dc_optional_string_either(const char *str1, const char *str2);


// ==========================
// Stuffers
// ==========================

/**
 * @brief Stuffs a float to the given variable.
 *
 * @param[in] f  The float variable to stuff to
 *
 * @throws errParse if an unexpected or otherwise malformed float string is found.
 * @throws errParse if nothing was found
 */
void dc_stuff_float(float *f);

/**
 * @brief Stuffs an int to the given variable. Supports binary (0b), hexadecimal (0x), and octal (0o) formats
 *
 * @param[in] i  The int variable to stuff to
 *
 * @details The binary, hexadecimal, and octal formats must be prefixed by their associated string.
 *   Ex: "0xDEADBEEF" would be parsed properly while "DEADBEEF" would throw an error
 *
 * @throws errParse if an unexpected or otherwise malformed float string is found.
 * @throws errParse if nothing was found
 */
void dc_stuff_int(int *i);

/**
 * @brief Stuffs an unsigned int to the given variable. Supports binary (0b), hexadecimal (0x), and octal (0o) formats
 *
 * @param[in] i  The unsigned int variable to stuff to
 *
 * @details The binary, hexadecimal, and octal formats must be prefixed by their associated string.
 *   Ex: "0xDEADBEEF" would be parsed properly while "DEADBEEF" would throw an error
 *
 * @throws errParse if an unexpected or otherwise malformed float string is found.
 * @throws errParse if nothing was found
 */
void dc_stuff_uint(uint *i);

/**
 * @brief Stuffs an unsigned byte to the given variable. Supports binary (0b), hexadecimal (0x), and octal (0o) formats
 *
 * @param[in] i  The ubyte variable to stuff to
 *
 * @details The binary, hexadecimal, and octal formats must be prefixed by their associated string.
 *   Ex: "0x0F" would be parsed properly while "0F" would throw an error
 *
 * @throws errParse if an unexpected or otherwise malformed float string is found.
 * @throws errParse if nothing was found
 */
void dc_stuff_ubyte(ubyte *i);

/**
 * @brief stuffs a boolean evaluated integer or string into the given variable.
 *
 * @param[in] b The bool variable to stuff to
 *
 * @details Supports a number of literal strings as true and false, including "true", "false", "yes", "no" and the
 *   yes/no equivalents in other languages supported in localization.
 *   TODO: Make a static string map to handle this instead of being hard-coded
 *
 * @throws errParse if an unexpected or otherwise malformed float string is found.
 * @throws errParse if nothing was found
 */
void dc_stuff_boolean(bool *b);

/**
 * @brief stuffs a boolean evaluated integer or string into the given variable.
 *
 * @param[in] i The int variable to stuff to. 0 is false, 1 is true
 *
 * @details Supports a number of literal strings as true and false, including "true", "false", "yes", "no" and the
 *   yes/no equivalents in other languages supported in localization.
 *   TODO: Make a static string map to handle this instead of being hard-coded
 *
 * @throws errParse if an unexpected or otherwise malformed float string is found.
 * @throws errParse if nothing was found
 */
void dc_stuff_boolean(int *i);

/**
 * @brief Stuffs a string to out_str from the command line, stopping at the end of the command line
 *
 * @param[out] str  Destination string
 * @param[in]  maxlen   Maximum length to copy. (maxlen <= sizeof(str)) && (maxlen <= MAX_TOKEN_LENGTH)
 *
 * @throws errParse when nothing left was found on the command line
 * @throws errParseOverflow when parser cannot stuff the entirety of the found string into out_str
 */
void dc_stuff_string(char *str, size_t maxlen);

/**
 * @brief Stuffs a string to out_str from the command line, stopping at the end of the command line
 *
 * @param[out] str  Destination string
 *
 * @throws errParse when nothing left was found on the command line
 */
void dc_stuff_string(SCP_string &str);

/**
 * @brief Stuffs a whitespace delimited string to out_str from the command line, stopping at the end of the command line
 *
 * @param[out] str  Destination string
 * @param[in]  len   Maximum length to copy. (len <= sizeof(str)) && (len <= MAX_TOKEN_LENGTH)
 *
 * @throws errParse when nothing left was found on the command line
 * @throws errParseOverflow when parser cannot stuff the entirety of the found string into out_str
 */
void dc_stuff_string_white(char *str, size_t len);

/**
 * @brief Stuffs a whitespace delimited string to out_str from the command line, stopping at the end of the command line
 *
 * @param[out] str  Destination string
 *
 * @throws errParse when nothing left was found on the command line
 */
void dc_stuff_string_white(SCP_string &str);

/**
 * @brief Tries to stuff a float from the Command_string.
 *
 * @param[in] f  The float variable to maybe stuff.
 *
 * @details
 *   If there's nothing on the command line, *f = 0 and false is returned
 *
 *   If there's something on the command line, and we're able to convert it, *f = the converted value, true is
 *     returned, and the parser is advanced past the token
 *
 *   If there's something on command line, but we can't convert it, an errParse is thrown
 */
bool dc_maybe_stuff_float(float *f);

/**
 * @brief Tries to stuff an int from the Command_string.
 *
 * @param[in] i  The int variable to maybe stuff.
 *
 * @details
 *   If there's nothing on the command line, *i = 0 and false is returned
 *
 *   If there's something on the command line, and we're able to convert it, *i = the converted value, true is
 *     returned, and the parser is advanced past the token
 *
 *   If there's something on command line, but we can't convert it, an errParse is thrown
 */
bool dc_maybe_stuff_int(int *i);

/**
 * @brief Tries to stuff an uint from the Command_string.
 *
 * @param[in] i  The uint variable to maybe stuff.
 *
 * @details
 *   If there's nothing on the command line, *i = 0 and false is returned
 *
 *   If there's something on the command line, and we're able to convert it, *i = the converted value, true is
 *     returned, and the parser is advanced past the token
 *
 *   If there's something on command line, but we can't convert it, an errParse is thrown
 */
bool dc_maybe_stuff_uint(uint *i);

/**
 * @brief Tries to stuff an ubyte from the Command_string.
 *
 * @param[in] i  The ubyte variable to maybe stuff.
 *
 * @details
 *   If there's nothing on the command line, *i = 0 and false is returned
 *
 *   If there's something on the command line, and we're able to convert it, *i = the converted value, true is
 *     returned, and the parser is advanced past the token
 *
 *   If there's something on command line, but we can't convert it, an errParse is thrown
 */
bool dc_maybe_stuff_ubyte(ubyte *i);

/**
 * @brief Tries to stuff a bool from the Command_string.
 *
 * @param[in] b  The bool variable to maybe stuff.
 *
 * @details
 *   If there's nothing on the command line, *b = false and false is returned
 *
 *   If there's something on the command line, and we're able to convert it, *b = the converted value, true is
 *     returned, and the parser is advanced past the token
 *
 *   If there's something on command line, but we can't convert it, an errParse is thrown
 */
bool dc_maybe_stuff_boolean(bool *b);

/**
 * @brief Tries to stuff an int with a bool value from the Command_string.
 *
 * @param[in] i  The int variable to maybe stuff.
 *
 * @details
 *   If there's nothing on the command line, *i = 0 and false is returned
 *
 *   If there's something on the command line, and we're able to convert it, *i = the converted value, true is
 *     returned, and the parser is advanced past the token
 *
 *   If there's something on command line, but we can't convert it, an errParse is thrown
 */
bool dc_maybe_stuff_boolean(int *i);

/**
 * @brief Tries to stuff a string to out_str from the command line, stopping at the end of the command line
 *
 * @param[out] str  Destination string. If nothing was found, str = ""
 * @param[in]  len   Maximum length to copy. (len <= sizeof(str)) && (len <= MAX_TOKEN_LENGTH)
 *
 * @retval true if the operation was successful,
 * @retval false otherwise
 *
 * @throws errParseOverflow when parser cannot stuff the entirety of the found string into out_str
 */
bool dc_maybe_stuff_string(char *str, size_t len);

/**
 * @brief Tries to stuff a string to out_str from the command line, stopping at the end of the command line
 *
 * @param[out] str  Destination string. If nothing was found, str = ""
 *
 * @retval true if the operation was successful,
 * @retval false otherwise
 */
bool dc_maybe_stuff_string(SCP_string &str);

/**
 * @brief Tries to stuff a whitespace delimited string to out_str from the command line, stopping at the end of the command line
 *
 * @param[out] str  Destination string. If nothing was found, str = ""
 * @param[in]  len   Maximum length to copy. (maxlen <= sizeof(str)) && (maxlen <= MAX_TOKEN_LENGTH)
 *
 * @retval true if the operation was successful,
 * @retval false otherwise
 *
 * @throws errParseOverflow when parser cannot stuff the entirety of the found string into out_str
 */
bool dc_maybe_stuff_string_white(char *str, size_t len);

/**
 * @brief Tries to stuff a whitespace delimited string to out_str from the command line, stopping at the end of the command line
 *
 * @param[out] str  Destination string. If nothing was found, str = ""
 *
 * @retval true if the operation was successful,
 * @retval false otherwise
 */
bool dc_maybe_stuff_string_white(SCP_string &str);

#endif // _CONSOLEPARSE_H