Branch data Line data Source code
1 : : #include "codegen_c.h"
2 : :
3 : : #include "flatcc/flatcc_types.h"
4 : :
5 : : /* -DFLATCC_PORTABLE may help if inttypes.h is missing. */
6 : : #ifndef PRId64
7 : : #include <inttypes.h>
8 : : #endif
9 : :
10 : 23 : static int gen_verifier_pretext(fb_output_t *out)
11 : : {
12 : 23 : fprintf(out->fp,
13 : : "#ifndef %s_VERIFIER_H\n"
14 : : "#define %s_VERIFIER_H\n",
15 : 23 : out->S->basenameup, out->S->basenameup);
16 : :
17 : 23 : fprintf(out->fp, "\n/* " FLATCC_GENERATED_BY " */\n\n");
18 : : /* Needed to get the file identifiers */
19 : 23 : fprintf(out->fp, "#ifndef %s_READER_H\n", out->S->basenameup);
20 : 23 : fprintf(out->fp, "#include \"%s_reader.h\"\n", out->S->basename);
21 : 23 : fprintf(out->fp, "#endif\n");
22 : 23 : fprintf(out->fp, "#include \"flatcc/flatcc_verifier.h\"\n");
23 : 23 : fb_gen_c_includes(out, "_verifier.h", "_VERIFIER_H");
24 : : gen_pragma_push(out);
25 : 23 : fprintf(out->fp, "\n");
26 : 23 : return 0;
27 : : }
28 : :
29 : 23 : static int gen_verifier_footer(fb_output_t *out)
30 : : {
31 : : gen_pragma_pop(out);
32 : 23 : fprintf(out->fp,
33 : : "#endif /* %s_VERIFIER_H */\n",
34 : 23 : out->S->basenameup);
35 : 23 : return 0;
36 : : }
37 : :
38 : 16 : static int gen_union_verifier(fb_output_t *out, fb_compound_type_t *ct)
39 : : {
40 : : fb_symbol_t *sym;
41 : : fb_member_t *member;
42 : : fb_scoped_name_t snt, snref;
43 : :
44 : 8 : fb_clear(snt);
45 : 8 : fb_clear(snref);
46 : : fb_compound_name(ct, &snt);
47 : :
48 : 8 : fprintf(out->fp,
49 : : "static int __%s_union_verifier(flatcc_table_verifier_descriptor_t *td, flatbuffers_voffset_t id, uint8_t type)\n{\n switch(type) {\n",
50 : : snt.text);
51 [ + + ]: 31 : for (sym = ct->members; sym; sym = sym->link) {
52 : : member = (fb_member_t *)sym;
53 [ + + ]: 23 : if (member->type.type == vt_missing) {
54 : : /* NONE is of type vt_missing and already handled. */
55 : 8 : continue;
56 : : }
57 : : assert(member->type.type == vt_compound_type_ref);
58 : 15 : fb_compound_name(member->type.ct, &snref);
59 : 15 : fprintf(out->fp,
60 : : " case %u: return flatcc_verify_table_field(td, id, 0, __%s_table_verifier);\n",
61 : 15 : (unsigned)member->value.u, snref.text);
62 : : }
63 : 8 : fprintf(out->fp,
64 : : " default: return flatcc_verify_ok;\n }\n}\n\n");
65 : 8 : return 0;
66 : : }
67 : :
68 : 52 : static int gen_table_verifier(fb_output_t *out, fb_compound_type_t *ct)
69 : : {
70 : : fb_symbol_t *sym;
71 : : fb_member_t *member;
72 : : fb_scoped_name_t snt, snref;
73 : : int required, first = 1;
74 : 52 : const char *nsc = out->nsc;
75 : :
76 : 52 : fb_clear(snt);
77 : 52 : fb_clear(snref);
78 : : fb_compound_name(ct, &snt);
79 : :
80 : 52 : fprintf(out->fp,
81 : : "static int __%s_table_verifier(flatcc_table_verifier_descriptor_t *td)\n{\n",
82 : : snt.text);
83 : :
84 [ + + ]: 353 : for (sym = ct->members; sym; sym = sym->link) {
85 : : member = (fb_member_t *)sym;
86 [ + + ]: 301 : if (member->metadata_flags & fb_f_deprecated) {
87 : 8 : continue;
88 : : }
89 : :
90 [ + + ]: 293 : if (first) {
91 : 45 : fprintf(out->fp, " int ret;\n if ((ret = ");
92 : : } else {
93 : 248 : fprintf(out->fp, ")) return ret;\n if ((ret = ");
94 : : }
95 : : first = 0;
96 : 293 : required = (member->metadata_flags & fb_f_required) != 0;
97 [ + + + + : 293 : switch (member->type.type) {
+ + - ]
98 : : case vt_scalar_type:
99 : 131 : fprintf(
100 : : out->fp,
101 : : "flatcc_verify_field(td, %"PRIu64", %"PRIu16", %"PRIu64")",
102 : 131 : member->id, member->align, member->size);
103 : 131 : break;
104 : : case vt_vector_type:
105 [ + + ]: 23 : if (member->nest) {
106 : : fb_compound_name((fb_compound_type_t *)&member->nest->symbol, &snref);
107 [ + - ]: 7 : if (member->nest->symbol.kind == fb_is_table) {
108 : 7 : fprintf(out->fp,
109 : : "flatcc_verify_table_as_nested_root(td, %"PRIu64", "
110 : : "%u, 0, %"PRIu16", __%s_table_verifier)",
111 : 7 : member->id, required, member->align, snref.text);
112 : : } else {
113 : 0 : fprintf(out->fp,
114 : : "flatcc_verify_struct_as_nested_root(td, %"PRIu64", "
115 : : "%u, 0, %"PRIu16", %"PRIu64")",
116 : 0 : member->id, required, member->align, member->size);
117 : : }
118 : : } else {
119 [ + - ]: 16 : fprintf(out->fp,
120 : : "flatcc_verify_vector_field(td, %"PRIu64", %d, %"PRId16", %"PRIu64", %"PRIu64"ULL)",
121 : 32 : member->id, required, member->align, member->size, (uint64_t)FLATBUFFERS_COUNT_MAX(member->size));
122 : : };
123 : : break;
124 : : case vt_string_type:
125 : 23 : fprintf(out->fp,
126 : : "flatcc_verify_string_field(td, %"PRIu64", %d)",
127 : : member->id, required);
128 : 23 : break;
129 : : case vt_vector_string_type:
130 : 7 : fprintf(out->fp,
131 : : "flatcc_verify_string_vector_field(td, %"PRIu64", %d)",
132 : : member->id, required);
133 : 7 : break;
134 : : case vt_compound_type_ref:
135 : 94 : fb_compound_name(member->type.ct, &snref);
136 [ + + + - ]: 94 : switch (member->type.ct->symbol.kind) {
137 : : case fb_is_enum:
138 : : case fb_is_struct:
139 : 65 : fprintf(out->fp,
140 : : "flatcc_verify_field(td, %"PRIu64", %"PRIu16", %"PRIu64")",
141 : 65 : member->id, member->align, member->size);
142 : 65 : break;
143 : : case fb_is_table:
144 : 21 : fprintf(out->fp,
145 : : "flatcc_verify_table_field(td, %"PRIu64", %d, &__%s_table_verifier)",
146 : : member->id, required, snref.text);
147 : 21 : break;
148 : : case fb_is_union:
149 : 8 : fprintf(out->fp,
150 : : "flatcc_verify_union_field(td, %"PRIu64", %d, &__%s_union_verifier)",
151 : : member->id, required, snref.text);
152 : 8 : break;
153 : : default:
154 : 0 : gen_panic(out, "internal error: unexpected compound type for table verifier");
155 : : return -1;
156 : : }
157 : : break;
158 : : case vt_vector_compound_type_ref:
159 : 15 : fb_compound_name(member->type.ct, &snref);
160 [ + + - ]: 15 : switch (member->type.ct->symbol.kind) {
161 : : case fb_is_table:
162 : 8 : fprintf(out->fp,
163 : : "flatcc_verify_table_vector_field(td, %"PRIu64", %d, &__%s_table_verifier)",
164 : : member->id, required, snref.text);
165 : 8 : break;
166 : : case fb_is_enum:
167 : : case fb_is_struct:
168 [ + - ]: 7 : fprintf(out->fp,
169 : : "flatcc_verify_vector_field(td, %"PRIu64", %d, %"PRId16", %"PRIu64", %"PRIu64"ULL)",
170 : 14 : member->id, required, member->align, member->size, (uint64_t)FLATBUFFERS_COUNT_MAX(member->size));
171 : 7 : break;
172 : : default:
173 : 0 : gen_panic(out, "internal error: unexpected vector compound type for table verifier");
174 : : return -1;
175 : : }
176 : : break;
177 : : }
178 : 293 : fprintf(out->fp, " /* %.*s */", (int)sym->ident->len, sym->ident->text);
179 : : }
180 [ + + ]: 52 : if (!first) {
181 : 45 : fprintf(out->fp, ")) return ret;\n");
182 : : }
183 : 52 : fprintf(out->fp, " return flatcc_verify_ok;\n");
184 : 52 : fprintf(out->fp, "}\n\n");
185 : 52 : fprintf(out->fp,
186 : : "static inline int %s_verify_as_root(const void *buf, size_t bufsiz)\n"
187 : : "{\n return flatcc_verify_table_as_root(buf, bufsiz, %s_identifier, &__%s_table_verifier);\n}\n\n",
188 : : snt.text, snt.text, snt.text);
189 : 52 : fprintf(out->fp,
190 : : "static inline int %s_verify_as_typed_root(const void *buf, size_t bufsiz)\n"
191 : : "{\n return flatcc_verify_table_as_root(buf, bufsiz, %s_type_identifier, &__%s_table_verifier);\n}\n\n",
192 : : snt.text, snt.text, snt.text);
193 : 52 : fprintf(out->fp,
194 : : "static inline int %s_verify_as_root_with_identifier(const void *buf, size_t bufsiz, const char *fid)\n"
195 : : "{\n return flatcc_verify_table_as_root(buf, bufsiz, fid, &__%s_table_verifier);\n}\n\n",
196 : : snt.text, snt.text);
197 : 52 : fprintf(out->fp,
198 : : "static inline int %s_verify_as_root_with_type_hash(const void *buf, size_t bufsiz, %sthash_t thash)\n"
199 : : "{\n return flatcc_verify_table_as_typed_root(buf, bufsiz, thash, &__%s_table_verifier);\n}\n\n",
200 : : snt.text, nsc, snt.text);
201 : : return 0;
202 : : }
203 : :
204 : 36 : static int gen_struct_verifier(fb_output_t *out, fb_compound_type_t *ct)
205 : : {
206 : : fb_scoped_name_t snt;
207 : :
208 : 36 : fb_clear(snt);
209 : : fb_compound_name(ct, &snt);
210 : :
211 : 36 : fprintf(out->fp,
212 : : "static inline int %s_verify_as_root(const void *buf, size_t bufsiz)\n"
213 : : "{\n return flatcc_verify_struct_as_root(buf, bufsiz, %s_identifier, %"PRIu16", %"PRIu64");\n}\n\n",
214 : 36 : snt.text, snt.text, ct->align, ct->size);
215 : 36 : fprintf(out->fp,
216 : : "static inline int %s_verify_as_typed_root(const void *buf, size_t bufsiz)\n"
217 : : "{\n return flatcc_verify_struct_as_typed_root(buf, bufsiz, %s_type_hash, %"PRIu16", %"PRIu64");\n}\n\n",
218 : 36 : snt.text, snt.text, ct->align, ct->size);
219 : 36 : fprintf(out->fp,
220 : : "static inline int %s_verify_as_root_with_type_hash(const void *buf, size_t bufsiz, %sthash_t thash)\n"
221 : : "{\n return flatcc_verify_struct_as_typed_root(buf, bufsiz, thash, %"PRIu16", %"PRIu64");\n}\n\n",
222 : 72 : snt.text, out->nsc, ct->align, ct->size);
223 : 36 : fprintf(out->fp,
224 : : "static inline int %s_verify_as_root_with_identifer(const void *buf, size_t bufsiz, const char *fid)\n"
225 : : "{\n return flatcc_verify_struct_as_root(buf, bufsiz, fid, %"PRIu16", %"PRIu64");\n}\n\n",
226 : 36 : snt.text, ct->align, ct->size);
227 : 36 : return 0;
228 : : }
229 : :
230 : 46 : static int gen_verifier_prototypes(fb_output_t *out)
231 : : {
232 : : fb_symbol_t *sym;
233 : : fb_scoped_name_t snt;
234 : :
235 : 23 : fb_clear(snt);
236 : :
237 [ + + ]: 141 : for (sym = out->S->symbols; sym; sym = sym->link) {
238 [ + + ]: 118 : switch (sym->kind) {
239 : : case fb_is_table:
240 : : fb_compound_name((fb_compound_type_t *)sym, &snt);
241 : 52 : fprintf(out->fp,
242 : : "static int __%s_table_verifier(flatcc_table_verifier_descriptor_t *td);\n",
243 : : snt.text);
244 : : }
245 : : }
246 : 23 : fprintf(out->fp, "\n");
247 : 23 : return 0;
248 : : }
249 : :
250 : 23 : static int gen_union_verifiers(fb_output_t *out)
251 : : {
252 : : fb_symbol_t *sym;
253 : :
254 [ + + ]: 141 : for (sym = out->S->symbols; sym; sym = sym->link) {
255 [ + + ]: 118 : switch (sym->kind) {
256 : : case fb_is_union:
257 : 8 : gen_union_verifier(out, (fb_compound_type_t *)sym);
258 : : }
259 : : }
260 : 23 : return 0;
261 : : }
262 : :
263 : 23 : static int gen_struct_verifiers(fb_output_t *out)
264 : : {
265 : : fb_symbol_t *sym;
266 : :
267 [ + + ]: 141 : for (sym = out->S->symbols; sym; sym = sym->link) {
268 [ + + ]: 118 : switch (sym->kind) {
269 : : case fb_is_struct:
270 : 36 : gen_struct_verifier(out, (fb_compound_type_t *)sym);
271 : : }
272 : : }
273 : 23 : return 0;
274 : : }
275 : :
276 : 23 : static int gen_table_verifiers(fb_output_t *out)
277 : : {
278 : : fb_symbol_t *sym;
279 : :
280 [ + + ]: 141 : for (sym = out->S->symbols; sym; sym = sym->link) {
281 [ + + ]: 118 : switch (sym->kind) {
282 : : case fb_is_table:
283 : 52 : gen_table_verifier(out, (fb_compound_type_t *)sym);
284 : : }
285 : : }
286 : 23 : return 0;
287 : : }
288 : :
289 : 23 : int fb_gen_c_verifier(fb_output_t *out)
290 : : {
291 : 23 : gen_verifier_pretext(out);
292 : 23 : gen_verifier_prototypes(out);
293 : 23 : gen_union_verifiers(out);
294 : 23 : gen_struct_verifiers(out);
295 : 23 : gen_table_verifiers(out);
296 : 23 : gen_verifier_footer(out);
297 : 23 : return 0;
298 : : }
|