Branch data Line data Source code
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, int len);
32 : :
33 : : void __flatcc_fb_default_error_out(void *err_ctx, const char *buf, int 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 : : int nesting_level;
69 : :
70 : : int has_schema;
71 : : fb_options_t opts;
72 : : fb_schema_t schema;
73 : : fb_scope_t *current_scope;
74 : : char *path;
75 : : char *referer_path;
76 : : };
77 : :
78 : 678 : static inline void checkmem(const void *p)
79 : : {
80 [ - + ]: 678 : if (!p) {
81 : 0 : fprintf(stderr, "error: out of memory, aborting...\n");
82 : 0 : exit(1);
83 : : }
84 : 678 : }
85 : :
86 : 2144 : static inline void *new_elem(fb_parser_t *P, int size)
87 : : {
88 : : size_t elem;
89 : : void *buf;
90 : :
91 : 2144 : size = (size + 15) & ~15;
92 : 2144 : elem = P->elem;
93 [ + + ]: 2144 : if (elem + size > P->elem_end) {
94 : 34 : buf = calloc(ELEM_BUFSIZ, 1);
95 : 34 : checkmem(buf);
96 : 34 : *(void**)buf = P->elem_buffers;
97 : 34 : P->elem_buffers = buf;
98 : 34 : elem = P->elem = (size_t)buf + 16;
99 : 34 : P->elem_end = (size_t)buf + ELEM_BUFSIZ;
100 : : }
101 : 2144 : P->elem += size;
102 : 2144 : return (void*)elem;
103 : : }
104 : :
105 : : int __flatcc_fb_print_error(fb_parser_t *P, const char * format, ...);
106 : : #define fb_print_error __flatcc_fb_print_error
107 : :
108 : : const char *__flatcc_error_find_file_of_token(fb_parser_t *P, fb_token_t *t);
109 : : #define error_find_file_of_token __flatcc_error_find_file_of_token
110 : :
111 : : /*
112 : : * This is the primary error reporting function.
113 : : * The parser is flagged as failed and error count incremented.
114 : : *
115 : : * If s is not null, then s, len replaces the token text of `t` but
116 : : * still reports the location of t. `peer` is optional and prints the
117 : : * token location and text and the end of the message.
118 : : * `msg` may be the only non-zero argument besides `P`.
119 : : *
120 : : * Various helper functions are available for the various cases.
121 : : *
122 : : * `fb_print_error` may be called instead to generate text to the error
123 : : * output that is not counted as an error.
124 : : */
125 : : void __flatcc_error_report(fb_parser_t *P, fb_token_t *t, const char *msg, fb_token_t *peer, const char *s, int len);
126 : : #define error_report __flatcc_error_report
127 : :
128 : : static void error_tok_2(fb_parser_t *P, fb_token_t *t, const char *msg, fb_token_t *peer)
129 : : {
130 : 523 : error_report(P, t, msg, peer, 0, 0);
131 : : }
132 : :
133 : : static inline void error_tok(fb_parser_t *P, fb_token_t *t, const char *msg)
134 : : {
135 : : error_tok_2(P, t, msg, 0);
136 : : }
137 : :
138 : : /* Only use the token location. */
139 : : static inline void error_tok_as_string(fb_parser_t *P, fb_token_t *t, const char *msg, char *s, int len)
140 : : {
141 : 0 : error_report(P, t, msg, 0, s, len);
142 : : }
143 : :
144 : : static inline void error(fb_parser_t *P, const char *msg)
145 : : {
146 : : error_tok(P, 0, msg);
147 : : }
148 : :
149 : 0 : static inline void error_name(fb_parser_t *P, fb_name_t *name, const char *msg)
150 : : {
151 [ # # ]: 0 : if (!name) {
152 : : error(P, msg);
153 : : } else {
154 : 0 : error_report(P, 0, msg, 0, name->name.s.s, name->name.s.len);
155 : : }
156 : 0 : }
157 : :
158 : : static inline void error_sym(fb_parser_t *P, fb_symbol_t *s, const char *msg)
159 : : {
160 : : error_tok(P, s->ident, msg);
161 : : }
162 : :
163 : : static inline void error_sym_2(fb_parser_t *P, fb_symbol_t *s, const char *msg, fb_symbol_t *s2)
164 : : {
165 : : error_tok_2(P, s->ident, msg, s2->ident);
166 : : }
167 : :
168 : : static inline void error_sym_tok(fb_parser_t *P, fb_symbol_t *s, const char *msg, fb_token_t *t2)
169 : : {
170 : : error_tok_2(P, s->ident, msg, t2);
171 : : }
172 : :
173 : : void error_ref_sym(fb_parser_t *P, fb_ref_t *ref, const char *msg, fb_symbol_t *s2);
174 : :
175 : : static inline void error_ref(fb_parser_t *P, fb_ref_t *ref, const char *msg)
176 : : {
177 : 0 : error_ref_sym(P, ref, msg, 0);
178 : : }
179 : :
180 : : /*
181 : : * If `opts` is null, defaults options are being used, otherwise opts is
182 : : * copied into the parsers options. The name may be path, the basename
183 : : * without default extension will be extracted. The `error_out` funciton is
184 : : * optional, otherwise output is printed to stderr, truncated to a
185 : : * reasoanble size per error. `error_ctx` is provided as argument to
186 : : * `error_out` if non-zero, and otherwise ignored.
187 : : *
188 : : * This api only deals with a single schema file so a parent level
189 : : * driver must handle file inclusion and update P->dependencies but
190 : : * order is not significant (parse order is, but this is handled by
191 : : * updating the `include_index` in the root schema).
192 : : *
193 : : * P->dependencies must be cleared by callee in any order but once one
194 : : * is cleared the entire structure should be taken down because symbols
195 : : * trees point everywhere. For parses without file inclusion
196 : : * dependencies will be null. Dependencies are not handled at this
197 : : * level. P->inverse_dependencies is just the reverse list.
198 : : *
199 : : * The file at the head of the dependencies list is the root and the
200 : : * one that provides the root schema. Other root schemas are not used.
201 : : */
202 : : int __flatcc_fb_init_parser(fb_parser_t *P, fb_options_t *opts, const char *name,
203 : : fb_error_fun error_out, void *error_ctx, fb_root_schema_t *rs);
204 : : #define fb_init_parser __flatcc_fb_init_parser
205 : :
206 : : int __flatcc_fb_parse(fb_parser_t *P, const char *input, size_t len, int own_buffer);
207 : : #define fb_parse __flatcc_fb_parse
208 : :
209 : : void __flatcc_fb_clear_parser(fb_parser_t *P);
210 : : #define fb_clear_parser __flatcc_fb_clear_parser
211 : :
212 : : #endif /* PARSER_H */
|