1 /** Init file parser library 2 * 3 * The basic structure of the parser is as follows: there is a table of hooks 4 * which are run when a directive matching their format is encountered. When the 5 * hook is called, all the arguments it declares in its format have been parsed 6 * out and can be accessed with parser_get*(). See the unit tests for examples. 7 */ 8 #ifndef PARSER_H 9 #define PARSER_H 10 11 #include "h-basic.h" 12 #include "z-bitflag.h" 13 #include "z-rand.h" 14 15 struct parser; 16 17 enum parser_error { 18 PARSE_ERROR_NONE = 0, 19 PARSE_ERROR_GENERIC, 20 PARSE_ERROR_INVALID_FLAG, 21 PARSE_ERROR_INVALID_ITEM_NUMBER, 22 PARSE_ERROR_INVALID_SPELL_FREQ, 23 PARSE_ERROR_INVALID_VALUE, 24 PARSE_ERROR_INVALID_COLOR, 25 PARSE_ERROR_INVALID_EFFECT, 26 PARSE_ERROR_INVALID_OPTION, 27 PARSE_ERROR_MISSING_FIELD, 28 PARSE_ERROR_MISSING_RECORD_HEADER, 29 PARSE_ERROR_FIELD_TOO_LONG, 30 PARSE_ERROR_NON_SEQUENTIAL_RECORDS, 31 PARSE_ERROR_NOT_NUMBER, 32 PARSE_ERROR_NOT_RANDOM, 33 PARSE_ERROR_OBSOLETE_FILE, 34 PARSE_ERROR_OUT_OF_BOUNDS, 35 PARSE_ERROR_OUT_OF_MEMORY, 36 PARSE_ERROR_TOO_FEW_ENTRIES, 37 PARSE_ERROR_TOO_MANY_ENTRIES, 38 PARSE_ERROR_UNDEFINED_DIRECTIVE, 39 PARSE_ERROR_UNRECOGNISED_BLOW, 40 PARSE_ERROR_UNRECOGNISED_TVAL, 41 PARSE_ERROR_UNRECOGNISED_SVAL, 42 PARSE_ERROR_VAULT_TOO_BIG, 43 PARSE_ERROR_INTERNAL, 44 45 PARSE_ERROR_MAX 46 }; 47 48 struct parser_state { 49 enum parser_error error; 50 unsigned int line; 51 unsigned int col; 52 char *msg; 53 }; 54 55 struct file_parser { 56 const char *name; 57 struct parser *(*init)(void); 58 errr (*run)(struct parser *p); 59 errr (*finish)(struct parser *p); 60 void (*cleanup)(void); 61 }; 62 63 extern const char *parser_error_str[PARSE_ERROR_MAX]; 64 65 /** Allocates a new parser. */ 66 extern struct parser *parser_new(void); 67 68 /** Parses the provided line. 69 * 70 * This runs the first parser hook registered with `p` that matches `line`. 71 */ 72 extern enum parser_error parser_parse(struct parser *p, const char *line); 73 74 /** Destroys a parser. */ 75 extern void parser_destroy(struct parser *p); 76 77 /** Gets parser's private data. */ 78 extern void *parser_priv(struct parser *p); 79 80 /** Sets parser's private data. 81 * 82 * This is commonly used to store context for stateful parsing. 83 */ 84 extern void parser_setpriv(struct parser *p, void *v); 85 86 /** Registers a parser hook. 87 * 88 * Hooks have the following format: 89 * <fmt> ::= <name> [<type> <name>]* [?<type> <name>]* 90 * <type> ::= int | str | sym | rand | char 91 * The first <name> is called the directive for this hook. Any other hooks with 92 * the same directive are superseded by this hook. It is an error for a 93 * mandatory field to follow an optional field. It is an error for any field to 94 * follow a field of type `str`, since `str` fields are not delimited and will 95 * consume the entire rest of the line. 96 */ 97 extern errr parser_reg(struct parser *p, const char *fmt, 98 enum parser_error (*func)(struct parser *p)); 99 100 /** A placeholder parse hook indicating a value is ignored */ 101 extern enum parser_error ignored(struct parser *p); 102 103 /** Returns whether the parser has a value named `name`. 104 * 105 * Used to test for presence of optional values. 106 */ 107 extern bool parser_hasval(struct parser *p, const char *name); 108 109 /** Returns the symbol named `name`. This symbol must exist. */ 110 extern const char *parser_getsym(struct parser *p, const char *name); 111 112 /** Returns the string named `name`. This symbol must exist. */ 113 extern const char *parser_getstr(struct parser *p, const char *name); 114 115 /** Returns the integer named `name`. This symbol must exist. */ 116 extern int parser_getint(struct parser *p, const char *name); 117 118 /** Returns the unsigned integer named `name`. This symbol must exist. */ 119 extern unsigned int parser_getuint(struct parser *p, const char *name); 120 121 /** Returns the random value named `name`. This symbol must exist. */ 122 extern struct random parser_getrand(struct parser *p, const char *name); 123 124 /** Returns the character named `name`. This symbol must exist. */ 125 extern wchar_t parser_getchar(struct parser *p, const char *name); 126 127 /** Fills the provided struct with the parser's state, if any. Returns true if 128 * the parser is in an error state, and false otherwise. 129 */ 130 extern int parser_getstate(struct parser *p, struct parser_state *s); 131 132 /** Sets the parser's detailed error description and field number. */ 133 extern void parser_setstate(struct parser *p, unsigned int col, const char *msg); 134 135 errr run_parser(struct file_parser *fp); 136 void cleanup_parser(struct file_parser *fp); 137 int lookup_flag(const char **flag_table, const char *flag_name); 138 errr grab_flag(bitflag *flags, const size_t size, const char **flag_table, const char *flag_name); 139 errr remove_flag(bitflag *flags, const size_t size, const char **flag_table, const char *flag_name); 140 141 #endif /* !PARSER_H */ 142