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