parser.h (6810B)
1 #ifndef PARSER_H 2 #define PARSER_H 3 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <stdint.h> 7 #include <string.h> 8 9 #include "../../config/config.h" 10 #include "flatcc/flatcc.h" 11 #include "symbols.h" 12 13 #define ELEM_BUFSIZ (64 * 1024) 14 #define ERROR_BUFSIZ 200 15 16 #define REVERT_LIST(TYPE, FIELD, HEAD) \ 17 do { \ 18 TYPE *tmp__next, *tmp__prev = 0, *tmp__link = *(HEAD); \ 19 while (tmp__link) { \ 20 tmp__next = tmp__link->FIELD; \ 21 tmp__link->FIELD = tmp__prev; \ 22 tmp__prev = tmp__link; \ 23 tmp__link = tmp__next; \ 24 } \ 25 *(HEAD) = tmp__prev; \ 26 } while (0) 27 28 typedef struct fb_parser fb_parser_t; 29 typedef flatcc_options_t fb_options_t; 30 31 typedef void (*fb_error_fun)(void *err_ctx, const char *buf, size_t len); 32 33 void __flatcc_fb_default_error_out(void *err_ctx, const char *buf, size_t len); 34 #define fb_default_error_out __flatcc_fb_default_error_out 35 36 int __flatcc_fb_print_error(fb_parser_t *P, const char * format, ...); 37 #define fb_print_error __flatcc_fb_print_error 38 39 struct fb_parser { 40 fb_parser_t *dependencies; 41 fb_parser_t *inverse_dependencies; 42 fb_error_fun error_out; 43 void *error_ctx; 44 45 const char *managed_input; 46 47 fb_token_t *ts, *te; 48 int tcapacity; 49 int doc_mode; 50 fb_doc_t *doc; 51 fb_token_t *token; 52 53 size_t elem_end; 54 void *elem_buffers; 55 size_t elem; 56 size_t offset_size; 57 58 const char *line; 59 long linenum; 60 61 /* Internal id (not a pointer into token stream). */ 62 fb_token_t t_none; 63 fb_token_t t_ubyte; 64 65 int failed; 66 67 unsigned char *tmp_field_marker; 68 fb_symbol_t **tmp_field_index; 69 int nesting_level; 70 71 int has_schema; 72 fb_options_t opts; 73 fb_schema_t schema; 74 fb_scope_t *root_scope; 75 fb_scope_t *current_scope; 76 char *path; 77 char *referer_path; 78 }; 79 80 static inline void checkmem(const void *p) 81 { 82 if (!p) { 83 fprintf(stderr, "error: out of memory, aborting...\n"); 84 exit(1); 85 } 86 } 87 88 static inline void *new_elem(fb_parser_t *P, size_t size) 89 { 90 size_t elem; 91 void *buf; 92 93 size = (size + 15) & ~(size_t)15; 94 elem = P->elem; 95 if (elem + size > P->elem_end) { 96 buf = calloc(ELEM_BUFSIZ, 1); 97 checkmem(buf); 98 *(void**)buf = P->elem_buffers; 99 P->elem_buffers = buf; 100 elem = P->elem = (size_t)buf + 16; 101 P->elem_end = (size_t)buf + ELEM_BUFSIZ; 102 } 103 P->elem += size; 104 return (void*)elem; 105 } 106 107 int __flatcc_fb_print_error(fb_parser_t *P, const char * format, ...); 108 #define fb_print_error __flatcc_fb_print_error 109 110 const char *__flatcc_error_find_file_of_token(fb_parser_t *P, fb_token_t *t); 111 #define error_find_file_of_token __flatcc_error_find_file_of_token 112 113 /* 114 * This is the primary error reporting function. 115 * The parser is flagged as failed and error count incremented. 116 * 117 * If s is not null, then s, len replaces the token text of `t` but 118 * still reports the location of t. `peer` is optional and prints the 119 * token location and text and the end of the message. 120 * `msg` may be the only non-zero argument besides `P`. 121 * 122 * Various helper functions are available for the various cases. 123 * 124 * `fb_print_error` may be called instead to generate text to the error 125 * output that is not counted as an error. 126 */ 127 void __flatcc_error_report(fb_parser_t *P, fb_token_t *t, const char *msg, fb_token_t *peer, const char *s, size_t len); 128 #define error_report __flatcc_error_report 129 130 static void error_tok_2(fb_parser_t *P, fb_token_t *t, const char *msg, fb_token_t *peer) 131 { 132 error_report(P, t, msg, peer, 0, 0); 133 } 134 135 static inline void error_tok(fb_parser_t *P, fb_token_t *t, const char *msg) 136 { 137 error_tok_2(P, t, msg, 0); 138 } 139 140 /* Only use the token location. */ 141 static inline void error_tok_as_string(fb_parser_t *P, fb_token_t *t, const char *msg, char *s, size_t len) 142 { 143 error_report(P, t, msg, 0, s, len); 144 } 145 146 static inline void error(fb_parser_t *P, const char *msg) 147 { 148 error_tok(P, 0, msg); 149 } 150 151 static inline void error_name(fb_parser_t *P, fb_name_t *name, const char *msg) 152 { 153 if (!name) { 154 error(P, msg); 155 } else { 156 error_report(P, 0, msg, 0, name->name.s.s, (size_t)name->name.s.len); 157 } 158 } 159 160 static inline void error_sym(fb_parser_t *P, fb_symbol_t *s, const char *msg) 161 { 162 error_tok(P, s->ident, msg); 163 } 164 165 static inline void error_sym_2(fb_parser_t *P, fb_symbol_t *s, const char *msg, fb_symbol_t *s2) 166 { 167 error_tok_2(P, s->ident, msg, s2->ident); 168 } 169 170 static inline void error_sym_tok(fb_parser_t *P, fb_symbol_t *s, const char *msg, fb_token_t *t2) 171 { 172 error_tok_2(P, s->ident, msg, t2); 173 } 174 175 void error_ref_sym(fb_parser_t *P, fb_ref_t *ref, const char *msg, fb_symbol_t *s2); 176 177 static inline void error_ref(fb_parser_t *P, fb_ref_t *ref, const char *msg) 178 { 179 error_ref_sym(P, ref, msg, 0); 180 } 181 182 /* 183 * If `opts` is null, defaults options are being used, otherwise opts is 184 * copied into the parsers options. The name may be path, the basename 185 * without default extension will be extracted. The `error_out` funciton is 186 * optional, otherwise output is printed to stderr, truncated to a 187 * reasoanble size per error. `error_ctx` is provided as argument to 188 * `error_out` if non-zero, and otherwise ignored. 189 * 190 * This api only deals with a single schema file so a parent level 191 * driver must handle file inclusion and update P->dependencies but 192 * order is not significant (parse order is, but this is handled by 193 * updating the `include_index` in the root schema). 194 * 195 * P->dependencies must be cleared by callee in any order but once one 196 * is cleared the entire structure should be taken down because symbols 197 * trees point everywhere. For parses without file inclusion 198 * dependencies will be null. Dependencies are not handled at this 199 * level. P->inverse_dependencies is just the reverse list. 200 * 201 * The file at the head of the dependencies list is the root and the 202 * one that provides the root schema. Other root schemas are not used. 203 */ 204 int __flatcc_fb_init_parser(fb_parser_t *P, fb_options_t *opts, const char *name, 205 fb_error_fun error_out, void *error_ctx, fb_root_schema_t *rs); 206 #define fb_init_parser __flatcc_fb_init_parser 207 208 int __flatcc_fb_parse(fb_parser_t *P, const char *input, size_t len, int own_buffer); 209 #define fb_parse __flatcc_fb_parse 210 211 void __flatcc_fb_clear_parser(fb_parser_t *P); 212 #define fb_clear_parser __flatcc_fb_clear_parser 213 214 #endif /* PARSER_H */