nostrdb

an unfairly fast embedded nostr database backed by lmdb
git clone git://jb55.com/nostrdb
Log | Files | Refs | Submodules | README | LICENSE

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 }