From fb32d6373e5ea82ef87ca89f27b4929f652cc5c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Mon, 21 Dec 2020 23:14:38 +0100 Subject: [PATCH 001/106] Use portable printf formatters for 64-bit integers --- src/compiler/codegen_c.h | 13 ++-- src/compiler/codegen_c_builder.c | 100 +++++++++++++++---------------- src/compiler/codegen_c_reader.c | 56 ++++++++--------- 3 files changed, 86 insertions(+), 83 deletions(-) diff --git a/src/compiler/codegen_c.h b/src/compiler/codegen_c.h index e6a82c41d..6eba54aa2 100644 --- a/src/compiler/codegen_c.h +++ b/src/compiler/codegen_c.h @@ -8,14 +8,17 @@ #include "parser.h" #include "codegen.h" +/* -DFLATCC_PORTABLE may help if inttypes.h is missing. */ +#ifndef PRId64 +#include +#endif + #define __FLATCC_ERROR_TYPE "INTERNAL_ERROR_UNEXPECTED_TYPE" #ifndef gen_panic #define gen_panic(context, msg) fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, msg), assert(0), exit(-1) #endif -#define llu(x) (long long unsigned int)(x) -#define lld(x) (long long int)(x) static inline void token_name(fb_token_t *t, int *n, const char **s) { *n = (int)t->len; @@ -251,18 +254,18 @@ static inline size_t print_literal(fb_scalar_type_t scalar_type, const fb_value_ switch (value->type) { case vt_uint: cast = scalar_cast(scalar_type); - return (size_t)sprintf(literal, "%s(%llu)", cast, llu(value->u)); + return (size_t)sprintf(literal, "%s(%"PRIu64")", cast, (uint64_t)value->u); break; case vt_int: cast = scalar_cast(scalar_type); - return (size_t)sprintf(literal, "%s(%lld)", cast, lld(value->i)); + return (size_t)sprintf(literal, "%s(%"PRId64")", cast, (int64_t)value->i); break; case vt_bool: cast = scalar_cast(scalar_type); return (size_t)sprintf(literal, "%s(%u)", cast, (unsigned)value->b); break; case vt_float: - /* + /* * .9g ensures sufficient precision in 32-bit floats and * .17g ensures sufficient precision for 64-bit floats (double). * The '#' forces a decimal point that would not be printed diff --git a/src/compiler/codegen_c_builder.c b/src/compiler/codegen_c_builder.c index d5ec59530..1860a48eb 100644 --- a/src/compiler/codegen_c_builder.c +++ b/src/compiler/codegen_c_builder.c @@ -1261,8 +1261,8 @@ static void gen_builder_struct(fb_output_t *out, fb_compound_type_t *ct) fprintf(out->fp, "{ "); gen_builder_struct_field_assign(out, ct, 0, arg_count, convert_from_pe, 1); fprintf(out->fp, "return p; }\n"); - fprintf(out->fp, "__%sbuild_struct(%s, %s, %llu, %u, %s_file_identifier, %s_type_identifier)\n", - nsc, nsc, snt.text, llu(ct->size), ct->align, snt.text, snt.text); + fprintf(out->fp, "__%sbuild_struct(%s, %s, %"PRIu64", %u, %s_file_identifier, %s_type_identifier)\n", + nsc, nsc, snt.text, (uint64_t)ct->size, ct->align, snt.text, snt.text); if (ct->size > 0) { fprintf(out->fp, "__%sdefine_fixed_array_primitives(%s, %s, %s_t)\n", @@ -1298,7 +1298,7 @@ static int gen_builder_table_call_list(fb_output_t *out, fb_compound_type_t *ct, continue; } gen_comma(out, index, arg_count, is_macro); - fprintf(out->fp, "v%llu", llu(member->id)); + fprintf(out->fp, "v%"PRIu64"", (uint64_t)member->id); ++index; } return index; @@ -1367,17 +1367,17 @@ static int gen_builder_table_args(fb_output_t *out, fb_compound_type_t *ct, int fb_compound_name(member->type.ct, &snref); switch (member->type.ct->symbol.kind) { case fb_is_struct: - fprintf(out->fp, "%s_t *v%llu", snref.text, llu(member->id)); + fprintf(out->fp, "%s_t *v%"PRIu64"", snref.text, (uint64_t)member->id); break; case fb_is_enum: - fprintf(out->fp, "%s_enum_t v%llu", snref.text, llu(member->id)); + fprintf(out->fp, "%s_enum_t v%"PRIu64"", snref.text, (uint64_t)member->id); break; case fb_is_table: - fprintf(out->fp, "%s_ref_t v%llu", snref.text, llu(member->id)); + fprintf(out->fp, "%s_ref_t v%"PRIu64"", snref.text, (uint64_t)member->id); break; case fb_is_union: /* Unions jump an index because it is two fields. */ - fprintf(out->fp, "%s_union_ref_t v%llu", snref.text, llu(member->id)); + fprintf(out->fp, "%s_union_ref_t v%"PRIu64"", snref.text, (uint64_t)member->id); break; default: gen_panic(out, "internal error: unexpected table field type"); @@ -1390,10 +1390,10 @@ static int gen_builder_table_args(fb_output_t *out, fb_compound_type_t *ct, int case fb_is_struct: case fb_is_enum: case fb_is_table: - fprintf(out->fp, "%s_vec_ref_t v%llu", snref.text, llu(member->id)); + fprintf(out->fp, "%s_vec_ref_t v%"PRIu64"", snref.text, (uint64_t)member->id); break; case fb_is_union: - fprintf(out->fp, "%s_union_vec_ref_t v%llu", snref.text, llu(member->id)); + fprintf(out->fp, "%s_union_vec_ref_t v%"PRIu64"", snref.text, (uint64_t)member->id); break; default: gen_panic(out, "internal error: unexpected table table type"); @@ -1403,17 +1403,17 @@ static int gen_builder_table_args(fb_output_t *out, fb_compound_type_t *ct, int case vt_scalar_type: tname_ns = scalar_type_ns(member->type.st, nsc); tname = scalar_type_name(member->type.st); - fprintf(out->fp, "%s%s v%llu", tname_ns, tname, llu(member->id)); + fprintf(out->fp, "%s%s v%"PRIu64"", tname_ns, tname, (uint64_t)member->id); break; case vt_vector_type: tname = scalar_type_prefix(member->type.st); - fprintf(out->fp, "%s%s_vec_ref_t v%llu", nsc, tname, llu(member->id)); + fprintf(out->fp, "%s%s_vec_ref_t v%"PRIu64"", nsc, tname, (uint64_t)member->id); break; case vt_string_type: - fprintf(out->fp, "%sstring_ref_t v%llu", nsc, llu(member->id)); + fprintf(out->fp, "%sstring_ref_t v%"PRIu64"", nsc, (uint64_t)member->id); break; case vt_vector_string_type: - fprintf(out->fp, "%sstring_vec_ref_t v%llu", nsc, llu(member->id)); + fprintf(out->fp, "%sstring_vec_ref_t v%"PRIu64"", nsc, (uint64_t)member->id); break; default: gen_panic(out, "internal error: unexpected table member type"); @@ -1472,11 +1472,11 @@ static int gen_builder_create_table(fb_output_t *out, fb_compound_type_t *ct) if (member->type.type == vt_compound_type_ref && member->type.ct->symbol.kind == fb_is_union) { has_union = 1; if (patch_union) { - fprintf(out->fp, "\n || %s_%.*s_add_value(B, v%llu)", snt.text, n, s, llu(member->id)); + fprintf(out->fp, "\n || %s_%.*s_add_value(B, v%"PRIu64")", snt.text, n, s, (uint64_t)member->id); continue; } } - fprintf(out->fp, "\n || %s_%.*s_add(B, v%llu)", snt.text, n, s, llu(member->id)); + fprintf(out->fp, "\n || %s_%.*s_add(B, v%"PRIu64")", snt.text, n, s, (uint64_t)member->id); } if (patch_union && has_union) { for (member = ct->ordered_members; member; member = member->order) { @@ -1485,7 +1485,7 @@ static int gen_builder_create_table(fb_output_t *out, fb_compound_type_t *ct) } if (member->type.type == vt_compound_type_ref && member->type.ct->symbol.kind == fb_is_union) { symbol_name(&member->symbol, &n, &s); - fprintf(out->fp, "\n || %s_%.*s_add_type(B, v%llu.type)", snt.text, n, s, llu(member->id)); + fprintf(out->fp, "\n || %s_%.*s_add_type(B, v%"PRIu64".type)", snt.text, n, s, (uint64_t)member->id); } } } @@ -1519,8 +1519,8 @@ static int gen_builder_table(fb_output_t *out, fb_compound_type_t *ct) fprintf(out->fp, "static %s_ref_t %s_clone(%sbuilder_t *B, %s_table_t t);\n", snt.text, snt.text, nsc, snt.text); - fprintf(out->fp, "__%sbuild_table(%s, %s, %llu)\n", - nsc, nsc, snt.text, llu(ct->count)); + fprintf(out->fp, "__%sbuild_table(%s, %s, %"PRIu64")\n", + nsc, nsc, snt.text, (uint64_t)ct->count); return 0; } @@ -1620,15 +1620,15 @@ static int gen_builder_table_fields(fb_output_t *out, fb_compound_type_t *ct) tprefix = scalar_type_prefix(member->type.st); if (is_optional) { fprintf(out->fp, - "__%sbuild_scalar_optional_field(%llu, %s, %s_%.*s, %s%s, %s%s, %llu, %u, %s)\n", - nsc, llu(member->id), nsc, snt.text, n, s, nsc, tprefix, tname_ns, tname, - llu(member->size), member->align, snt.text); + "__%sbuild_scalar_optional_field(%"PRIu64", %s, %s_%.*s, %s%s, %s%s, %"PRIu64", %u, %s)\n", + nsc, (uint64_t)member->id, nsc, snt.text, n, s, nsc, tprefix, tname_ns, tname, + (uint64_t)member->size, member->align, snt.text); } else { print_literal(member->type.st, &member->value, literal); fprintf(out->fp, - "__%sbuild_scalar_field(%llu, %s, %s_%.*s, %s%s, %s%s, %llu, %u, %s, %s)\n", - nsc, llu(member->id), nsc, snt.text, n, s, nsc, tprefix, tname_ns, tname, - llu(member->size), member->align, literal, snt.text); + "__%sbuild_scalar_field(%"PRIu64", %s, %s_%.*s, %s%s, %s%s, %"PRIu64", %u, %s, %s)\n", + nsc, (uint64_t)member->id, nsc, snt.text, n, s, nsc, tprefix, tname_ns, tname, + (uint64_t)member->size, member->align, literal, snt.text); } break; case vt_vector_type: @@ -1636,8 +1636,8 @@ static int gen_builder_table_fields(fb_output_t *out, fb_compound_type_t *ct) tname = scalar_type_name(member->type.st); tprefix = scalar_type_prefix(member->type.st); fprintf(out->fp, - "__%sbuild_vector_field(%llu, %s, %s_%.*s, %s%s, %s%s, %s)\n", - nsc, llu(member->id), nsc, snt.text, n, s, nsc, tprefix, tname_ns, tname, snt.text); + "__%sbuild_vector_field(%"PRIu64", %s, %s_%.*s, %s%s, %s%s, %s)\n", + nsc, (uint64_t)member->id, nsc, snt.text, n, s, nsc, tprefix, tname_ns, tname, snt.text); /* [ubyte] vectors can nest buffers. */ if (member->nest) { switch (member->nest->symbol.kind) { @@ -1660,45 +1660,45 @@ static int gen_builder_table_fields(fb_output_t *out, fb_compound_type_t *ct) break; case vt_string_type: fprintf(out->fp, - "__%sbuild_string_field(%llu, %s, %s_%.*s, %s)\n", - nsc, llu(member->id), nsc, snt.text, n, s, snt.text); + "__%sbuild_string_field(%"PRIu64", %s, %s_%.*s, %s)\n", + nsc, (uint64_t)member->id, nsc, snt.text, n, s, snt.text); break; case vt_vector_string_type: fprintf(out->fp, - "__%sbuild_string_vector_field(%llu, %s, %s_%.*s, %s)\n", - nsc, llu(member->id), nsc, snt.text, n, s, snt.text); + "__%sbuild_string_vector_field(%"PRIu64", %s, %s_%.*s, %s)\n", + nsc, (uint64_t)member->id, nsc, snt.text, n, s, snt.text); break; case vt_compound_type_ref: fb_compound_name(member->type.ct, &snref); switch (member->type.ct->symbol.kind) { case fb_is_struct: fprintf(out->fp, - "__%sbuild_struct_field(%llu, %s, %s_%.*s, %s, %llu, %u, %s)\n", - nsc, llu(member->id), nsc, snt.text, n, s, snref.text, llu(member->size), member->align, snt.text); + "__%sbuild_struct_field(%"PRIu64", %s, %s_%.*s, %s, %"PRIu64", %u, %s)\n", + nsc, (uint64_t)member->id, nsc, snt.text, n, s, snref.text, (uint64_t)member->size, member->align, snt.text); break; case fb_is_table: fprintf(out->fp, - "__%sbuild_table_field(%llu, %s, %s_%.*s, %s, %s)\n", - nsc, llu(member->id), nsc, snt.text, n, s, snref.text, snt.text); + "__%sbuild_table_field(%"PRIu64", %s, %s_%.*s, %s, %s)\n", + nsc, (uint64_t)member->id, nsc, snt.text, n, s, snref.text, snt.text); break; case fb_is_enum: if (is_optional) { fprintf(out->fp, - "__%sbuild_scalar_optional_field(%llu, %s, %s_%.*s, %s, %s_enum_t, %llu, %u, %s)\n", - nsc, llu(member->id), nsc, snt.text, n, s, snref.text, snref.text, - llu(member->size), member->align, snt.text); + "__%sbuild_scalar_optional_field(%"PRIu64", %s, %s_%.*s, %s, %s_enum_t, %"PRIu64", %u, %s)\n", + nsc, (uint64_t)member->id, nsc, snt.text, n, s, snref.text, snref.text, + (uint64_t)member->size, member->align, snt.text); } else { print_literal(member->type.ct->type.st, &member->value, literal); fprintf(out->fp, - "__%sbuild_scalar_field(%llu, %s, %s_%.*s, %s, %s_enum_t, %llu, %u, %s, %s)\n", - nsc, llu(member->id), nsc, snt.text, n, s, snref.text, snref.text, - llu(member->size), member->align, literal, snt.text); + "__%sbuild_scalar_field(%"PRIu64", %s, %s_%.*s, %s, %s_enum_t, %"PRIu64", %u, %s, %s)\n", + nsc, (uint64_t)member->id, nsc, snt.text, n, s, snref.text, snref.text, + (uint64_t)member->size, member->align, literal, snt.text); } break; case fb_is_union: fprintf(out->fp, - "__%sbuild_union_field(%llu, %s, %s_%.*s, %s, %s)\n", - nsc, llu(member->id), nsc, snt.text, n, s, snref.text, snt.text); + "__%sbuild_union_field(%"PRIu64", %s, %s_%.*s, %s, %s)\n", + nsc, (uint64_t)member->id, nsc, snt.text, n, s, snref.text, snt.text); gen_union_fields(out, snt.text, n, s, member->type.ct, 0); break; default: @@ -1714,26 +1714,26 @@ static int gen_builder_table_fields(fb_output_t *out, fb_compound_type_t *ct) fprintf(out->fp, "/* vector has keyed elements */\n"); } fprintf(out->fp, - "__%sbuild_vector_field(%llu, %s, %s_%.*s, %s, %s_t, %s)\n", - nsc, llu(member->id), nsc, snt.text, n, s, snref.text, snref.text, snt.text); + "__%sbuild_vector_field(%"PRIu64", %s, %s_%.*s, %s, %s_t, %s)\n", + nsc, (uint64_t)member->id, nsc, snt.text, n, s, snref.text, snref.text, snt.text); break; case fb_is_table: if (member->type.ct->symbol.flags & fb_indexed) { fprintf(out->fp, "/* vector has keyed elements */\n"); } fprintf(out->fp, - "__%sbuild_table_vector_field(%llu, %s, %s_%.*s, %s, %s)\n", - nsc, llu(member->id), nsc, snt.text, n, s, snref.text, snt.text); + "__%sbuild_table_vector_field(%"PRIu64", %s, %s_%.*s, %s, %s)\n", + nsc, (uint64_t)member->id, nsc, snt.text, n, s, snref.text, snt.text); break; case fb_is_enum: fprintf(out->fp, - "__%sbuild_vector_field(%llu, %s, %s_%.*s, %s, %s_enum_t, %s)\n", - nsc, llu(member->id), nsc, snt.text, n, s, snref.text, snref.text, snt.text); + "__%sbuild_vector_field(%"PRIu64", %s, %s_%.*s, %s, %s_enum_t, %s)\n", + nsc, (uint64_t)member->id, nsc, snt.text, n, s, snref.text, snref.text, snt.text); break; case fb_is_union: fprintf(out->fp, - "__%sbuild_union_vector_field(%llu, %s, %s_%.*s, %s, %s)\n", - nsc, llu(member->id), nsc, snt.text, n, s, snref.text, snt.text); + "__%sbuild_union_vector_field(%"PRIu64", %s, %s_%.*s, %s, %s)\n", + nsc, (uint64_t)member->id, nsc, snt.text, n, s, snref.text, snt.text); gen_union_fields(out, snt.text, n, s, member->type.ct, 1); break; default: diff --git a/src/compiler/codegen_c_reader.c b/src/compiler/codegen_c_reader.c index 5cd2f7a16..a504bd3cc 100644 --- a/src/compiler/codegen_c_reader.c +++ b/src/compiler/codegen_c_reader.c @@ -1222,8 +1222,8 @@ static void gen_struct(fb_output_t *out, fb_compound_type_t *ct) fprintf(out->fp, "#pragma pack()\n"); } fprintf(out->fp, - "static_assert(sizeof(%s_t) == %llu, \"struct size mismatch\");\n\n", - snt.text, llu(ct->size)); + "static_assert(sizeof(%s_t) == %"PRIu64", \"struct size mismatch\");\n\n", + snt.text, (uint64_t)ct->size); fprintf(out->fp, "static inline const %s_t *%s__const_ptr_add(const %s_t *p, size_t i) { return p + i; }\n", snt.text, snt.text, snt.text); fprintf(out->fp, @@ -1234,8 +1234,8 @@ static void gen_struct(fb_output_t *out, fb_compound_type_t *ct) snt.text, snt.text, snt.text, nsc); } - fprintf(out->fp, "static inline size_t %s__size(void) { return %llu; }\n", - snt.text, llu(ct->size)); + fprintf(out->fp, "static inline size_t %s__size(void) { return %"PRIu64"; }\n", + snt.text, (uint64_t)ct->size); fprintf(out->fp, "static inline size_t %s_vec_len(%s_vec_t vec)\n" "__%svec_len(vec)\n", @@ -1619,12 +1619,12 @@ static void gen_table(fb_output_t *out, fb_compound_type_t *ct) print_literal(member->type.st, &member->value, literal); if (is_optional) { fprintf(out->fp, - "__%sdefine_scalar_optional_field(%llu, %s, %.*s, %s%s, %s%s, %s)\n", - nsc, llu(member->id), snt.text, n, s, nsc, tname_prefix, tname_ns, tname, literal); + "__%sdefine_scalar_optional_field(%"PRIu64", %s, %.*s, %s%s, %s%s, %s)\n", + nsc, (uint64_t)member->id, snt.text, n, s, nsc, tname_prefix, tname_ns, tname, literal); } else { fprintf(out->fp, - "__%sdefine_scalar_field(%llu, %s, %.*s, %s%s, %s%s, %s)\n", - nsc, llu(member->id), snt.text, n, s, nsc, tname_prefix, tname_ns, tname, literal); + "__%sdefine_scalar_field(%"PRIu64", %s, %.*s, %s%s, %s%s, %s)\n", + nsc, (uint64_t)member->id, snt.text, n, s, nsc, tname_prefix, tname_ns, tname, literal); } if (!out->opts->allow_scan_for_all_fields && (member->metadata_flags & fb_f_key)) { fprintf(out->fp, @@ -1665,16 +1665,16 @@ static void gen_table(fb_output_t *out, fb_compound_type_t *ct) tname = scalar_vector_type_name(member->type.st); tname_ns = nsc; fprintf(out->fp, - "__%sdefine_vector_field(%llu, %s, %.*s, %s%s, %u)\n", - nsc, llu(member->id), snt.text, n, s, tname_ns, tname, r); + "__%sdefine_vector_field(%"PRIu64", %s, %.*s, %s%s, %u)\n", + nsc, (uint64_t)member->id, snt.text, n, s, tname_ns, tname, r); if (member->nest) { gen_nested_root(out, &member->nest->symbol, &ct->symbol, &member->symbol); } break; case vt_string_type: fprintf(out->fp, - "__%sdefine_string_field(%llu, %s, %.*s, %u)\n", - nsc, llu(member->id), snt.text, n, s, r); + "__%sdefine_string_field(%"PRIu64", %s, %.*s, %u)\n", + nsc, (uint64_t)member->id, snt.text, n, s, r); if (!out->opts->allow_scan_for_all_fields && (member->metadata_flags & fb_f_key)) { fprintf(out->fp, "__%sdefine_scan_by_string_field(%s, %.*s)\n", @@ -1710,32 +1710,32 @@ static void gen_table(fb_output_t *out, fb_compound_type_t *ct) break; case vt_vector_string_type: fprintf(out->fp, - "__%sdefine_vector_field(%llu, %s, %.*s, %sstring_vec_t, %u)\n", - nsc, llu(member->id), snt.text, n, s, nsc, r); + "__%sdefine_vector_field(%"PRIu64", %s, %.*s, %sstring_vec_t, %u)\n", + nsc, (uint64_t)member->id, snt.text, n, s, nsc, r); break; case vt_compound_type_ref: fb_compound_name(member->type.ct, &snref); switch (member->type.ct->symbol.kind) { case fb_is_struct: fprintf(out->fp, - "__%sdefine_struct_field(%llu, %s, %.*s, %s_struct_t, %u)\n", - nsc, llu(member->id), snt.text, n, s, snref.text, r); + "__%sdefine_struct_field(%"PRIu64", %s, %.*s, %s_struct_t, %u)\n", + nsc, (uint64_t)member->id, snt.text, n, s, snref.text, r); break; case fb_is_table: fprintf(out->fp, - "__%sdefine_table_field(%llu, %s, %.*s, %s_table_t, %u)\n", - nsc, llu(member->id), snt.text, n, s, snref.text, r); + "__%sdefine_table_field(%"PRIu64", %s, %.*s, %s_table_t, %u)\n", + nsc, (uint64_t)member->id, snt.text, n, s, snref.text, r); break; case fb_is_enum: print_literal(member->type.ct->type.st, &member->value, literal); if (is_optional) { fprintf(out->fp, - "__%sdefine_scalar_optional_field(%llu, %s, %.*s, %s, %s_enum_t, %s)\n", - nsc, llu(member->id), snt.text, n, s, snref.text, snref.text, literal); + "__%sdefine_scalar_optional_field(%"PRIu64", %s, %.*s, %s, %s_enum_t, %s)\n", + nsc, (uint64_t)member->id, snt.text, n, s, snref.text, snref.text, literal); } else { fprintf(out->fp, - "__%sdefine_scalar_field(%llu, %s, %.*s, %s, %s_enum_t, %s)\n", - nsc, llu(member->id), snt.text, n, s, snref.text, snref.text, literal); + "__%sdefine_scalar_field(%"PRIu64", %s, %.*s, %s, %s_enum_t, %s)\n", + nsc, (uint64_t)member->id, snt.text, n, s, snref.text, snref.text, literal); } if (!out->opts->allow_scan_for_all_fields && (member->metadata_flags & fb_f_key)) { fprintf(out->fp, @@ -1774,8 +1774,8 @@ static void gen_table(fb_output_t *out, fb_compound_type_t *ct) case fb_is_union: present_id--; fprintf(out->fp, - "__%sdefine_union_field(%s, %llu, %s, %.*s, %s, %u)\n", - nsc, nsc, llu(member->id), snt.text, n, s, snref.text, r); + "__%sdefine_union_field(%s, %"PRIu64", %s, %.*s, %s, %u)\n", + nsc, nsc, (uint64_t)member->id, snt.text, n, s, snref.text, r); break; default: gen_panic(out, "internal error: unexpected compound type in table during code generation"); @@ -1800,12 +1800,12 @@ static void gen_table(fb_output_t *out, fb_compound_type_t *ct) if (member->type.ct->symbol.kind == fb_is_union) { present_id--; fprintf(out->fp, - "__%sdefine_union_vector_field(%s, %llu, %s, %.*s, %s, %u)\n", - nsc, nsc, llu(member->id), snt.text, n, s, snref.text, r); + "__%sdefine_union_vector_field(%s, %"PRIu64", %s, %.*s, %s, %u)\n", + nsc, nsc, (uint64_t)member->id, snt.text, n, s, snref.text, r); } else { fprintf(out->fp, - "__%sdefine_vector_field(%llu, %s, %.*s, %s_vec_t, %u)\n", - nsc, llu(member->id), snt.text, n, s, snref.text, r); + "__%sdefine_vector_field(%"PRIu64", %s, %.*s, %s_vec_t, %u)\n", + nsc, (uint64_t)member->id, snt.text, n, s, snref.text, r); } break; default: From 53d54f9c56611106982f879289ad8ab93c16c579 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Mon, 21 Dec 2020 23:45:43 +0100 Subject: [PATCH 002/106] Use portable printf formatters for 64-bit integers, also for tests --- samples/reflection/bfbs2json.c | 15 +++++++++------ test/reflection_test/reflection_test.c | 8 ++++++-- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/samples/reflection/bfbs2json.c b/samples/reflection/bfbs2json.c index cbd316bc4..cd7ac0d20 100644 --- a/samples/reflection/bfbs2json.c +++ b/samples/reflection/bfbs2json.c @@ -1,8 +1,11 @@ #include "flatcc/support/readfile.h" #include "flatcc/reflection/reflection_reader.h" -/* Portable way to print 64-bit integers. */ -#define lld(x) (long long int)(x) +/* -DFLATCC_PORTABLE may help if inttypes.h is missing. */ +#ifndef PRId64 +#include +#endif + /* * Reads a binary schema generated by `flatcc` or Googles `flatc` tool, @@ -11,7 +14,7 @@ * Note: This is completely unrelated to `flatcc's` JSON support - we * just needed to do something tangible with the data we read from the * binary schema and opted to print it as JSON. - * + * * The JSON can be pretty printed with an external tool, for example: * * cat monster_test_schema.json | jq '.' @@ -96,7 +99,7 @@ void print_object(reflection_Object_table_t O) printf(",\"id\":%hu", reflection_Field_id(F)); } if (reflection_Field_default_integer_is_present(F)) { - printf(",\"default_integer\":%lld", lld(reflection_Field_default_integer(F))); + printf(",\"default_integer\":%"PRId64"", (int64_t)reflection_Field_default_integer(F)); } if (reflection_Field_default_real_is_present(F)) { printf(",\"default_integer\":%lf", reflection_Field_default_real(F)); @@ -146,7 +149,7 @@ void print_enum(reflection_Enum_table_t E) } printf("{\"name\":\"%s\"", reflection_EnumVal_name(EV)); if (reflection_EnumVal_value_is_present(EV)) { - printf(",\"value\":%lld", lld(reflection_EnumVal_value(EV))); + printf(",\"value\":%"PRId64"", (int64_t)reflection_EnumVal_value(EV)); } if (reflection_EnumVal_object_is_present(EV)) { printf(",\"object\":"); @@ -155,7 +158,7 @@ void print_enum(reflection_Enum_table_t E) if (reflection_EnumVal_union_type_is_present(EV)) { printf(",\"union_type\":"); print_type(reflection_EnumVal_union_type(EV)); - } + } printf("}"); } printf("]"); diff --git a/test/reflection_test/reflection_test.c b/test/reflection_test/reflection_test.c index 92f0409e4..de940c27d 100644 --- a/test/reflection_test/reflection_test.c +++ b/test/reflection_test/reflection_test.c @@ -2,7 +2,11 @@ #include "flatcc/reflection/reflection_reader.h" #include "flatcc/portable/pcrt.h" -#define lld(x) (long long int)(x) +/* -DFLATCC_PORTABLE may help if inttypes.h is missing. */ +#ifndef PRId64 +#include +#endif + /* This is not an exhaustive test. */ int test_schema(const char *monster_bfbs) @@ -50,7 +54,7 @@ int test_schema(const char *monster_bfbs) if (reflection_Field_default_integer(F) != 150) { printf("mana field has wrong default value\n"); printf("field name: %s\n", reflection_Field_name(F)); - printf("%lld\n", lld(reflection_Field_default_integer(F))); + printf("%"PRId64"\n", (int64_t)reflection_Field_default_integer(F)); goto done; } T = reflection_Field_type(F); From 7d565a82e3d41d27450d35efb5f0762413a975a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Wed, 30 Dec 2020 11:02:08 +0100 Subject: [PATCH 003/106] Add partial TCC support for alignas and alignof --- include/flatcc/portable/pstdalign.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/include/flatcc/portable/pstdalign.h b/include/flatcc/portable/pstdalign.h index 207ecfc5a..169fe27ed 100644 --- a/include/flatcc/portable/pstdalign.h +++ b/include/flatcc/portable/pstdalign.h @@ -30,7 +30,10 @@ * * MSVC does not support at least up to MSVC 2015, * but does appear to support alignas and alignof keywords in - * recent standard C++. + * recent standard C++. + * + * TCC only supports alignas with a numeric argument like + * `alignas(4)`, but not `alignas(float)`. * * If stdalign.h is supported but heuristics in this file are * insufficient to detect this, try including manually @@ -125,6 +128,12 @@ extern "C" { #define _Alignas(t) __declspec (align(t)) #define _Alignof(t) __alignof(t) +#elif defined(__TINYC__) + +/* Supports `_Alignas(integer-expression)`, but not `_Alignas(type)`. */ +#define _Alignas(t) __attribute__(aligned(t)) +#define _Alignof(t) __alignof__(t) + #else #error please update pstdalign.h with support for current compiler and library #endif From 919e6029e4d942b8f611344259b22421cb875e8a Mon Sep 17 00:00:00 2001 From: Ian Hunter Date: Wed, 6 Jan 2021 16:28:10 +0000 Subject: [PATCH 004/106] Update binary-format.md --- doc/binary-format.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/binary-format.md b/doc/binary-format.md index 89646c1b3..7c2f53e6e 100644 --- a/doc/binary-format.md +++ b/doc/binary-format.md @@ -79,7 +79,7 @@ as sharing a string. FlatBuffers are constructed back to front such that lower level objects such as sub-tables and strings are created first in stored last and such that the root object is stored last and early in the buffer. See also -(Stream Buffers](#stream-buffers) for a proposed variation over this +[Stream Buffers](#stream-buffers) for a proposed variation over this theme. All addressing in FlatBuffers are relative. The reason for this? When From f4ec267ae043dd35cb3965d7b1232a6eee034799 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Wed, 20 Jan 2021 19:59:48 +0100 Subject: [PATCH 005/106] Fix enum range check --- src/compiler/semantics.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/compiler/semantics.c b/src/compiler/semantics.c index 6655ee965..a6d765b12 100644 --- a/src/compiler/semantics.c +++ b/src/compiler/semantics.c @@ -1711,15 +1711,15 @@ static int process_enum(fb_parser_t *P, fb_compound_type_t *ct) } else { if (member->value.type) { index = member->value; - /* - * Captures errors in user assigned values. Also captures - * overflow on auto-increment on all types except maximum - * representation size, i.e. long or ulong which we handled - * above. - */ - if (fb_coerce_scalar_type(P, sym, ct->type.st, &index)) { - return -1; - } + } + /* + * Captures errors in user assigned values. Also captures + * overflow on auto-increment on all types except maximum + * representation size, i.e. long or ulong which we handled + * above. + */ + if (fb_coerce_scalar_type(P, sym, ct->type.st, &index)) { + return -1; } member->value = index; } From c084a38e2739f931246328148c0f62a40ed2d569 Mon Sep 17 00:00:00 2001 From: Darius Arnold Date: Fri, 26 Mar 2021 14:33:49 +0100 Subject: [PATCH 006/106] Fix two typos in README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 860672e01..4308350a4 100644 --- a/README.md +++ b/README.md @@ -461,7 +461,7 @@ may be higher but eventually smaller buffers will be hit by call overhead and thus we get down to 300MB/s at about 150ns/op encoding small buffers. These numbers are just a rough guideline - they obviously depend on hardware, compiler, and data encoded. Measurements are -excluding an ininitial warmup step. +excluding an initial warmup step. The generated JSON parsers are roughly 4 times slower than building a FlatBuffer directly in C or C++, or about 2200ns vs 600ns for a 700 byte @@ -542,7 +542,7 @@ schema. It requires a `flatbuffers_common_builder.h` file also generated by the compiler and a small runtime library `libflatccrt.a`. It is because of this requirement that the reader and builder generated code is kept separate. Typical uses can be seen in the [monster_test.c] file. -The builder allows of repeated pushing of content to a vector or a +The builder allows for repeated pushing of content to a vector or a string while a containing table is being updated which simplifies parsing of external formats. It is also possible to build nested buffers in-line - at first this may sound excessive but it is useful when From 4f38ccb981f878b50d8462048a45cb7d02d4ff2f Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Fri, 16 Apr 2021 10:37:07 +0900 Subject: [PATCH 007/106] doc/builder.md: Fix a typo in an example code --- doc/builder.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/builder.md b/doc/builder.md index 1d31bd966..14ac10d8c 100644 --- a/doc/builder.md +++ b/doc/builder.md @@ -1213,7 +1213,7 @@ vector field that we just invented for the occasion): Monster_friends_push_create_str(B, "Shrek"); Monster_friends_push_create_str(B, "Pinnochio"); Monster_friends_push_create_str(B, "Pinnochio"); - Monster_friends_push_creae(B, "Hector", 6); + Monster_friends_push_create(B, "Hector", 6); Monster_friends_push(friend); p = Monster_friends_extend(B, 1); *p = flatbuffers_string_create_str("Cindarella"); From 48a643aacef63e1c69823f0caf9b2462b67cc0f6 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Wed, 28 Apr 2021 11:08:01 +0900 Subject: [PATCH 008/106] hexdump: constify --- include/flatcc/support/hexdump.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/flatcc/support/hexdump.h b/include/flatcc/support/hexdump.h index 85ad0c42d..7b6f9b885 100644 --- a/include/flatcc/support/hexdump.h +++ b/include/flatcc/support/hexdump.h @@ -8,10 +8,10 @@ extern "C" { #include /* Based on: http://stackoverflow.com/a/7776146 */ -static void hexdump(char *desc, void *addr, size_t len, FILE *fp) { +static void hexdump(const char *desc, const void *addr, size_t len, FILE *fp) { unsigned int i; unsigned char buf[17]; - unsigned char *pc = (unsigned char*)addr; + const unsigned char *pc = (const unsigned char*)addr; /* Output description if given. */ if (desc != NULL) fprintf(fp, "%s:\n", desc); From 87820f5a5e4223fb157e262874589a0515efe3a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Wed, 5 May 2021 13:04:31 +0200 Subject: [PATCH 009/106] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 752322cc8..1dacb2feb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ - Make build.sh work for non-bash shells (PR #159). - Fix parsing json struct as roort (#157) - Add support for optional scalar values (#162) +- Fix enum out of range (#176) ## [0.6.0] From 092955f78adacf2a7af87da810a3d75909256a9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Wed, 5 May 2021 13:19:40 +0200 Subject: [PATCH 010/106] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1dacb2feb..25aaa89f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,7 @@ - Fix parsing json struct as roort (#157) - Add support for optional scalar values (#162) - Fix enum out of range (#176) +- Add stdalign support for TCC compiler (#174) ## [0.6.0] From 5adc0a5a88db63ad8bec7f69eea07158eed754fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Bollo?= Date: Tue, 4 May 2021 16:10:19 +0200 Subject: [PATCH 011/106] Adds services in binary schema flatcc already parses correctly the definitions of rpc_service. This change emits these definitions in the binary exported schema produced by option --schema. The test reflection_test dumps for debugging the list of services and rpc call names. It then includes the following checks: - Service MyGame.Example.MonsterStorage must exist - Within it, the call 'Store' must exist - Store takes a request of type MyGame.Example.Monster - Store gives a response of type MyGame.Example.Stat - Store has an attribute of name 'streaming' and value 'none' The sample program 'bfbs2json' is also modified to print the services. The sample bfbs2json was ignoring services present in BFBS files generated by flatc. After this change, it outputs the JSON output: "service": [ { "name": "", "calls": [ { "name": "", "request": , "response": } ... ] } ... ] (optional attributes not shown) --- samples/reflection/bfbs2json.c | 51 ++++++++++++++++++++ src/compiler/catalog.h | 21 ++++++++ src/compiler/codegen_schema.c | 42 ++++++++++++++++ test/reflection_test/reflection_test.c | 67 +++++++++++++++++++++++++- 4 files changed, 180 insertions(+), 1 deletion(-) diff --git a/samples/reflection/bfbs2json.c b/samples/reflection/bfbs2json.c index cd7ac0d20..03c31e7fa 100644 --- a/samples/reflection/bfbs2json.c +++ b/samples/reflection/bfbs2json.c @@ -174,10 +174,50 @@ void print_enum(reflection_Enum_table_t E) printf("}"); } +void print_call(reflection_RPCCall_table_t C) +{ + printf("{\"name\":\"%s\"", reflection_RPCCall_name(C)); + printf(",\"request\":"); + print_object(reflection_RPCCall_request(C)); + printf(",\"response\":"); + print_object(reflection_RPCCall_response(C)); + + if (reflection_RPCCall_attributes_is_present(C)) { + printf(",\"attributes\":"); + print_attributes(reflection_RPCCall_attributes(C)); + } + printf("}"); +} + +void print_service(reflection_Service_table_t S) +{ + reflection_RPCCall_vec_t calls; + size_t i; + + printf("{\"name\":\"%s\"", reflection_Service_name(S)); + + printf(",\"calls\":["); + calls = reflection_Service_calls(S); + for (i = 0; i < reflection_RPCCall_vec_len(calls); ++i) { + if (i > 0) { + printf(","); + } + print_call(reflection_RPCCall_vec_at(calls, i)); + } + printf("]"); + + if (reflection_Service_attributes_is_present(S)) { + printf(",\"attributes\":"); + print_attributes(reflection_Service_attributes(S)); + } + printf("}"); +} + void print_schema(reflection_Schema_table_t S) { reflection_Object_vec_t Objs; reflection_Enum_vec_t Enums; + reflection_Service_vec_t Services; size_t i; Objs = reflection_Schema_objects(S); @@ -209,6 +249,17 @@ void print_schema(reflection_Schema_table_t S) printf(",\"root_table\":"); print_object(reflection_Schema_root_table(S)); } + if (reflection_Schema_services_is_present(S)) { + printf(",\"services\":["); + Services = reflection_Schema_services(S); + for (i = 0; i < reflection_Service_vec_len(Services); ++i) { + if (i > 0) { + printf(","); + } + print_service(reflection_Service_vec_at(Services, i)); + } + printf("]"); + } printf("}\n"); } diff --git a/src/compiler/catalog.h b/src/compiler/catalog.h index 149161780..de2947fd1 100644 --- a/src/compiler/catalog.h +++ b/src/compiler/catalog.h @@ -10,6 +10,7 @@ typedef struct entry entry_t; typedef entry_t object_entry_t; typedef entry_t enum_entry_t; +typedef entry_t service_entry_t; typedef struct scope_entry scope_entry_t; struct entry { @@ -28,16 +29,21 @@ struct catalog { int qualify_names; int nobjects; int nenums; + int nservices; size_t name_table_size; object_entry_t *objects; enum_entry_t *enums; + service_entry_t *services; char *name_table; object_entry_t *next_object; enum_entry_t *next_enum; + service_entry_t *next_service; char *next_name; fb_schema_t *schema; }; +#include + static void count_symbol(void *context, fb_symbol_t *sym) { catalog_t *catalog = context; @@ -75,6 +81,9 @@ static void count_symbol(void *context, fb_symbol_t *sym) case fb_is_enum: ++catalog->nenums; break; + case fb_is_rpc_service: + ++catalog->nservices; + break; default: return; } } @@ -122,6 +131,11 @@ static void install_symbol(void *context, fb_symbol_t *sym) catalog->next_enum->name = name; catalog->next_enum++; break; + case fb_is_rpc_service: + catalog->next_service->ct = (fb_compound_type_t *)sym; + catalog->next_service->name = name; + catalog->next_service++; + break; default: break; } } @@ -160,6 +174,9 @@ static void clear_catalog(catalog_t *catalog) if (catalog->enums) { free(catalog->enums); } + if (catalog->services) { + free(catalog->services); + } if (catalog->name_table) { free(catalog->name_table); } @@ -176,12 +193,15 @@ static int build_catalog(catalog_t *catalog, fb_schema_t *schema, int qualify_na fb_scope_table_visit(index, count_symbols, catalog); catalog->objects = calloc((size_t)catalog->nobjects, sizeof(catalog->objects[0])); catalog->enums = calloc((size_t)catalog->nenums, sizeof(catalog->enums[0])); + catalog->services = calloc((size_t)catalog->nservices, sizeof(catalog->services[0])); catalog->name_table = malloc(catalog->name_table_size); catalog->next_object = catalog->objects; catalog->next_enum = catalog->enums; + catalog->next_service = catalog->services; catalog->next_name = catalog->name_table; if ((!catalog->objects && catalog->nobjects > 0) || (!catalog->enums && catalog->nenums > 0) || + (!catalog->services && catalog->nservices > 0) || (!catalog->name_table && catalog->name_table_size > 0)) { clear_catalog(catalog); return -1; @@ -190,6 +210,7 @@ static int build_catalog(catalog_t *catalog, fb_schema_t *schema, int qualify_na /* Presort objects and enums because the sorted index is required in Type tables. */ sort_entries(catalog->objects, catalog->nobjects); sort_entries(catalog->enums, catalog->nenums); + sort_entries(catalog->services, catalog->nservices); return 0; } diff --git a/src/compiler/codegen_schema.c b/src/compiler/codegen_schema.c index 356f150e6..0313d9ef8 100644 --- a/src/compiler/codegen_schema.c +++ b/src/compiler/codegen_schema.c @@ -345,6 +345,47 @@ static void export_root_type(flatcc_builder_t *B, fb_symbol_t * root_type, } } +static void export_call(flatcc_builder_t *B, fb_member_t *member, reflection_Object_ref_t *object_map) +{ + reflection_RPCCall_vec_push_start(B); + reflection_RPCCall_name_create(B, member->symbol.ident->text, (size_t)member->symbol.ident->len); + reflection_RPCCall_request_add(B, object_map[member->req_type.ct->export_index]); + reflection_RPCCall_response_add(B, object_map[member->type.ct->export_index]); + if (member->metadata) { + reflection_RPCCall_attributes_start(B); + export_attributes(B, member->metadata); + reflection_RPCCall_attributes_end(B); + } + reflection_RPCCall_vec_push_end(B); +} + +static void export_services(flatcc_builder_t *B, service_entry_t *services, int nservices, + reflection_Object_ref_t *object_map) +{ + int i; + fb_compound_type_t *ct; + fb_symbol_t *sym; + + reflection_Schema_services_start(B); + for (i = 0; i < nservices; ++i) { + ct = services[i].ct; + reflection_Service_vec_push_start(B); + reflection_Service_name_create_str(B, services[i].name); + reflection_Service_calls_start(B); + for (sym = ct->members; sym; sym = sym->link) { + export_call(B, (fb_member_t *)sym, object_map); + } + reflection_Service_calls_end(B); + if (ct->metadata) { + reflection_Service_attributes_start(B); + export_attributes(B, ct->metadata); + reflection_Service_attributes_end(B); + } + reflection_Service_vec_push_end(B); + } + reflection_Schema_services_end(B); +} + static int export_schema(flatcc_builder_t *B, fb_options_t *opts, fb_schema_t *S) { catalog_t catalog; @@ -377,6 +418,7 @@ static int export_schema(flatcc_builder_t *B, fb_options_t *opts, fb_schema_t *S export_objects(B, catalog.objects, catalog.nobjects, object_map); export_enums(B, catalog.enums, catalog.nenums, object_map); export_root_type(B, S->root_type.type, object_map); + export_services(B, catalog.services, catalog.nservices, object_map); reflection_Schema_end_as_root(B); diff --git a/test/reflection_test/reflection_test.c b/test/reflection_test/reflection_test.c index de940c27d..eef0bd17f 100644 --- a/test/reflection_test/reflection_test.c +++ b/test/reflection_test/reflection_test.c @@ -21,6 +21,12 @@ int test_schema(const char *monster_bfbs) reflection_Field_table_t F; reflection_Type_table_t T; size_t k, monster_index; + reflection_Service_vec_t Svcs; + reflection_Service_table_t Svc; + reflection_RPCCall_vec_t Calls; + reflection_RPCCall_table_t Call; + size_t call_index; + const char *strval; buffer = readfile(monster_bfbs, 100000, &size); if (!buffer) { @@ -98,7 +104,66 @@ int test_schema(const char *monster_bfbs) printf("array of tables is not a monster vector\n"); goto done; } - + /* list services and calls */ + Svcs = reflection_Schema_services(S); + for (k = 0; k < reflection_Service_vec_len(Svcs); ++k) { + Svc = reflection_Service_vec_at(Svcs, k); + printf("dbg: svc #%d : %s\n", (int)k, + reflection_Service_name(Svc)); + Calls = reflection_Service_calls(Svc); + for (call_index = 0 ; + call_index < reflection_RPCCall_vec_len(Calls) ; + call_index++) { + Call = reflection_RPCCall_vec_at(Calls, call_index); + printf("dbg: call %d : %s\n", (int)call_index, + reflection_RPCCall_name(Call)); + } + } + /* Within service MyGame.Example.MonsterStorage ... */ + k = reflection_Service_vec_find(Svcs, "MyGame.Example.MonsterStorage"); + if (k == flatbuffers_not_found) { + printf("Could not find MonsterStorage service in schema\n"); + goto done; + } + Svc = reflection_Service_vec_at(Svcs, k); + /* ... search the RPC call Store */ + Calls = reflection_Service_calls(Svc); + k = reflection_RPCCall_vec_find(Calls, "Store"); + if (k == flatbuffers_not_found) { + printf("Could not find call Store in service\n"); + goto done; + } + Call = reflection_RPCCall_vec_at(Calls, k); + /* Ensure request type is MyGame.Example.Monster */ + Obj = reflection_Object_vec_at(Objs, monster_index); + if (Obj != reflection_RPCCall_request(Call)) { + printf("Wrong request type of rpc call\n"); + goto done; + } + /* Ensure response type is MyGame.Example.Stat */ + k = reflection_Object_vec_find(Objs, "MyGame.Example.Stat"); + if (k == flatbuffers_not_found) { + printf("Could not find Stat in schema\n"); + goto done; + } + Obj = reflection_Object_vec_at(Objs, k); + if (Obj != reflection_RPCCall_response(Call)) { + printf("Wrong response type of rpc call\n"); + goto done; + } + /* check the call has an attribute "streaming" */ + k = reflection_KeyValue_vec_scan(reflection_RPCCall_attributes(Call), "streaming"); + if (k == flatbuffers_not_found) { + printf("Could not find attribute in call\n"); + goto done; + } + /* check the attribute value is "none" */ + strval = reflection_KeyValue_value( + reflection_KeyValue_vec_at(reflection_RPCCall_attributes(Call), k)); + if (!strval || 0 != strcmp("none", strval)) { + printf("Wrong attribute value in call\n"); + goto done; + } ret = 0; done: if (buffer) { From 5130d3fc4e5f1fa5e3ce0b3eeefd7d6f93a9fbd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Wed, 5 May 2021 14:19:14 +0200 Subject: [PATCH 012/106] Update CHANGELOG --- CHANGELOG.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 25aaa89f9..f54ac1fca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,10 +35,11 @@ - Fix cli options so common files can be generated without schema files (PR #156). - Make build.sh work for non-bash shells (PR #159). -- Fix parsing json struct as roort (#157) -- Add support for optional scalar values (#162) -- Fix enum out of range (#176) -- Add stdalign support for TCC compiler (#174) +- Fix parsing json struct as roort (#157). +- Add support for optional scalar values (#162). +- Fix enum out of range (#176). +- Add stdalign support for TCC compiler (#174). +- Add RPC data to bfbs binary schema (#181). ## [0.6.0] From b8f5bd1701871c875bebc2e31587350c916bbee0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Wed, 5 May 2021 20:40:05 +0200 Subject: [PATCH 013/106] Fix incorrect scalar type when printing enum vectors to JSON --- src/compiler/codegen_c_json_printer.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/compiler/codegen_c_json_printer.c b/src/compiler/codegen_c_json_printer.c index db1142881..f95ca356d 100644 --- a/src/compiler/codegen_c_json_printer.c +++ b/src/compiler/codegen_c_json_printer.c @@ -564,14 +564,13 @@ static int gen_json_printer_table(fb_output_t *out, fb_compound_type_t *ct) member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len, snref.text); break; case fb_is_enum: + tp = scalar_type_prefix(member->type.ct->type.st); #if FLATCC_JSON_PRINT_MAP_ENUMS - tp = scalar_type_prefix(member->type.st); fprintf(out->fp, "flatcc_json_printer_%s_enum_vector_field(ctx, td, %"PRIu64", \"%.*s\", %ld, %"PRIu64", %s_print_json_enum);", tp, member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len, (uint64_t)ct->size, snref.text); break; #else - tp = scalar_type_prefix(member->type.st); fprintf(out->fp, "flatcc_json_printer_%s_vector_field(ctx, td, %"PRIu64", \"%.*s\", %ld);", tp, member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len); From 8fa8948b1b1c398b42802e2ad11e876fa9bd60a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Thu, 6 May 2021 11:13:50 +0200 Subject: [PATCH 014/106] Remove extra argument from JSON printer for enum vectors --- src/compiler/codegen_c_json_printer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/codegen_c_json_printer.c b/src/compiler/codegen_c_json_printer.c index f95ca356d..d27ba9d69 100644 --- a/src/compiler/codegen_c_json_printer.c +++ b/src/compiler/codegen_c_json_printer.c @@ -567,8 +567,8 @@ static int gen_json_printer_table(fb_output_t *out, fb_compound_type_t *ct) tp = scalar_type_prefix(member->type.ct->type.st); #if FLATCC_JSON_PRINT_MAP_ENUMS fprintf(out->fp, - "flatcc_json_printer_%s_enum_vector_field(ctx, td, %"PRIu64", \"%.*s\", %ld, %"PRIu64", %s_print_json_enum);", - tp, member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len, (uint64_t)ct->size, snref.text); + "flatcc_json_printer_%s_enum_vector_field(ctx, td, %"PRIu64", \"%.*s\", %ld, %s_print_json_enum);", + tp, member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len, snref.text); break; #else fprintf(out->fp, From 7ce7589c1635530a4ae96cea51ad40c3e7b2f672 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Thu, 6 May 2021 12:20:10 +0200 Subject: [PATCH 015/106] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f54ac1fca..37555a421 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ - Fix enum out of range (#176). - Add stdalign support for TCC compiler (#174). - Add RPC data to bfbs binary schema (#181). +- Fix support for printing JSON enum vectors (#182). ## [0.6.0] From f8c4140dd9dde61c86db751f6002def78754fced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Wed, 19 May 2021 18:05:26 +0200 Subject: [PATCH 016/106] Silence GCC identation warning --- CHANGELOG.md | 1 + CMakeLists.txt | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37555a421..a63129c9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ - Add stdalign support for TCC compiler (#174). - Add RPC data to bfbs binary schema (#181). - Fix support for printing JSON enum vectors (#182). +- Silence GCC 11 identation warning (#183). ## [0.6.0] diff --git a/CMakeLists.txt b/CMakeLists.txt index 40dee3b3c..7a201691d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -225,6 +225,10 @@ elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU") message(STATUS "Disabling GNU C compiler warnings: -Wstringop-truncation -Wno-format-overflow") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-stringop-truncation -Wno-format-overflow") endif() + if (NOT (GCC_VERSION VERSION_LESS 11.0)) + # Disable warning on misleading indentation it become more aggressive in 11.0 + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-misleading-indentation") + endif() if (FLATCC_GNU_POSIX_MEMALIGN) # -std=c11 prevents detection of posix_memalign and aligned_alloc might be missing set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DPORTABLE_POSIX_MEMALIGN=1") From 2eaf0fa3a18e5fcab7fc66f04accb677119f2e27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Wed, 19 May 2021 18:14:12 +0200 Subject: [PATCH 017/106] Fix type of code field in json test --- CHANGELOG.md | 1 + test/json_test/test_basic_parse.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a63129c9e..0c5d2a493 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,7 @@ - Add RPC data to bfbs binary schema (#181). - Fix support for printing JSON enum vectors (#182). - Silence GCC 11 identation warning (#183). +- Fix type of code field on json test (#184). ## [0.6.0] diff --git a/test/json_test/test_basic_parse.c b/test/json_test/test_basic_parse.c index 4f6f940f6..de27ee775 100644 --- a/test/json_test/test_basic_parse.c +++ b/test/json_test/test_basic_parse.c @@ -89,7 +89,8 @@ const char *test(flatcc_builder_t *B, const char *buf, const char *end, int *ret uint64_t w; const char *k; char *s; - char code[4]; + flatcc_json_parser_escape_buffer_t code; + void *p; ctx = &parse_ctx; From 0b72d40d32fd4831c00161dcdc156d1814790d69 Mon Sep 17 00:00:00 2001 From: Olivier Matz Date: Thu, 20 May 2021 12:01:57 +0200 Subject: [PATCH 018/106] Fix end_loc in json parser context After parsing a table or struct, ctx->end_loc is set to the current value of buf, which is expected to be the end of the json data. However the ctx->end_loc value is incorrect, because buf is not updated after the call to the parser callback function. Fix this in both flatcc_json_parser_table_as_root() and flatcc_json_parser_struct_as_root(). --- src/runtime/json_parser.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/runtime/json_parser.c b/src/runtime/json_parser.c index 4941a4e0b..fbb32d2b0 100644 --- a/src/runtime/json_parser.c +++ b/src/runtime/json_parser.c @@ -1268,7 +1268,7 @@ int flatcc_json_parser_table_as_root(flatcc_builder_t *B, flatcc_json_parser_t * ctx = ctx ? ctx : &_ctx; flatcc_json_parser_init(ctx, B, buf, buf + bufsiz, flags); if (flatcc_builder_start_buffer(B, fid, 0, builder_flags)) return -1; - parser(ctx, buf, buf + bufsiz, &root); + buf = parser(ctx, buf, buf + bufsiz, &root); if (ctx->error) { return ctx->error; } @@ -1288,7 +1288,7 @@ int flatcc_json_parser_struct_as_root(flatcc_builder_t *B, flatcc_json_parser_t ctx = ctx ? ctx : &_ctx; flatcc_json_parser_init(ctx, B, buf, buf + bufsiz, flags); if (flatcc_builder_start_buffer(B, fid, 0, builder_flags)) return -1; - parser(ctx, buf, buf + bufsiz, &root); + buf = parser(ctx, buf, buf + bufsiz, &root); if (ctx->error) { return ctx->error; } From be31b4f73e87f806ec78cb932ef22fc1bbc8ade2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Fri, 21 May 2021 14:01:52 +0200 Subject: [PATCH 019/106] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c5d2a493..c9392ff3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ - Fix support for printing JSON enum vectors (#182). - Silence GCC 11 identation warning (#183). - Fix type of code field on json test (#184). +- Add `end_loc` to parser state of root json parsers (#186). ## [0.6.0] From efb2b683bcc9809cfbcd4078cf5114316d5719d5 Mon Sep 17 00:00:00 2001 From: Olivier Matz Date: Fri, 21 May 2021 17:06:25 +0200 Subject: [PATCH 020/106] Fix per-table file identifiers and extensions (#187) * Fix definition of per-table file identifiers The generated headers contain something like this: #undef flatbuffers_identifier #define flatbuffers_identifier "ABCD" #ifndef MyNamespace_MyTable_file_identifier #define MyNamespace_MyTable_file_identifier flatbuffers_identifier #endif If several different headers are included, the macro flatbuffers_identifier is undefined and redefined several times, and at the end its value it the one from the last included header. Therefore, all macros __file_identifier will have this value, which is not expected. Fix this by using the file identifier string instead of the flatbuffers_identifier macro: #ifndef MyNamespace_MyTable_file_identifier #define MyNamespace_MyTable_file_identifier "ABCD" #endif * Remove dot from generated file extension Change the generated file_extension from ".ext" to "ext". This is more consistent with the schema definition. * Add definition of per-table file extensions The documentation says that the file_extension is handled in a similar manner than file_identifier (see "File Identifiers" in README.md). However there is currently no per-table file extension. This commit adds it. --- README.md | 13 ++++----- config/config.h | 3 +- src/compiler/codegen_c_builder.c | 3 +- src/compiler/codegen_c_reader.c | 48 ++++++++++++++++++++++++++++---- 4 files changed, 50 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 4308350a4..255125d04 100644 --- a/README.md +++ b/README.md @@ -1263,16 +1263,13 @@ defined as the null identifier. The generated code defines the identifiers for a given table: - #ifndef MyGame_Example_Monster_identifier - #define MyGame_Example_Monster_identifier flatbuffers_identifier + #ifndef MyGame_Example_Monster_file_identifier + #define MyGame_Example_Monster_file_identifier "MONS" #endif -The `flatbuffers_identifier` is the schema specific `file_identifier` -and is undefined and redefined for each generated `_reader.h` file. - The user can now override the identifier for a given type, for example: - #define MyGame_Example_Vec3_identifier "VEC3" + #define MyGame_Example_Vec3_file_identifier "VEC3" #include "monster_test_builder.h" ... @@ -1283,8 +1280,8 @@ and so does other `_as_root` methods. The `file_extension` is handled in a similar manner: - #ifndef MyGame_Example_Monster_extension - #define MyGame_Example_Monster_extension flatbuffers_extension + #ifndef MyGame_Example_Monster_file_extension + #define MyGame_Example_Monster_file_extension "mon" #endif ### Type Identifiers diff --git a/config/config.h b/config/config.h index 0387ce372..041ec228c 100644 --- a/config/config.h +++ b/config/config.h @@ -337,8 +337,9 @@ #define FLATCC_DEFAULT_BIN_SCHEMA_EXT ".bfbs" #endif +/* Schema file extensions do not carry a dot by convention, do the same here. */ #ifndef FLATCC_DEFAULT_BIN_EXT -#define FLATCC_DEFAULT_BIN_EXT ".bin" +#define FLATCC_DEFAULT_BIN_EXT "bin" #endif #ifndef FLATCC_DEFAULT_DEP_EXT diff --git a/src/compiler/codegen_c_builder.c b/src/compiler/codegen_c_builder.c index 1860a48eb..ffa105db8 100644 --- a/src/compiler/codegen_c_builder.c +++ b/src/compiler/codegen_c_builder.c @@ -897,12 +897,11 @@ static int gen_builder_pretext(fb_output_t *out) if (out->S->file_extension.type == vt_string) { fprintf(out->fp, "#undef %sextension\n" - "#define %sextension \".%.*s\"\n", + "#define %sextension \"%.*s\"\n", nsc, nsc, out->S->file_extension.s.len, out->S->file_extension.s.s); } else { fprintf(out->fp, - /* Configured extensions include dot, schema does not. */ "#ifndef %sextension\n" "#define %sextension \"%s\"\n" "#endif\n", diff --git a/src/compiler/codegen_c_reader.c b/src/compiler/codegen_c_reader.c index a504bd3cc..67f8055bc 100644 --- a/src/compiler/codegen_c_reader.c +++ b/src/compiler/codegen_c_reader.c @@ -37,6 +37,9 @@ static void print_type_identifier(fb_output_t *out, fb_compound_type_t *ct) uint32_t type_hash; int conflict = 0; fb_symbol_t *sym; + const char *file_identifier; + int file_identifier_len; + const char *quote; fb_clear(snt); @@ -54,19 +57,28 @@ static void print_type_identifier(fb_output_t *out, fb_compound_type_t *ct) break; } } + if (out->S->file_identifier.type == vt_string) { + quote = "\""; + file_identifier = out->S->file_identifier.s.s; + file_identifier_len = out->S->file_identifier.s.len; + } else { + quote = ""; + file_identifier = "0"; + file_identifier_len = 1; + } fprintf(out->fp, "#ifndef %s_file_identifier\n" - "#define %s_file_identifier %sidentifier\n" + "#define %s_file_identifier %s%.*s%s\n" "#endif\n", - name, name, nsc); + name, name, quote, file_identifier_len, file_identifier, quote); if (!conflict) { /* For backwards compatibility. */ fprintf(out->fp, "/* deprecated, use %s_file_identifier */\n" "#ifndef %s_identifier\n" - "#define %s_identifier %sidentifier\n" + "#define %s_identifier %s%.*s%s\n" "#endif\n", - name, name, name, nsc); + name, name, name, quote, file_identifier_len, file_identifier, quote); } fprintf(out->fp, "#define %s_type_hash ((%sthash_t)0x%lx)\n", @@ -92,6 +104,30 @@ static void print_type_identifier(fb_output_t *out, fb_compound_type_t *ct) name, buf); } +static void print_file_extension(fb_output_t *out, fb_compound_type_t *ct) +{ + fb_scoped_name_t snt; + const char *name; + + fb_clear(snt); + fb_compound_name(ct, &snt); + name = snt.text; + + if (out->S->file_extension.type == vt_string) { + fprintf(out->fp, + "#ifndef %s_file_extension\n" + "#define %s_file_extension \"%.*s\"\n" + "#endif\n", + name, name, out->S->file_extension.s.len, out->S->file_extension.s.s); + } else { + fprintf(out->fp, + "#ifndef %s_file_extension\n" + "#define %s_file_extension \"%s\"\n" + "#endif\n", + name, name, out->opts->default_bin_ext); + } +} + /* Finds first occurrence of matching key when vector is sorted on the named field. */ static void gen_find(fb_output_t *out) { @@ -1009,12 +1045,11 @@ static void gen_pretext(fb_output_t *out) if (out->S->file_extension.type == vt_string) { fprintf(out->fp, "#undef %sextension\n" - "#define %sextension \".%.*s\"\n", + "#define %sextension \"%.*s\"\n", nsc, nsc, out->S->file_extension.s.len, out->S->file_extension.s.s); } else { fprintf(out->fp, - /* Configured extensions include dot, schema does not. */ "#ifndef %sextension\n" "#define %sextension \"%s\"\n" "#endif\n", @@ -1848,6 +1883,7 @@ int fb_gen_c_reader(fb_output_t *out) /* Fall through. */ case fb_is_table: print_type_identifier(out, (fb_compound_type_t *)sym); + print_file_extension(out, (fb_compound_type_t *)sym); break; } } From f71f1dd1ff1a57bcebc637664885df58fcacfde4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Fri, 21 May 2021 17:12:16 +0200 Subject: [PATCH 021/106] Update CHANGELOG --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9392ff3b..cc684d472 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,11 @@ - Silence GCC 11 identation warning (#183). - Fix type of code field on json test (#184). - Add `end_loc` to parser state of root json parsers (#186). +- BREAKING: Add per table `_file extension` and fixed wrong per table + `_file_identifier` assignment when multiple files are included due to + macro expansion conflict. Extensions are now specified without extra dot + prefix unless specified explicitly in the schema file. The default extension + is now 'bin' instead of '.bin' (#187). ## [0.6.0] From e926d38aa32370385145a76822a05febbe355c2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Fri, 21 May 2021 17:15:51 +0200 Subject: [PATCH 022/106] Update CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc684d472..4c32b72b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,7 +44,7 @@ - Silence GCC 11 identation warning (#183). - Fix type of code field on json test (#184). - Add `end_loc` to parser state of root json parsers (#186). -- BREAKING: Add per table `_file extension` and fixed wrong per table +- BREAKING: Add per table `_file_extension` and fixed wrong per table `_file_identifier` assignment when multiple files are included due to macro expansion conflict. Extensions are now specified without extra dot prefix unless specified explicitly in the schema file. The default extension From 8a90c929e4f5c11bdff5c93bc8c82b0cf677d88c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Sat, 22 May 2021 23:17:44 +0200 Subject: [PATCH 023/106] Fix buffer overrun on parser error symbol --- src/compiler/parser.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/compiler/parser.c b/src/compiler/parser.c index d96a29671..502e1a2ad 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -103,25 +103,31 @@ void error_ref_sym(fb_parser_t *P, fb_ref_t *ref, const char *msg, fb_symbol_t * size_t k = FLATCC_MAX_IDENT_SHOW; size_t n = 0; size_t n0 = 0; + int truncated = 0; + p = ref; while (p && k > 0) { + if (n0 > 0) { + buf[n0] = '.'; + --k; + ++n0; + } n = (size_t)p->ident->len; if (k < n) { n = k; + truncated = 1; } memcpy(buf + n0, p->ident->text, n); k -= n; n0 += n; - buf[n0] = '.'; - --k; - ++n0; p = p->link; } + if (p) truncated = 1; buf[n0] = '\0'; if (n0 > 0) { --n0; } - if (k <= 0) { + if (truncated) { memcpy(buf + FLATCC_MAX_IDENT_SHOW + 1 - 4, "...\0", 4); n0 = FLATCC_MAX_IDENT_SHOW; } From c2158f1f1e6af8f313ee45ae394f51839c1715ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Sat, 22 May 2021 23:52:21 +0200 Subject: [PATCH 024/106] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c32b72b1..1f424f92b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,7 @@ macro expansion conflict. Extensions are now specified without extra dot prefix unless specified explicitly in the schema file. The default extension is now 'bin' instead of '.bin' (#187). +- Fix buffer overrun when parser reports error on large symbols (#188). ## [0.6.0] From 3ffbb7e8e3c2dbbb82a5ac8c9da24efba7e0ef7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Thu, 27 May 2021 12:02:27 +0200 Subject: [PATCH 025/106] Print --version to stdout, not stderr --- CHANGELOG.md | 1 + src/cli/flatcc_cli.c | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f424f92b..812a3168a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,7 @@ prefix unless specified explicitly in the schema file. The default extension is now 'bin' instead of '.bin' (#187). - Fix buffer overrun when parser reports error on large symbols (#188). +- BREAKING: Print --version to stdout, not stderr. ## [0.6.0] diff --git a/src/cli/flatcc_cli.c b/src/cli/flatcc_cli.c index 77c192fa0..9a03dec9c 100644 --- a/src/cli/flatcc_cli.c +++ b/src/cli/flatcc_cli.c @@ -173,8 +173,8 @@ int set_opt(flatcc_options_t *opts, const char *s, const char *a) exit(0); } if (0 == strcmp("-version", s)) { - fprintf(stderr, "%s\n", TITLE); - fprintf(stderr, "version: %s\n", VERSION); + fprintf(stdout, "%s\n", TITLE); + fprintf(stdout, "version: %s\n", VERSION); exit(0); } if (0 == strcmp("-stdout", s)) { @@ -425,7 +425,7 @@ int main(int argc, const char *argv[]) free((void *)opts.inpaths); exit(-1); } - + parse_opts(argc, argv, &opts); if (opts.cgen_builder && opts.cgen_common_reader) { opts.cgen_common_builder = 1; From 3298496feffa700af5b14cda089b7e8812273f1e Mon Sep 17 00:00:00 2001 From: Olivier Matz Date: Mon, 7 Jun 2021 15:24:27 +0200 Subject: [PATCH 026/106] fix flatcc return code on include failure (#193) When the file being compiled includes another one that does not exist, the generation fails but the return code is 0: user@host:$ echo 'include "unexistant_file.fbs";' > schema.fbs user@host:$ flatcc schema.fbs error reading included schema file: attributes.fbs user@host:$ echo $? 0 In flatcc_parse_file(), the ret variable is initialized to -1 at the beginning of the function, but modified to 0 when fb_parse() is called with success. Subsequent "goto done" do not set back ret to -1, so the return value is 0 when the file is not found. Let's remove the use of ret in the fb_parse() test, and remove the uneeded affectations of ret above. Signed-off-by: Olivier Matz --- src/compiler/flatcc.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/compiler/flatcc.c b/src/compiler/flatcc.c index 6041cb01a..3111b4c2c 100644 --- a/src/compiler/flatcc.c +++ b/src/compiler/flatcc.c @@ -345,7 +345,6 @@ int flatcc_parse_file(flatcc_context_t ctx, const char *filename) if (!(buf = fb_read_file(filename, P->opts.max_schema_size, &size))) { if (size + P->schema.root_schema->total_source_size > P->opts.max_schema_size && P->opts.max_schema_size > 0) { fb_print_error(P, "input exceeds maximum allowed size\n"); - ret = -1; goto done; } } else { @@ -361,7 +360,6 @@ int flatcc_parse_file(flatcc_context_t ctx, const char *filename) path = 0; if (size > P->opts.max_schema_size && P->opts.max_schema_size > 0) { fb_print_error(P, "input exceeds maximum allowed size\n"); - ret = -1; goto done; } } @@ -375,7 +373,6 @@ int flatcc_parse_file(flatcc_context_t ctx, const char *filename) path = 0; if (size > P->opts.max_schema_size && P->opts.max_schema_size > 0) { fb_print_error(P, "input exceeds maximum allowed size\n"); - ret = -1; goto done; } } @@ -393,7 +390,7 @@ int flatcc_parse_file(flatcc_context_t ctx, const char *filename) * need to parse all include files to make sense of the current * file. */ - if (!(ret = fb_parse(P, buf, size, 1))) { + if (!fb_parse(P, buf, size, 1)) { /* Parser owns buffer. */ buf = 0; inc = P->schema.includes; From 32aabef14ccc0e3ac15602c99476d25dcd230d19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Mon, 7 Jun 2021 15:27:01 +0200 Subject: [PATCH 027/106] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 812a3168a..57242b574 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,7 @@ is now 'bin' instead of '.bin' (#187). - Fix buffer overrun when parser reports error on large symbols (#188). - BREAKING: Print --version to stdout, not stderr. +- Fix schema parser returning on success on some failure modes (#193). ## [0.6.0] From 4bc99c3540ebba2bf5de97a20e170592b01dcecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Mon, 21 Jun 2021 12:05:07 +0200 Subject: [PATCH 028/106] Fix missing '_with_identifier' in documentation --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 255125d04..78aa7e5d3 100644 --- a/README.md +++ b/README.md @@ -1088,7 +1088,8 @@ In the builder example above, we can apply a verifier to the output: int ret; ... ... finalize - if ((ret = ns(Monster_verify_as_root(buffer, size, "MONS")))) { + if ((ret = ns(Monster_verify_as_root_with_identifier(buffer, size, + "MONS")))) { printf("Monster buffer is invalid: %s\n", flatcc_verify_error_string(ret)); } From 28a62c521fde0790aafc5e9dd999f88242dab8d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Tue, 22 Jun 2021 17:29:18 +0200 Subject: [PATCH 029/106] Fix documentation on scalar vector fields --- doc/builder.md | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/doc/builder.md b/doc/builder.md index 14ac10d8c..cef88c18d 100644 --- a/doc/builder.md +++ b/doc/builder.md @@ -1053,17 +1053,22 @@ type, and because the operations are not type safe (any kind of push would be accepted), some vector operations are also mapped to the field name: + uint8_t v; Monster_inventory_start(B); - Monster_inventory_push(B, 1); - Monster_inventory_push(B, 2); - Monster_inventory_push(B, 3); + v = 1; + Monster_inventory_push(B, &v); + v = 2; + Monster_inventory_push(B, &v); + v = 3; + Monster_inventory_push(B, &v); Monster_inventory_end(B); -Note: vector operations on a type uses the `_vec_` syntax, -for example `uint8_vec_push` or `Monster_vec_push` while operations that -are mapped onto table field names of vector type do not use the `_vec` -infix because it is not a type name, for example `Monster_inventory_push`. +The field vector operations always use pointers to element values and cannot push scalars by value as is the case with the typed vector operations. +Vector operations on a type uses the `_vec_` syntax, for example +`uint8_vec_push` or `Monster_vec_push` while operations that are mapped onto +table field names of vector type do not use the `_vec` infix because it is not a +type name, for example `Monster_inventory_push`. A slightly faster operation preallocates the vector: @@ -1081,9 +1086,10 @@ with `edit` and `reserved_len` between `start/end` (recalling that pointers cannot be reused across buffer calls): uint8_t *v, i; + uint8_t data[] = { 1, 2 }; Monster_inventory_start(B); - Monster_inventory_push(B, 1); - Monster_inventory_push(B, 2); + Monster_inventory_push(B, data[0]); + Monster_inventory_push(B, data[1]); v = Monster_inventory_edit(B); for (i = 1; i < Monster_inventory_reserved_len(B); ++i) { v[i] = v[i - 1] + v[i]; From 83850f0cad5411006a5274f93a0a88e0c3e812c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Tue, 22 Jun 2021 17:47:45 +0200 Subject: [PATCH 030/106] Fix documentation on scalar vector fields --- doc/builder.md | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/doc/builder.md b/doc/builder.md index cef88c18d..f79b59df1 100644 --- a/doc/builder.md +++ b/doc/builder.md @@ -1030,21 +1030,29 @@ without being concerned with the underlying integer type, for example: ## Vectors Vectors can be created independently, or directly when updating a table - the -end result is the same. +end result is the same. Builder vector operations always reference element +values by pointer, or by reference for offset types like tables and strings. + uint8_t v; Monster_inventory_start(B); - flatbuffers_uint8_vec_push(B, 1); - flatbuffers_uint8_vec_push(B, 2); - flatbuffers_uint8_vec_push(B, 3); + v = 1; + flatbuffers_uint8_vec_push(B, &v); + v = 2; + flatbuffers_uint8_vec_push(B, &v); + v = 3; + flatbuffers_uint8_vec_push(B, &v); Monster_inventory_end(B); or flatbuffers_uint8_vec_ref_t inv; flatbuffers_uint8_vec_start(B); - flatbuffers_uint8_vec_push(B, 1); - flatbuffers_uint8_vec_push(B, 2); - flatbuffers_uint8_vec_push(B, 3); + v = 1; + flatbuffers_uint8_vec_push(B, &v); + v = 2; + flatbuffers_uint8_vec_push(B, &v); + v = 3; + flatbuffers_uint8_vec_push(B, &v); inv = flatbuffers_uint8_vec_end(B); Monster_inventory_add(B, inv); @@ -1063,12 +1071,10 @@ name: Monster_inventory_push(B, &v); Monster_inventory_end(B); -The field vector operations always use pointers to element values and cannot push scalars by value as is the case with the typed vector operations. - -Vector operations on a type uses the `_vec_` syntax, for example -`uint8_vec_push` or `Monster_vec_push` while operations that are mapped onto -table field names of vector type do not use the `_vec` infix because it is not a -type name, for example `Monster_inventory_push`. +Note: vector operations on a type uses the `_vec_` syntax, for +example `uint8_vec_push` or `Monster_vec_push` while operations that are mapped +onto table field names of vector type do not use the `_vec` infix because it is +not a type name, for example `Monster_inventory_push`. A slightly faster operation preallocates the vector: @@ -1088,8 +1094,8 @@ cannot be reused across buffer calls): uint8_t *v, i; uint8_t data[] = { 1, 2 }; Monster_inventory_start(B); - Monster_inventory_push(B, data[0]); - Monster_inventory_push(B, data[1]); + Monster_inventory_push(B, &data[0]); + Monster_inventory_push(B, &data[1]); v = Monster_inventory_edit(B); for (i = 1; i < Monster_inventory_reserved_len(B); ++i) { v[i] = v[i - 1] + v[i]; @@ -1129,7 +1135,7 @@ translated into similar calls prefixed with the field name instead of `vector` and except for `start`, the calls also add the vector to the table if successful, for example: - uint8_t data[] = [1, 2, 3]; + uint8_t data[] = { 1, 2, 3 }; Monster_inventory_create(B, data, 3); Monster_breadcrumbs_slice(B, some_other_breadcrumbs, 0, 10); @@ -1175,7 +1181,7 @@ on all platforms if `vec_end_pe` is used at the end. A vector may also be created from an existing array: - uint8_t data[] = {1, 2, 3}; + uint8_t data[] = { 1, 2, 3 }; Monster_inventory_add(B, flatbuffers_uint8_vec_create(B, data, 3)); This also applies to arrays of structs as long as they are properly zero From d875e6aebb64156a292bb9f494f57cdd0bb5f9b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Tue, 22 Jun 2021 17:49:18 +0200 Subject: [PATCH 031/106] Fix documentation on scalar vector fields --- doc/builder.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/builder.md b/doc/builder.md index f79b59df1..c9537704d 100644 --- a/doc/builder.md +++ b/doc/builder.md @@ -1046,6 +1046,7 @@ values by pointer, or by reference for offset types like tables and strings. or flatbuffers_uint8_vec_ref_t inv; + uint8_t v; flatbuffers_uint8_vec_start(B); v = 1; flatbuffers_uint8_vec_push(B, &v); From 69503a62a12d3d492914a5bf940f9638ab4c07d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Tue, 22 Jun 2021 18:49:43 +0200 Subject: [PATCH 032/106] Fix large constants in json parser --- src/compiler/codegen_c_json_parser.c | 34 ++++------------------------ 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/src/compiler/codegen_c_json_parser.c b/src/compiler/codegen_c_json_parser.c index 3d526ee63..e516ad686 100644 --- a/src/compiler/codegen_c_json_parser.c +++ b/src/compiler/codegen_c_json_parser.c @@ -422,6 +422,7 @@ static int gen_field_match_handler(fb_output_t *out, fb_compound_type_t *ct, voi size_t array_len = 0; fb_scalar_type_t st = 0; const char *tname_prefix = "n/a", *tname = "n/a"; /* suppress compiler warnigns */ + fb_literal_t literal; fb_clear(snref); @@ -604,36 +605,9 @@ static int gen_field_match_handler(fb_output_t *out, fb_compound_type_t *ct, voi if (!is_struct_container && !is_vector && !is_base64 && !is_base64url) { #if !FLATCC_JSON_PARSE_FORCE_DEFAULTS /* We need to create a check for the default value and create a table field if not the default. */ - if (!is_optional) - switch (member->value.type) { - case vt_bool: - case vt_uint: - println(out, "if (val != %"PRIu64" || (ctx->flags & flatcc_json_parser_f_force_add)) {", member->value.u); indent(); - break; - case vt_int: - println(out, "if (val != %"PRId64" || (ctx->flags & flatcc_json_parser_f_force_add)) {", member->value.i); indent(); - break; - /* - * NOTE: We only store default value as a double float - - * if the field type is a 32-bit single precision float - * we might not print the exact value and thus we cannot - * test exactly for default - but then we store a value - * close to the default, or get a default close to the - * value. The same problem exists in the generated - * builder. Regardless, there is also truncation and - * rounding when parsing the original default value from - * the schema, so as long as we are consistent ... The - * flatbuffers reflection schema also only has a real - * type (64-bit double precision float). - * Even with double precision, printing is not an exact - * science and depends on the runtime library. - */ - case vt_float: - println(out, "if (val != %lf || (ctx->flags & flatcc_json_parser_f_force_add)) {", (double)member->value.f); indent(); - break; - default: - gen_panic(out, "internal error: unexpected default value type\n"); - return -1; + if (!is_optional) { + if (!print_literal(st, &member->value, literal)) return -1; + println(out, "if (val != %s || (ctx->flags & flatcc_json_parser_f_force_add)) {", literal); indent(); } #endif println(out, "if (!(pval = flatcc_builder_table_add(ctx->ctx, %"PRIu64", %"PRIu64", %hu))) goto failed;", From ee73bfbaf2285563f5efe6bdb03a55ea8e6a67c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Wed, 23 Jun 2021 19:14:39 +0200 Subject: [PATCH 033/106] Fix large constants in json printer --- src/compiler/codegen_c_json_printer.c | 165 +++++++++----------------- 1 file changed, 55 insertions(+), 110 deletions(-) diff --git a/src/compiler/codegen_c_json_printer.c b/src/compiler/codegen_c_json_printer.c index d27ba9d69..3b9a67d9f 100644 --- a/src/compiler/codegen_c_json_printer.c +++ b/src/compiler/codegen_c_json_printer.c @@ -38,30 +38,31 @@ static int gen_json_printer_enum(fb_output_t *out, fb_compound_type_t *ct) const char *tp, *tn, *ns; int bit_flags; uint64_t mask = 0; - char *suffix = ""; + char *constwrap = ""; char *ut = ""; + fb_scalar_type_t st = ct->type.st; fb_clear(snt); fb_clear(snref); fb_compound_name(ct, &snt); - tp = scalar_type_prefix(ct->type.st); - tn = scalar_type_name(ct->type.st); - ns = scalar_type_ns(ct->type.st, out->nsc); + tp = scalar_type_prefix(st); + tn = scalar_type_name(st); + ns = scalar_type_ns(st, out->nsc); bit_flags = !!(ct->metadata_flags & fb_f_bit_flags); if (bit_flags) { switch (ct->size) { case 1: - mask = 0xff, suffix = "U", ut = "uint8_t"; + mask = UINT8_MAX, constwrap = "UINT8_C", ut = "uint8_t"; break; case 2: - mask = 0xffff, suffix = "U", ut = "uint16_t"; + mask = UINT16_MAX, constwrap = "UINT16_C", ut = "uint16_t"; break; case 4: - mask = 0xffffffffL, suffix = "UL", ut = "uint32_t"; + mask = UINT32_MAX, constwrap = "UINT32_C", ut = "uint32_t"; break; default: - mask = 0xffffffffffffffffULL, suffix = "ULL", ut = "uint64_t"; + mask = UINT64_MAX, constwrap = "UINT64_C", ut = "uint64_t"; break; } for (sym = ct->members; sym; sym = sym->link) { @@ -100,11 +101,11 @@ static int gen_json_printer_enum(fb_output_t *out, fb_compound_type_t *ct) */ if (mask) { fprintf(out->fp, - " if ((x & 0x%"PRIx64") || x == 0) {\n" + " if ((x & %s(0x%"PRIx64")) || x == 0) {\n" " flatcc_json_printer_%s(ctx, v);\n" " return;\n" " }\n", - mask, tp); + constwrap, mask, tp); } /* * Test if multiple bits set. We may have a configuration option @@ -119,16 +120,16 @@ static int gen_json_printer_enum(fb_output_t *out, fb_compound_type_t *ct) member = (fb_member_t *)sym; switch (member->value.type) { case vt_uint: - fprintf(out->fp, " if (x & 0x%"PRIx64"%s) flatcc_json_printer_enum_flag(ctx, i++, \"%.*s\", %ld);\n", - member->value.u, suffix, (int)sym->ident->len, sym->ident->text, sym->ident->len); + fprintf(out->fp, " if (x & %s(0x%"PRIx64")) flatcc_json_printer_enum_flag(ctx, i++, \"%.*s\", %ld);\n", + constwrap, member->value.u, (int)sym->ident->len, sym->ident->text, sym->ident->len); break; case vt_int: - fprintf(out->fp, " if (x & 0x%"PRIx64"%s) flatcc_json_printer_enum_flag(ctx, i++, \"%.*s\", %ld);\n", - (uint64_t)member->value.i, suffix, (int)sym->ident->len, sym->ident->text, sym->ident->len); + fprintf(out->fp, " if (x & %s(0x%"PRIx64")) flatcc_json_printer_enum_flag(ctx, i++, \"%.*s\", %ld);\n", + constwrap, (uint64_t)member->value.i, (int)sym->ident->len, sym->ident->text, sym->ident->len); break; case vt_bool: - fprintf(out->fp, " if (x & 0x%"PRIx64"%s) flatcc_json_printer_enum_flag(ctx, i++, \"%.*s\", %ld);\n", - (uint64_t)member->value.b, suffix, (int)sym->ident->len, sym->ident->text, sym->ident->len); + fprintf(out->fp, " if (x & %s(0x%"PRIx64")) flatcc_json_printer_enum_flag(ctx, i++, \"%.*s\", %ld);\n", + constwrap, (uint64_t)member->value.b, (int)sym->ident->len, sym->ident->text, sym->ident->len); break; default: gen_panic(out, "internal error: unexpected value type for enum json_print"); @@ -142,16 +143,16 @@ static int gen_json_printer_enum(fb_output_t *out, fb_compound_type_t *ct) member = (fb_member_t *)sym; switch (member->value.type) { case vt_uint: - fprintf(out->fp, " case %"PRIu64": flatcc_json_printer_enum(ctx, \"%.*s\", %ld); break;\n", - member->value.u, (int)sym->ident->len, sym->ident->text, sym->ident->len); + fprintf(out->fp, " case %s(%"PRIu64"): flatcc_json_printer_enum(ctx, \"%.*s\", %ld); break;\n", + constwrap, member->value.u, (int)sym->ident->len, sym->ident->text, sym->ident->len); break; case vt_int: - fprintf(out->fp, " case %"PRId64": flatcc_json_printer_enum(ctx, \"%.*s\", %ld); break;\n", - member->value.i, (int)sym->ident->len, sym->ident->text, sym->ident->len); + fprintf(out->fp, " case %s(%"PRId64"): flatcc_json_printer_enum(ctx, \"%.*s\", %ld); break;\n", + constwrap, member->value.i, (int)sym->ident->len, sym->ident->text, sym->ident->len); break; case vt_bool: - fprintf(out->fp, " case %u: flatcc_json_printer_enum(ctx, \"%.*s\", %ld); break;\n", - member->value.b, (int)sym->ident->len, sym->ident->text, sym->ident->len); + fprintf(out->fp, " case %s(%u): flatcc_json_printer_enum(ctx, \"%.*s\", %ld); break;\n", + constwrap, member->value.b, (int)sym->ident->len, sym->ident->text, sym->ident->len); break; default: gen_panic(out, "internal error: unexpected value type for enum json_print"); @@ -393,44 +394,16 @@ static int gen_json_printer_table(fb_output_t *out, fb_compound_type_t *ct) switch (member->type.type) { case vt_scalar_type: tp = scalar_type_prefix(member->type.st); - switch(member->value.type) { - case vt_bool: - case vt_uint: - if (is_optional) { - fprintf( out->fp, - "flatcc_json_printer_%s_optional_field(ctx, td, %"PRIu64", \"%.*s\", %ld);", - tp, member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len); - } else { - fprintf( out->fp, - "flatcc_json_printer_%s_field(ctx, td, %"PRIu64", \"%.*s\", %ld, %"PRIu64");", - tp, member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len, member->value.u); - } - break; - case vt_int: - if (is_optional) { - fprintf( out->fp, - "flatcc_json_printer_%s_optional_field(ctx, td, %"PRIu64", \"%.*s\", %ld);", - tp, member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len); - } else { - fprintf( out->fp, - "flatcc_json_printer_%s_field(ctx, td, %"PRIu64", \"%.*s\", %ld, %"PRId64");", - tp, member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len, member->value.i); - } - break; - case vt_float: - if (is_optional) { - fprintf( out->fp, - "flatcc_json_printer_%s_optional_field(ctx, td, %"PRIu64", \"%.*s\", %ld);", - tp, member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len); - } else { - fprintf( out->fp, - "flatcc_json_printer_%s_field(ctx, td, %"PRIu64", \"%.*s\", %ld, %lf);", - tp, member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len, member->value.f); - } - break; - default: - gen_panic(out, "internal error: unexpected default value type\n"); - goto fail; + if (is_optional) { + fprintf( out->fp, + "flatcc_json_printer_%s_optional_field(ctx, td, %"PRIu64", \"%.*s\", %ld);", + tp, member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len); + } else { + fb_literal_t literal; + if (!print_literal(member->type.st, &member->value, literal)) return -1; + fprintf( out->fp, + "flatcc_json_printer_%s_field(ctx, td, %"PRIu64", \"%.*s\", %ld, %s);", + tp, member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len, literal); } break; case vt_vector_type: @@ -480,59 +453,31 @@ static int gen_json_printer_table(fb_output_t *out, fb_compound_type_t *ct) switch (member->type.ct->symbol.kind) { case fb_is_enum: tp = scalar_type_prefix(member->type.ct->type.st); - switch(member->value.type) { - case vt_bool: #if FLATCC_JSON_PRINT_MAP_ENUMS - case vt_uint: - if (is_optional) { - fprintf( out->fp, - "flatcc_json_printer_%s_enum_optional_field(ctx, td, %"PRIu64", \"%.*s\", %ld, %s_print_json_enum);", - tp, member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len, snref.text); - } else { - fprintf( out->fp, - "flatcc_json_printer_%s_enum_field(ctx, td, %"PRIu64", \"%.*s\", %ld, %"PRIu64", %s_print_json_enum);", - tp, member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len, member->value.u, snref.text); - } - break; - case vt_int: - if (is_optional) { - fprintf( out->fp, - "flatcc_json_printer_%s_enum_optional_field(ctx, td, %"PRIu64", \"%.*s\", %ld, %s_print_json_enum);", - tp, member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len, snref.text); - } else { - fprintf( out->fp, - "flatcc_json_printer_%s_enum_field(ctx, td, %"PRIu64", \"%.*s\", %ld, %"PRId64", %s_print_json_enum);", - tp, member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len, member->value.i, snref.text); - } - break; + if (is_optional) { + fprintf(out->fp, + "flatcc_json_printer_%s_enum_optional_field(ctx, td, %"PRIu64", \"%.*s\", %ld, %s_print_json_enum);", + tp, member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len, snref.text); + } else { + fb_literal_t literal; + if (!print_literal(member->type.ct->type.st, &member->value, literal)) return -1; + fprintf(out->fp, + "flatcc_json_printer_%s_enum_field(ctx, td, %"PRIu64", \"%.*s\", %ld, %s, %s_print_json_enum);", + tp, member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len, literal, snref.text); + } #else - case vt_uint: - if (is_optional) { - fprintf( out->fp, - "flatcc_json_printer_%s_optional_field(ctx, td, %"PRIu64", \"%.*s\", %ld);", - tp, member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len); - } else { - fprintf( out->fp, - "flatcc_json_printer_%s_field(ctx, td, %"PRIu64", \"%.*s\", %ld, %"PRIu64");", - tp, member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len, member->value.u); - } - break; - case vt_int: - if (is_optional) { - fprintf( out->fp, - "flatcc_json_printer_%s_optinal_field(ctx, td, %"PRIu64", \"%.*s\", %ld);", - tp, member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len); - } else { - fprintf( out->fp, - "flatcc_json_printer_%s_field(ctx, td, %"PRIu64", \"%.*s\", %ld, %"PRId64");", - tp, member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len, member->value.i); - } - break; -#endif - default: - gen_panic(out, "internal error: unexpected default value type for enum\n"); - goto fail; + if (is_optional) { + fprintf( out->fp, + "flatcc_json_printer_%s_optional_field(ctx, td, %"PRIu64", \"%.*s\", %ld);", + tp, member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len); + } else { + fb_literal_t literal; + if (!print_literal(member->type.ct->type.st, &member->value, literal)) return -1; + fprintf( out->fp, + "flatcc_json_printer_%s_field(ctx, td, %"PRIu64", \"%.*s\", %ld, %s);", + tp, member->id, (int)sym->ident->len, sym->ident->text, sym->ident->len, literal); } +#endif break; case fb_is_struct: fprintf(out->fp, From 66121594ded0ef17de68f532721bf86913806d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Thu, 24 Jun 2021 09:30:04 +0200 Subject: [PATCH 034/106] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57242b574..99a7be6f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,7 @@ - Fix buffer overrun when parser reports error on large symbols (#188). - BREAKING: Print --version to stdout, not stderr. - Fix schema parser returning on success on some failure modes (#193). +- Fix larger integer literal types in JSON parser and printer (#194). ## [0.6.0] From e717c20dced58a173ee436dfac223eb00621f5d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= Date: Fri, 9 Jul 2021 17:01:28 +0200 Subject: [PATCH 035/106] Fix compiler error message in process_table (#196) --- src/compiler/semantics.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/semantics.c b/src/compiler/semantics.c index a6d765b12..3338c04fc 100644 --- a/src/compiler/semantics.c +++ b/src/compiler/semantics.c @@ -1255,8 +1255,8 @@ static int process_table(fb_parser_t *P, fb_compound_type_t *ct) if (!id_failed && type_sym && type_sym->kind == fb_is_union) { if (member->id <= 1) { error_tok(P, m->ident, is_union_vector ? - "id attribute value should be larger to accomdate hidden union vector type field" : - "id attribute value should be larger to accomdate hidden union type field"); + "id attribute value should be larger to accommodate hidden union vector type field" : + "id attribute value should be larger to accommodate hidden union type field"); id_failed = 1; } else if (field_marker[member->id - 1] == type_field) { error_tok(P, m->ident, is_union_vector ? From 5bc7c3512109e5fd6ea231fe1d76f09e1ce7a24e Mon Sep 17 00:00:00 2001 From: Andrew Sun Date: Thu, 22 Jul 2021 13:25:50 -0400 Subject: [PATCH 036/106] Fix undefined zero length memcpy in fileio.c and semantics.c (#199) --- src/compiler/fileio.c | 6 ++++-- src/compiler/semantics.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/compiler/fileio.c b/src/compiler/fileio.c index 17e0e0399..56d88c114 100644 --- a/src/compiler/fileio.c +++ b/src/compiler/fileio.c @@ -62,8 +62,10 @@ char *fb_create_join_path_n(const char *prefix, size_t prefix_len, return 0; } n = 0; - memcpy(path, prefix, prefix_len); - n += prefix_len; + if (prefix_len > 0) { + memcpy(path, prefix, prefix_len); + n += prefix_len; + } if (path_sep) { path[n++] = '/'; } diff --git a/src/compiler/semantics.c b/src/compiler/semantics.c index 3338c04fc..311ef4a2a 100644 --- a/src/compiler/semantics.c +++ b/src/compiler/semantics.c @@ -1543,7 +1543,7 @@ static int process_enum(fb_parser_t *P, fb_compound_type_t *ct) fb_symbol_t *sym, *old, *type_sym; fb_member_t *member; fb_metadata_t *knowns[KNOWN_ATTR_COUNT]; - fb_value_t index; + fb_value_t index = { 0 }; fb_value_t old_index; int first = 1; int bit_flags = 0; From 5e3b712246cf0ad960a597e5ac45ff6e9691b198 Mon Sep 17 00:00:00 2001 From: Daniel Horner Date: Sat, 31 Jul 2021 01:51:26 -0700 Subject: [PATCH 037/106] Add void parameters to function definitions (#202) - for clang -Wstrict-prototypes --- test/emit_test/emit_test.c | 4 ++-- test/json_test/test_json.c | 12 ++++++------ test/json_test/test_json_parser.c | 2 +- test/json_test/test_json_printer.c | 2 +- test/optional_scalars_test/optional_scalars_test.c | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/test/emit_test/emit_test.c b/test/emit_test/emit_test.c index eec2d264d..fa18034ac 100644 --- a/test/emit_test/emit_test.c +++ b/test/emit_test/emit_test.c @@ -30,7 +30,7 @@ int dbg_emitter(void *emit_context, return 0; } -int debug_test() +int debug_test(void) { flatcc_builder_t builder, *B; float x[10] = { 0 }; @@ -48,7 +48,7 @@ int debug_test() * this assumes a very simple schema: * "table { time: long; device: ubyte; samples: [float]; }" */ -int emit_test() +int emit_test(void) { /* * Note that there is some apparently unnecessary padding after 0x01 diff --git a/test/json_test/test_json.c b/test/json_test/test_json.c index 9d6d0c996..6d6698b80 100644 --- a/test/json_test/test_json.c +++ b/test/json_test/test_json.c @@ -139,7 +139,7 @@ int test_json(const struct test_scope *scope, char *json, #define TEST_ERROR_FLAGS(fparse, fprint, x, err) \ ret |= test_json(scope, (x), 0, err, (fparse), (fprint), __LINE__); -int edge_case_tests() +int edge_case_tests(void) { BEGIN_TEST(Monster); /* @@ -280,7 +280,7 @@ int edge_case_tests() END_TEST(); } -int error_case_tests() +int error_case_tests(void) { BEGIN_TEST(Monster); @@ -363,7 +363,7 @@ int error_case_tests() #define RANDOM_BASE64URL_NOPAD "zLOuiUjH49tz4Ap2JnmpTX5NqoiMzlD8hSw45QCS2yaSp7UYoA" \ "oE8KpY_5pKYmk-54NI40hyeyZ1zRUE4vKQT0hEdVl0iXq2fqPamkVD1AZlVvQJ1m00PaoXOSgG-64Zv-Uygw" -int base64_tests() +int base64_tests(void) { BEGIN_TEST(Monster); @@ -425,7 +425,7 @@ int base64_tests() END_TEST(); } -int mixed_type_union_tests() +int mixed_type_union_tests(void) { BEGIN_TEST(Movie); @@ -479,7 +479,7 @@ int mixed_type_union_tests() END_TEST(); } -int union_vector_tests() +int union_vector_tests(void) { BEGIN_TEST(Alt); /* Union vector */ @@ -505,7 +505,7 @@ int union_vector_tests() END_TEST(); } -int fixed_array_tests() +int fixed_array_tests(void) { BEGIN_TEST(Alt); /* Fixed array */ diff --git a/test/json_test/test_json_parser.c b/test/json_test/test_json_parser.c index 14cd23767..de2b738b2 100644 --- a/test/json_test/test_json_parser.c +++ b/test/json_test/test_json_parser.c @@ -64,7 +64,7 @@ int verify_parse(void *buffer) // first iteration. This suggests there is an end check missing somwhere // and this needs to be debugged. The input size as of this writing is 701 // bytes, and the output size is 288 bytes. -int test_parse() +int test_parse(void) { #if FLATCC_BENCHMARK double t1, t2; diff --git a/test/json_test/test_json_printer.c b/test/json_test/test_json_printer.c index 48c39e9be..efbd57245 100644 --- a/test/json_test/test_json_printer.c +++ b/test/json_test/test_json_printer.c @@ -23,7 +23,7 @@ const char *filename = 0; /* "monsterdata_test.mon"; */ const char *golden_filename = "monsterdata_test.golden"; const char *target_filename = "monsterdata_test.json.txt"; -int test_print() +int test_print(void) { int ret = 0; const char *buf = 0; diff --git a/test/optional_scalars_test/optional_scalars_test.c b/test/optional_scalars_test/optional_scalars_test.c index e5dbf48a7..7566c056c 100644 --- a/test/optional_scalars_test/optional_scalars_test.c +++ b/test/optional_scalars_test/optional_scalars_test.c @@ -159,7 +159,7 @@ int access_scalar_stuff(const void *buf) return 0; } -int test() +int test(void) { flatcc_builder_t builder; void *buf; @@ -192,7 +192,7 @@ int print_buffer(const void *buf, size_t size) } #endif -int test_json_printer() +int test_json_printer(void) { flatcc_builder_t builder; void *buf; @@ -219,7 +219,7 @@ int test_json_printer() return 0; } -int test_json_parser() +int test_json_parser(void) { flatcc_builder_t builder; void *buf; From 9d583b82c4d77016108cd6d85582e8883cdd5daf Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Tue, 3 Aug 2021 11:46:37 -0700 Subject: [PATCH 038/106] build: repair the build where CMake is not on the path (#204) When cmake is not on the path, the build would previously fail as it hardcoded the name for the cmake binary, expecting to find it on the path. Use `CMAKE_COMMAND` instead to reference the cmake binary that was used to configure the target. --- samples/monster/CMakeLists.txt | 2 +- samples/reflection/CMakeLists.txt | 2 +- test/emit_test/CMakeLists.txt | 2 +- test/flatc_compat/CMakeLists.txt | 4 ++-- test/json_test/CMakeLists.txt | 6 +++--- test/load_test/CMakeLists.txt | 2 +- test/monster_test/CMakeLists.txt | 2 +- test/monster_test_concat/CMakeLists.txt | 2 +- test/monster_test_cpp/CMakeLists.txt | 2 +- test/monster_test_prefix/CMakeLists.txt | 2 +- test/monster_test_solo/CMakeLists.txt | 2 +- test/optional_scalars_test/CMakeLists.txt | 2 +- test/reflection_test/CMakeLists.txt | 2 +- 13 files changed, 16 insertions(+), 16 deletions(-) diff --git a/samples/monster/CMakeLists.txt b/samples/monster/CMakeLists.txt index a14e10990..1c0345539 100644 --- a/samples/monster/CMakeLists.txt +++ b/samples/monster/CMakeLists.txt @@ -9,7 +9,7 @@ include_directories("${GEN_DIR}" "${INC_DIR}") add_custom_target(gen_monster_fbs ALL) add_custom_command ( TARGET gen_monster_fbs - COMMAND cmake -E make_directory "${GEN_DIR}" + COMMAND ${CMAKE_COMMAND} -E make_directory "${GEN_DIR}" COMMAND flatcc_cli -a -o "${GEN_DIR}" "${FBS_DIR}/monster.fbs" DEPENDS flatcc_cli "${FBS_DIR}/monster.fbs" ) diff --git a/samples/reflection/CMakeLists.txt b/samples/reflection/CMakeLists.txt index db5b75445..cfbef1c01 100644 --- a/samples/reflection/CMakeLists.txt +++ b/samples/reflection/CMakeLists.txt @@ -18,7 +18,7 @@ include_directories("${GEN_DIR}" "${INC_DIR}") add_custom_target(gen_monster_bfbs ALL) add_custom_command ( TARGET gen_monster_bfbs - COMMAND cmake -E make_directory "${GEN_DIR}" + COMMAND ${CMAKE_COMMAND} -E make_directory "${GEN_DIR}" COMMAND flatcc_cli --schema -o "${GEN_DIR}" "${FBS_DIR}/monster.fbs" DEPENDS flatcc_cli "${FBS_DIR}/monster.fbs" ) diff --git a/test/emit_test/CMakeLists.txt b/test/emit_test/CMakeLists.txt index aac5fb790..54f3b2860 100644 --- a/test/emit_test/CMakeLists.txt +++ b/test/emit_test/CMakeLists.txt @@ -9,7 +9,7 @@ include_directories("${GEN_DIR}" "${INC_DIR}") add_custom_target(gen_emit_test ALL) add_custom_command ( TARGET gen_emit_test - COMMAND cmake -E make_directory "${GEN_DIR}" + COMMAND ${CMAKE_COMMAND} -E make_directory "${GEN_DIR}" COMMAND flatcc_cli -a -o "${GEN_DIR}" "${FBS_DIR}/emit_test.fbs" DEPENDS flatcc_cli "${FBS}" ) diff --git a/test/flatc_compat/CMakeLists.txt b/test/flatc_compat/CMakeLists.txt index 6a9a4a3f6..a47297956 100644 --- a/test/flatc_compat/CMakeLists.txt +++ b/test/flatc_compat/CMakeLists.txt @@ -9,8 +9,8 @@ include_directories("${GEN_DIR}" "${INC_DIR}") add_custom_target(gen_flatc_compat ALL) add_custom_command ( TARGET gen_flatc_compat - COMMAND cmake -E make_directory "${GEN_DIR}" - COMMAND cmake -E copy "${CMAKE_CURRENT_SOURCE_DIR}/monsterdata_test.mon" ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E make_directory "${GEN_DIR}" + COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/monsterdata_test.mon" ${CMAKE_CURRENT_BINARY_DIR} COMMAND flatcc_cli -a -o "${GEN_DIR}" "${FBS_DIR}/monster_test.fbs" DEPENDS flatcc_cli "${FBS_DIR}/monster_test.fbs" "${FBS_DIR}/include_test1.fbs" "${FBS_DIR}/include_test2.fbs" ) diff --git a/test/json_test/CMakeLists.txt b/test/json_test/CMakeLists.txt index fec6c7c1a..332905d6c 100644 --- a/test/json_test/CMakeLists.txt +++ b/test/json_test/CMakeLists.txt @@ -12,9 +12,9 @@ include_directories("${GEN_DIR}" "${INC_DIR}") add_custom_target(gen_monster_test_json ALL) add_custom_command ( TARGET gen_monster_test_json - COMMAND cmake -E make_directory "${GEN_DIR}" - COMMAND cmake -E copy "${DATA_SRC}/monsterdata_test.golden" "${DATA_DST}" - COMMAND cmake -E copy "${DATA_SRC}/monsterdata_test.mon" "${DATA_DST}" + COMMAND ${CMAKE_COMMAND} -E make_directory "${GEN_DIR}" + COMMAND ${CMAKE_COMMAND} -E copy "${DATA_SRC}/monsterdata_test.golden" "${DATA_DST}" + COMMAND ${CMAKE_COMMAND} -E copy "${DATA_SRC}/monsterdata_test.mon" "${DATA_DST}" COMMAND flatcc_cli -av --json -o "${GEN_DIR}" "${FBS_DIR}/monster_test.fbs" DEPENDS flatcc_cli "${FBS_DIR}/monster_test.fbs" "${FBS_DIR}/include_test1.fbs" "${FBS_DIR}/include_test2.fbs" ) diff --git a/test/load_test/CMakeLists.txt b/test/load_test/CMakeLists.txt index 6d444a547..0c146d112 100644 --- a/test/load_test/CMakeLists.txt +++ b/test/load_test/CMakeLists.txt @@ -9,7 +9,7 @@ include_directories("${GEN_DIR}" "${INC_DIR}") add_custom_target(gen_load_test ALL) add_custom_command ( TARGET gen_load_test - COMMAND cmake -E make_directory "${GEN_DIR}" + COMMAND ${CMAKE_COMMAND} -E make_directory "${GEN_DIR}" COMMAND flatcc_cli -a -o "${GEN_DIR}" "${FBS_DIR}/monster_test.fbs" DEPENDS flatcc_cli "${FBS_DIR}/monster_test.fbs" "${FBS_DIR}/include_test1.fbs" "${FBS_DIR}/include_test2.fbs" ) diff --git a/test/monster_test/CMakeLists.txt b/test/monster_test/CMakeLists.txt index 818292725..5860a37e5 100644 --- a/test/monster_test/CMakeLists.txt +++ b/test/monster_test/CMakeLists.txt @@ -9,7 +9,7 @@ include_directories("${GEN_DIR}" "${INC_DIR}") add_custom_target(gen_monster_test ALL) add_custom_command ( TARGET gen_monster_test - COMMAND cmake -E make_directory "${GEN_DIR}" + COMMAND ${CMAKE_COMMAND} -E make_directory "${GEN_DIR}" COMMAND flatcc_cli -a -o "${GEN_DIR}" "${FBS_DIR}/monster_test.fbs" DEPENDS flatcc_cli "${FBS_DIR}/monster_test.fbs" "${FBS_DIR}/include_test1.fbs" "${FBS_DIR}/include_test2.fbs" ) diff --git a/test/monster_test_concat/CMakeLists.txt b/test/monster_test_concat/CMakeLists.txt index 836ae09e1..dab13f59a 100644 --- a/test/monster_test_concat/CMakeLists.txt +++ b/test/monster_test_concat/CMakeLists.txt @@ -9,7 +9,7 @@ include_directories("${GEN_DIR}" "${INC_DIR}") add_custom_target(gen_monster_test_concat ALL) add_custom_command ( TARGET gen_monster_test_concat - COMMAND cmake -E make_directory "${GEN_DIR}" + COMMAND ${CMAKE_COMMAND} -E make_directory "${GEN_DIR}" # We could also use the recursive -r option, but this tests adding files manually to the output file. COMMAND flatcc_cli -cwv --reader -o "${GEN_DIR}" "--outfile=monster_test.h" "${FBS_DIR}/attributes.fbs" "${FBS_DIR}/include_test2.fbs" "${FBS_DIR}/include_test1.fbs" "${FBS_DIR}/monster_test.fbs" DEPENDS flatcc_cli "${FBS_DIR}/monster_test.fbs" "${FBS_DIR}/include_test1.fbs" "${FBS_DIR}/include_test2.fbs" "${FBS_DIR}/attributes.fbs" ) diff --git a/test/monster_test_cpp/CMakeLists.txt b/test/monster_test_cpp/CMakeLists.txt index 22247a394..dd576ca81 100644 --- a/test/monster_test_cpp/CMakeLists.txt +++ b/test/monster_test_cpp/CMakeLists.txt @@ -12,7 +12,7 @@ include_directories("${GEN_DIR}" "${INC_DIR}") add_custom_target(gen_monster_test_cpp ALL) add_custom_command ( TARGET gen_monster_test_cpp - COMMAND cmake -E make_directory "${GEN_DIR}" + COMMAND ${CMAKE_COMMAND} -E make_directory "${GEN_DIR}" COMMAND flatcc_cli -a -o "${GEN_DIR}" "${FBS_DIR}/monster.fbs" DEPENDS flatcc_cli "${FBS_DIR}/monster.fbs" ) diff --git a/test/monster_test_prefix/CMakeLists.txt b/test/monster_test_prefix/CMakeLists.txt index 13461ec36..1e2676135 100644 --- a/test/monster_test_prefix/CMakeLists.txt +++ b/test/monster_test_prefix/CMakeLists.txt @@ -9,7 +9,7 @@ include_directories("${GEN_DIR}" "${INC_DIR}") add_custom_target(gen_monster_test_prefix ALL) add_custom_command ( TARGET gen_monster_test_prefix - COMMAND cmake -E make_directory "${GEN_DIR}" + COMMAND ${CMAKE_COMMAND} -E make_directory "${GEN_DIR}" COMMAND flatcc_cli -a --prefix=zzz_ --stdout "${FBS_DIR}/monster_test.fbs" > "${GEN_DIR}/zzz_monster_test.h" DEPENDS flatcc_cli "${FBS_DIR}/monster_test.fbs" "${FBS_DIR}/include_test1.fbs" "${FBS_DIR}/include_test2.fbs" ) diff --git a/test/monster_test_solo/CMakeLists.txt b/test/monster_test_solo/CMakeLists.txt index b6294b85f..a974434fb 100644 --- a/test/monster_test_solo/CMakeLists.txt +++ b/test/monster_test_solo/CMakeLists.txt @@ -9,7 +9,7 @@ include_directories("${GEN_DIR}" "${INC_DIR}") add_custom_target(gen_monster_test_solo ALL) add_custom_command ( TARGET gen_monster_test_solo - COMMAND cmake -E make_directory "${GEN_DIR}" + COMMAND ${CMAKE_COMMAND} -E make_directory "${GEN_DIR}" COMMAND flatcc_cli -cwv --reader --stdout "${FBS_DIR}/attributes.fbs" "${FBS_DIR}/include_test2.fbs" "${FBS_DIR}/include_test1.fbs" "${FBS_DIR}/monster_test.fbs" > "${GEN_DIR}/monster_test.h" DEPENDS flatcc_cli "${FBS_DIR}/monster_test.fbs" "${FBS_DIR}/include_test1.fbs" "${FBS_DIR}/include_test2.fbs" "${FBS_DIR}/attributes.fbs" ) diff --git a/test/optional_scalars_test/CMakeLists.txt b/test/optional_scalars_test/CMakeLists.txt index 61a00c71d..b13c1b9ed 100644 --- a/test/optional_scalars_test/CMakeLists.txt +++ b/test/optional_scalars_test/CMakeLists.txt @@ -9,7 +9,7 @@ include_directories("${GEN_DIR}" "${INC_DIR}") add_custom_target(gen_optional_scalars_test ALL) add_custom_command ( TARGET gen_optional_scalars_test - COMMAND cmake -E make_directory "${GEN_DIR}" + COMMAND ${CMAKE_COMMAND} -E make_directory "${GEN_DIR}" COMMAND flatcc_cli -a --json -o "${GEN_DIR}" "${FBS_DIR}/optional_scalars_test.fbs" ) add_executable(optional_scalars_test optional_scalars_test.c) diff --git a/test/reflection_test/CMakeLists.txt b/test/reflection_test/CMakeLists.txt index fa1e4b3f5..f82d1f53c 100644 --- a/test/reflection_test/CMakeLists.txt +++ b/test/reflection_test/CMakeLists.txt @@ -9,7 +9,7 @@ include_directories("${GEN_DIR}" "${INC_DIR}") add_custom_target(gen_reflection_test ALL) add_custom_command ( TARGET gen_reflection_test - COMMAND cmake -E make_directory "${GEN_DIR}" + COMMAND ${CMAKE_COMMAND} -E make_directory "${GEN_DIR}" COMMAND flatcc_cli --schema -o "${GEN_DIR}" "${FBS_DIR}/monster_test.fbs" DEPENDS flatcc_cli "${FBS_DIR}/monster_test.fbs" "${FBS_DIR}/include_test1.fbs" "${FBS_DIR}/include_test2.fbs" ) From 1a01a16c2b4b07fff5f42acd3d70ef90a075b46a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Wed, 4 Aug 2021 11:45:00 +0200 Subject: [PATCH 039/106] Add portable fallthrough attribute --- include/flatcc/portable/pattributes.h | 67 +++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 include/flatcc/portable/pattributes.h diff --git a/include/flatcc/portable/pattributes.h b/include/flatcc/portable/pattributes.h new file mode 100644 index 000000000..96762b6cc --- /dev/null +++ b/include/flatcc/portable/pattributes.h @@ -0,0 +1,67 @@ + +/* + * There are no standard attributes defines as macros. + * + * C23 introduces an attributes `[[]]`. Priot to that + * some compiler versions supported the `__attribute__` syntax. + * + * See also: + * https://en.cppreference.com/w/c/language/attributes + * + * There is no portable way to use C23 attributes in older C standards + * so in order to use these portably, some macro name needs to be + * defined for each attribute. + * + * The Linux kernel defines certain attributes as macros, such as + * `fallthrough`. When adding attributes is seems reasonable to follow + * the Linux conventions in lack of any official standard. However, it + * is not the intention that this file should mirror the Linux + * attributes 1 to 1. + * + * See also: + * https://github.com/torvalds/linux/blob/master/include/linux/compiler_attributes.h + * + * There is a risk that attribute macros may lead to conflicts with + * other symbols. It is suggested to undefine such symbols after + * including this header if that should become a problem. + */ + + +#ifndef PATTRIBUTES_H +#define PATTRIBUTES_H + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __has_c_attribute +# define PORTABLE_HAS_C_ATTRIBUTE(x) __has_c_attribute(x) +#else +# define PORTABLE_HAS_C_ATTRIBUTE(x) 0 +#endif + +#ifdef __has_attribute +# define PORTABLE_HAS_ATTRIBUTE(x) __has_attribute(x) +#else +# define PORTABLE_HAS_ATTRIBUTE(x) 0 +#endif + + +/* https://en.cppreference.com/w/c/language/attributes/fallthrough */ +#ifndef fallthrough +# if PORTABLE_HAS_C_ATTRIBUTE(__fallthrough__) +# define fallthrough [[__fallthrough__]] +# elif PORTABLE_HAS_ATTRIBUTE(__fallthrough__) +# define fallthrough __attribute__((__fallthrough__)) +# else +# define fallthrough ((void)0) +# endif +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* PATTRIBUTES_H */ From 8bdaefa84f999d82d9b0ce61b716b1a356423ce6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Wed, 4 Aug 2021 11:45:34 +0200 Subject: [PATCH 040/106] Add pattributes.h to common flatcc include files --- include/flatcc/flatcc_flatbuffers.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/flatcc/flatcc_flatbuffers.h b/include/flatcc/flatcc_flatbuffers.h index b5a80fe97..4f3edb241 100644 --- a/include/flatcc/flatcc_flatbuffers.h +++ b/include/flatcc/flatcc_flatbuffers.h @@ -23,6 +23,9 @@ extern "C" { /* Needed by C99 compilers without FLATCC_PORTABLE. */ #include "flatcc/portable/pstdalign.h" +/* Handle fallthrough attribute in switch statemnents. */ +#include "flatcc/portable/pattributes.h" + #include "flatcc/flatcc_alloc.h" #include "flatcc/flatcc_assert.h" From 349993ec4e29d3bfc0b2ce4b1af60a799fb2b995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Wed, 4 Aug 2021 12:02:31 +0200 Subject: [PATCH 041/106] Add fallthrough attribute to pprintint.h --- include/flatcc/portable/pprintint.h | 45 ++++++++++++++--------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/include/flatcc/portable/pprintint.h b/include/flatcc/portable/pprintint.h index 45dbdea6a..37f4c2a4c 100644 --- a/include/flatcc/portable/pprintint.h +++ b/include/flatcc/portable/pprintint.h @@ -75,6 +75,8 @@ extern "C" { #include #endif +#include "pattributes.h" /* fallthrough */ + #define PDIAGNOSTIC_IGNORE_UNUSED_FUNCTION #include "pdiagnostic_push.h" @@ -188,10 +190,10 @@ static int print_uint16(uint16_t n, char *p) switch (k) { case 5: __print_stage(); - /* Fall through */ + fallthrough; case 3: __print_stage(); - /* Fall through */ + fallthrough; case 1: p[-1] = (char)n + '0'; } @@ -199,7 +201,7 @@ static int print_uint16(uint16_t n, char *p) switch (k) { case 4: __print_stage(); - /* Fall through */ + fallthrough; case 2: __print_stage(); } @@ -251,16 +253,16 @@ static int print_uint32(uint32_t n, char *p) switch (k) { case 9: __print_stage(); - /* Fall through */ + fallthrough; case 7: __print_stage(); - /* Fall through */ + fallthrough; case 5: __print_stage(); - /* Fall through */ + fallthrough; case 3: __print_stage(); - /* Fall through */ + fallthrough; case 1: p[-1] = (char)n + '0'; } @@ -268,19 +270,18 @@ static int print_uint32(uint32_t n, char *p) switch (k) { case 10: __print_stage(); - /* Fall through */ + fallthrough; case 8: __print_stage(); - /* Fall through */ + fallthrough; case 6: __print_stage(); - /* Fall through */ + fallthrough; case 4: __print_stage(); - /* Fall through */ + fallthrough; case 2: __print_stage(); - /* Fall through */ } } return k; @@ -335,42 +336,40 @@ static int print_uint64(uint64_t n, char *p) p += k; *p = '\0'; if (k & 1) { - /* Fall through comments needed to silence gcc 7 warnings. */ switch (k) { case 19: __print_stage(); - /* Fall through */ + fallthrough; case 17: __print_stage(); - /* Fall through */ + fallthrough; case 15: __print_stage(); - /* Fall through */ + fallthrough; case 13: __print_stage(); - /* Fall through */ + fallthrough; case 11: __print_stage() __print_short_stage(); } } else { - /* Fall through comments needed to silence gcc 7 warnings. */ switch (k) { case 20: __print_stage(); - /* Fall through */ + fallthrough; case 18: __print_stage(); - /* Fall through */ + fallthrough; case 16: __print_stage(); - /* Fall through */ + fallthrough; case 14: __print_stage(); - /* Fall through */ + fallthrough; case 12: __print_stage(); - /* Fall through */ + fallthrough; case 10: __print_stage(); } From d234cdd352ed4b01074da35bb667cab9e99a2a00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Wed, 4 Aug 2021 12:07:13 +0200 Subject: [PATCH 042/106] Silence fallthrough warning --- external/lex/luthor.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/external/lex/luthor.c b/external/lex/luthor.c index df8869e8a..fc81985f3 100644 --- a/external/lex/luthor.c +++ b/external/lex/luthor.c @@ -1367,8 +1367,9 @@ static int lex(const char *buf, size_t len, int mode, void *context) */ } /* If condition around switch under '0' case. */ --p; - /* Fall through. */ + goto lex_fallthrough_1; /* silence warning */ + lex_fallthrough_1: /* Leading integer digit in C integers. */ case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': From 3854524dc9020a7cddd6484a430b73c263781b3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Wed, 4 Aug 2021 22:41:43 +0200 Subject: [PATCH 043/106] Clean up comments --- include/flatcc/portable/pattributes.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/include/flatcc/portable/pattributes.h b/include/flatcc/portable/pattributes.h index 96762b6cc..717f85691 100644 --- a/include/flatcc/portable/pattributes.h +++ b/include/flatcc/portable/pattributes.h @@ -1,7 +1,5 @@ /* - * There are no standard attributes defines as macros. - * * C23 introduces an attributes `[[]]`. Priot to that * some compiler versions supported the `__attribute__` syntax. * @@ -13,7 +11,7 @@ * defined for each attribute. * * The Linux kernel defines certain attributes as macros, such as - * `fallthrough`. When adding attributes is seems reasonable to follow + * `fallthrough`. When adding attributes it seems reasonable to follow * the Linux conventions in lack of any official standard. However, it * is not the intention that this file should mirror the Linux * attributes 1 to 1. From c876ef785773d79cdb82b2b043628e3f1f56157e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Wed, 4 Aug 2021 22:42:19 +0200 Subject: [PATCH 044/106] Typo in comment --- include/flatcc/flatcc_flatbuffers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/flatcc/flatcc_flatbuffers.h b/include/flatcc/flatcc_flatbuffers.h index 4f3edb241..4bfc74352 100644 --- a/include/flatcc/flatcc_flatbuffers.h +++ b/include/flatcc/flatcc_flatbuffers.h @@ -23,7 +23,7 @@ extern "C" { /* Needed by C99 compilers without FLATCC_PORTABLE. */ #include "flatcc/portable/pstdalign.h" -/* Handle fallthrough attribute in switch statemnents. */ +/* Handle fallthrough attribute in switch statements. */ #include "flatcc/portable/pattributes.h" #include "flatcc/flatcc_alloc.h" From 62a7f88611af08c68be5485ce6d9c7e92474eab8 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Wed, 4 Aug 2021 14:16:31 -0700 Subject: [PATCH 045/106] annotate fallthrough paths with attribute. (#203) Use portable fallthrough attribute to silence switch statement warnings. --- include/flatcc/flatcc_json_parser.h | 16 ++++++++-------- src/compiler/codegen_c_json_parser.c | 3 +++ src/compiler/codegen_c_json_printer.c | 3 +++ src/compiler/parser.c | 2 ++ src/compiler/semantics.c | 4 +++- src/runtime/json_parser.c | 2 +- 6 files changed, 20 insertions(+), 10 deletions(-) diff --git a/include/flatcc/flatcc_json_parser.h b/include/flatcc/flatcc_json_parser.h index 9fbcb12ac..1907fc7fc 100644 --- a/include/flatcc/flatcc_json_parser.h +++ b/include/flatcc/flatcc_json_parser.h @@ -246,21 +246,21 @@ static inline uint64_t flatcc_json_parser_symbol_part_ext(const char *buf, const /* Fall through comments needed to silence gcc 7 warnings. */ switch (n) { case 8: w |= ((uint64_t)buf[7]) << (0 * 8); - /* Fall through */ + fallthrough; case 7: w |= ((uint64_t)buf[6]) << (1 * 8); - /* Fall through */ + fallthrough; case 6: w |= ((uint64_t)buf[5]) << (2 * 8); - /* Fall through */ + fallthrough; case 5: w |= ((uint64_t)buf[4]) << (3 * 8); - /* Fall through */ + fallthrough; case 4: w |= ((uint64_t)buf[3]) << (4 * 8); - /* Fall through */ + fallthrough; case 3: w |= ((uint64_t)buf[2]) << (5 * 8); - /* Fall through */ + fallthrough; case 2: w |= ((uint64_t)buf[1]) << (6 * 8); - /* Fall through */ + fallthrough; case 1: w |= ((uint64_t)buf[0]) << (7 * 8); - /* Fall through */ + fallthrough; case 0: break; } diff --git a/src/compiler/codegen_c_json_parser.c b/src/compiler/codegen_c_json_parser.c index e516ad686..29ebc85dd 100644 --- a/src/compiler/codegen_c_json_parser.c +++ b/src/compiler/codegen_c_json_parser.c @@ -8,6 +8,8 @@ #include #endif +#include "flatcc/portable/pattributes.h" /* fallthrough */ + #define PRINTLN_SPMAX 64 static char println_spaces[PRINTLN_SPMAX]; @@ -1768,6 +1770,7 @@ static int gen_json_parser_prototypes(fb_output_t *out) println(out, "const char *buf, size_t bufsiz, int flags);"); unindent(); unindent(); println(out, ""); + fallthrough; default: break; } diff --git a/src/compiler/codegen_c_json_printer.c b/src/compiler/codegen_c_json_printer.c index 3b9a67d9f..2bdaba63d 100644 --- a/src/compiler/codegen_c_json_printer.c +++ b/src/compiler/codegen_c_json_printer.c @@ -6,6 +6,8 @@ #include #endif +#include "flatcc/portable/pattributes.h" /* fallthrough */ + static int gen_json_printer_pretext(fb_output_t *out) { fprintf(out->fp, @@ -581,6 +583,7 @@ static int gen_json_printer_prototypes(fb_output_t *out) fprintf(out->fp, "static int %s_print_json(flatcc_json_printer_t *ctx, const char *buf, size_t bufsiz);\n\n", out->S->basename); + fallthrough; default: break; } diff --git a/src/compiler/parser.c b/src/compiler/parser.c index 502e1a2ad..250d6600d 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -16,6 +16,7 @@ #include "codegen.h" #include "fileio.h" #include "pstrutil.h" +#include "flatcc/portable/pattributes.h" /* fallthrough */ #include "flatcc/portable/pparseint.h" void fb_default_error_out(void *err_ctx, const char *buf, size_t len) @@ -919,6 +920,7 @@ static void parse_enum_decl(fb_parser_t *P, fb_compound_type_t *ct) case tok_kw_float32: case tok_kw_float64: error_tok(P, ct->type.t, "integral type expected"); + fallthrough; default: break; } diff --git a/src/compiler/semantics.c b/src/compiler/semantics.c index 311ef4a2a..a2866cf33 100644 --- a/src/compiler/semantics.c +++ b/src/compiler/semantics.c @@ -11,6 +11,8 @@ #include #endif +#include "flatcc/portable/pattributes.h" /* fallthrough */ + /* Same order as enum! */ static const char *fb_known_attribute_names[] = { "", @@ -699,7 +701,7 @@ static int process_struct(fb_parser_t *P, fb_compound_type_t *ct) switch (member->type.type) { case vt_fixed_array_type_ref: key_ok = 0; - /* fall through */ + fallthrough; case vt_type_ref: type_sym = lookup_type_reference(P, ct->scope, member->type.ref); if (!type_sym) { diff --git a/src/runtime/json_parser.c b/src/runtime/json_parser.c index fbb32d2b0..313bd8085 100644 --- a/src/runtime/json_parser.c +++ b/src/runtime/json_parser.c @@ -144,8 +144,8 @@ const char *flatcc_json_parser_space_ext(flatcc_json_parser_t *ctx, const char * /* Fall through comments needed to silence gcc 7 warnings. */ switch (*buf) { case 0x0d: buf += (end - buf > 1 && buf[1] == 0x0a); - /* Fall through */ /* Consume following LF or treating CR as LF. */ + fallthrough; case 0x0a: ++ctx->line; ctx->line_start = ++buf; continue; case 0x09: ++buf; continue; case 0x20: goto again; /* Don't consume here, sync with power of 2 spaces. */ From 26a5c477bb928712cabd9fc89061198397eebc40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Wed, 4 Aug 2021 23:24:16 +0200 Subject: [PATCH 046/106] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 99a7be6f7..76775d3e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,8 @@ - BREAKING: Print --version to stdout, not stderr. - Fix schema parser returning on success on some failure modes (#193). - Fix larger integer literal types in JSON parser and printer (#194). +- Add pattributes.h to portable library and replace GCC fallthrough comments + with fallthough attribute to also silence clang warnings (#203). ## [0.6.0] From f06da091109d19296ff603e0f91bf9c7eb23e983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Thu, 5 Aug 2021 08:22:18 +0200 Subject: [PATCH 047/106] Optionally hide portable attributes --- include/flatcc/portable/pattributes.h | 35 +++++++++++++++++------ include/flatcc/portable/pprintint.h | 40 +++++++++++++-------------- 2 files changed, 46 insertions(+), 29 deletions(-) diff --git a/include/flatcc/portable/pattributes.h b/include/flatcc/portable/pattributes.h index 717f85691..7f1eb9ca2 100644 --- a/include/flatcc/portable/pattributes.h +++ b/include/flatcc/portable/pattributes.h @@ -1,14 +1,17 @@ /* - * C23 introduces an attributes `[[]]`. Priot to that - * some compiler versions supported the `__attribute__` syntax. + * C23 introduces an attribute syntax `[[]]`. Prior to that + * other non-standard syntaxes such as `__attribute__(())` + * and `__declspec()` have been supported by some compiler + * versions. * * See also: * https://en.cppreference.com/w/c/language/attributes * * There is no portable way to use C23 attributes in older C standards * so in order to use these portably, some macro name needs to be - * defined for each attribute. + * defined for each attribute that either maps to the older supported + * syntax, or ignores the attribute as appropriate. * * The Linux kernel defines certain attributes as macros, such as * `fallthrough`. When adding attributes it seems reasonable to follow @@ -19,9 +22,13 @@ * See also: * https://github.com/torvalds/linux/blob/master/include/linux/compiler_attributes.h * - * There is a risk that attribute macros may lead to conflicts with - * other symbols. It is suggested to undefine such symbols after - * including this header if that should become a problem. + * There is a risk that exposed attribute names may lead to name + * conflicts. A conflicting name can be undefined and if necessary used + * using `pattribute()`. All attributes can be hidden by + * defining `PORTABLE_EXPOSE_ATTRIBUTES=0` in which case + * `pattribute()` can still be used and then if a specific + * attribute name still needs to be exposed, it can be defined manually + * like `#define fallthrough pattribute(fallthrough)`. */ @@ -32,6 +39,9 @@ extern "C" { #endif +#ifndef PORTABLE_EXPOSE_ATTRIBUTES +#define PORTABLE_EXPOSE_ATTRIBUTES 1 +#endif #ifdef __has_c_attribute # define PORTABLE_HAS_C_ATTRIBUTE(x) __has_c_attribute(x) @@ -49,15 +59,22 @@ extern "C" { /* https://en.cppreference.com/w/c/language/attributes/fallthrough */ #ifndef fallthrough # if PORTABLE_HAS_C_ATTRIBUTE(__fallthrough__) -# define fallthrough [[__fallthrough__]] +# define pattribute_fallthrough [[__fallthrough__]] # elif PORTABLE_HAS_ATTRIBUTE(__fallthrough__) -# define fallthrough __attribute__((__fallthrough__)) +# define pattribute_fallthrough __attribute__((__fallthrough__)) # else -# define fallthrough ((void)0) +# define pattribute_fallthrough ((void)0) # endif #endif +#define pattribute(x) pattribute_##x + +#if PORTABLE_EXPOSE_ATTRIBUTES +#define fallthrough pattribute(fallthrough) +#endif + + #ifdef __cplusplus } #endif diff --git a/include/flatcc/portable/pprintint.h b/include/flatcc/portable/pprintint.h index 37f4c2a4c..d05f37611 100644 --- a/include/flatcc/portable/pprintint.h +++ b/include/flatcc/portable/pprintint.h @@ -190,10 +190,10 @@ static int print_uint16(uint16_t n, char *p) switch (k) { case 5: __print_stage(); - fallthrough; + pattribute(fallthrough); case 3: __print_stage(); - fallthrough; + pattribute(fallthrough); case 1: p[-1] = (char)n + '0'; } @@ -201,7 +201,7 @@ static int print_uint16(uint16_t n, char *p) switch (k) { case 4: __print_stage(); - fallthrough; + pattribute(fallthrough); case 2: __print_stage(); } @@ -253,16 +253,16 @@ static int print_uint32(uint32_t n, char *p) switch (k) { case 9: __print_stage(); - fallthrough; + pattribute(fallthrough); case 7: __print_stage(); - fallthrough; + pattribute(fallthrough); case 5: __print_stage(); - fallthrough; + pattribute(fallthrough); case 3: __print_stage(); - fallthrough; + pattribute(fallthrough); case 1: p[-1] = (char)n + '0'; } @@ -270,16 +270,16 @@ static int print_uint32(uint32_t n, char *p) switch (k) { case 10: __print_stage(); - fallthrough; + pattribute(fallthrough); case 8: __print_stage(); - fallthrough; + pattribute(fallthrough); case 6: __print_stage(); - fallthrough; + pattribute(fallthrough); case 4: __print_stage(); - fallthrough; + pattribute(fallthrough); case 2: __print_stage(); } @@ -339,16 +339,16 @@ static int print_uint64(uint64_t n, char *p) switch (k) { case 19: __print_stage(); - fallthrough; + pattribute(fallthrough); case 17: __print_stage(); - fallthrough; + pattribute(fallthrough); case 15: __print_stage(); - fallthrough; + pattribute(fallthrough); case 13: __print_stage(); - fallthrough; + pattribute(fallthrough); case 11: __print_stage() __print_short_stage(); @@ -357,19 +357,19 @@ static int print_uint64(uint64_t n, char *p) switch (k) { case 20: __print_stage(); - fallthrough; + pattribute(fallthrough); case 18: __print_stage(); - fallthrough; + pattribute(fallthrough); case 16: __print_stage(); - fallthrough; + pattribute(fallthrough); case 14: __print_stage(); - fallthrough; + pattribute(fallthrough); case 12: __print_stage(); - fallthrough; + pattribute(fallthrough); case 10: __print_stage(); } From c6c2064ec1f1eb8e9734c7d3a1105fa6102eba9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Thu, 5 Aug 2021 08:28:21 +0200 Subject: [PATCH 048/106] Only expose attribute name if not already defined --- include/flatcc/portable/pattributes.h | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/include/flatcc/portable/pattributes.h b/include/flatcc/portable/pattributes.h index 7f1eb9ca2..30b3b23d3 100644 --- a/include/flatcc/portable/pattributes.h +++ b/include/flatcc/portable/pattributes.h @@ -57,21 +57,23 @@ extern "C" { /* https://en.cppreference.com/w/c/language/attributes/fallthrough */ -#ifndef fallthrough -# if PORTABLE_HAS_C_ATTRIBUTE(__fallthrough__) -# define pattribute_fallthrough [[__fallthrough__]] -# elif PORTABLE_HAS_ATTRIBUTE(__fallthrough__) -# define pattribute_fallthrough __attribute__((__fallthrough__)) -# else -# define pattribute_fallthrough ((void)0) -# endif +#if PORTABLE_HAS_C_ATTRIBUTE(__fallthrough__) +# define pattribute_fallthrough [[__fallthrough__]] +#elif PORTABLE_HAS_ATTRIBUTE(__fallthrough__) +# define pattribute_fallthrough __attribute__((__fallthrough__)) +#else +# define pattribute_fallthrough ((void)0) #endif #define pattribute(x) pattribute_##x #if PORTABLE_EXPOSE_ATTRIBUTES -#define fallthrough pattribute(fallthrough) + +#ifndef fallthrough +# define fallthrough pattribute(fallthrough) +#endif + #endif From 8f85608beade1313dedac19bdb68b57ab8e0c537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Sun, 8 Aug 2021 10:46:51 +0200 Subject: [PATCH 049/106] Remove misguided include guards --- include/flatcc/portable/pdiagnostic_pop.h | 5 ----- include/flatcc/portable/pdiagnostic_push.h | 5 ----- 2 files changed, 10 deletions(-) diff --git a/include/flatcc/portable/pdiagnostic_pop.h b/include/flatcc/portable/pdiagnostic_pop.h index eed26e670..f5e16b340 100644 --- a/include/flatcc/portable/pdiagnostic_pop.h +++ b/include/flatcc/portable/pdiagnostic_pop.h @@ -1,6 +1,3 @@ -#ifndef PDIAGNOSTIC_POP_H -#define PDIAGNOSTIC_POP_H - #if defined(PDIAGNOSTIC_PUSHED_MSVC) #if PDIAGNOSTIC_PUSHED_MSVC #pragma warning( pop ) @@ -21,5 +18,3 @@ #endif // PDIAGNOSTIC_PUSHED_GCC #undef PDIAGNOSTIC_PUSHED_GCC #endif // defined(PDIAGNOSTIC_PUSHED_GCC) - -#endif /* PDIAGNOSTIC_POP_H */ diff --git a/include/flatcc/portable/pdiagnostic_push.h b/include/flatcc/portable/pdiagnostic_push.h index 542f9b323..c9ede8a34 100644 --- a/include/flatcc/portable/pdiagnostic_push.h +++ b/include/flatcc/portable/pdiagnostic_push.h @@ -1,6 +1,3 @@ -#ifndef PDIAGNOSTIC_PUSH_H -#define PDIAGNOSTIC_PUSH_H - /* * See also comment in "pdiagnostic.h" * @@ -51,8 +48,6 @@ #define PDIAGNOSTIC_PUSHED_GCC 0 #endif // defined(__GNUC__) && !defined(__clang__) -#endif /* PDIAGNOSTIC_PUSH_H */ - /* * We cannot handle nested push, but we can add to the parent context * so keep this outside the header include guard. From 22664beeff03c0be0e6ca2109a93a49e2065ec8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Sun, 8 Aug 2021 10:47:19 +0200 Subject: [PATCH 050/106] Make functions inline to silence unused function warnings --- include/flatcc/portable/pbase64.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/include/flatcc/portable/pbase64.h b/include/flatcc/portable/pbase64.h index 7e2d6c300..a6812c4b1 100644 --- a/include/flatcc/portable/pbase64.h +++ b/include/flatcc/portable/pbase64.h @@ -24,7 +24,7 @@ extern "C" { /* Decoding ends at valid tail length but last byte has non-zero bits where it shouldn't have. */ #define BASE64_EDIRTY 5 -static const char *base64_strerror(int err); +static inline const char *base64_strerror(int err); /* All codecs are URL safe. Only Crockford allow for non-canocical decoding. */ enum { @@ -48,14 +48,14 @@ enum { }; /* Encoded size with or without padding. */ -static size_t base64_encoded_size(size_t len, int mode); +static inline size_t base64_encoded_size(size_t len, int mode); /* * Decoded size assuming no padding. * If `len` does include padding, the actual size may be less * when decoding, but never more. */ -static size_t base64_decoded_size(size_t len); +static inline size_t base64_decoded_size(size_t len); /* * `dst` must hold ceil(len * 4 / 3) bytes. @@ -76,7 +76,7 @@ static size_t base64_decoded_size(size_t len); * checksum must be separate from the main buffer and is not supported * by this library. */ -static int base64_encode(uint8_t *dst, const uint8_t *src, size_t *dst_len, size_t *src_len, int mode); +static inline int base64_encode(uint8_t *dst, const uint8_t *src, size_t *dst_len, size_t *src_len, int mode); /* * Decodes according to mode while ignoring encoding modifiers. @@ -96,9 +96,9 @@ static int base64_encode(uint8_t *dst, const uint8_t *src, size_t *dst_len, size * without output holding the last full block, if any. BASE64_ETAIL is also * returned if the a valid length holds non-zero unused tail bits. */ -static int base64_decode(uint8_t *dst, const uint8_t *src, size_t *dst_len, size_t *src_len, int mode); +static inline int base64_decode(uint8_t *dst, const uint8_t *src, size_t *dst_len, size_t *src_len, int mode); -static const char *base64_strerror(int err) +static inline const char *base64_strerror(int err) { switch (err) { case BASE64_EOK: return "ok"; @@ -111,7 +111,7 @@ static const char *base64_strerror(int err) } } -static size_t base64_encoded_size(size_t len, int mode) +static inline size_t base64_encoded_size(size_t len, int mode) { size_t k = len % 3; size_t n = (len * 4 / 3 + 3) & ~(size_t)3; @@ -132,7 +132,7 @@ static size_t base64_encoded_size(size_t len, int mode) return n; } -static size_t base64_decoded_size(size_t len) +static inline size_t base64_decoded_size(size_t len) { size_t k = len % 4; size_t n = len / 4 * 3; @@ -149,7 +149,7 @@ static size_t base64_decoded_size(size_t len) } } -static int base64_encode(uint8_t *dst, const uint8_t *src, size_t *dst_len, size_t *src_len, int mode) +static inline int base64_encode(uint8_t *dst, const uint8_t *src, size_t *dst_len, size_t *src_len, int mode) { const uint8_t *rfc4648_alphabet = (const uint8_t *) "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -227,7 +227,7 @@ static int base64_encode(uint8_t *dst, const uint8_t *src, size_t *dst_len, size return ret; } -static int base64_decode(uint8_t *dst, const uint8_t *src, size_t *dst_len, size_t *src_len, int mode) +static inline int base64_decode(uint8_t *dst, const uint8_t *src, size_t *dst_len, size_t *src_len, int mode) { static const uint8_t cinvalid = 64; static const uint8_t cignore = 65; From 1ab6748d12a058964702627b1d9f7eb4ca56a0ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Sun, 8 Aug 2021 10:47:34 +0200 Subject: [PATCH 051/106] Remove unused variable --- include/flatcc/support/cdump.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/flatcc/support/cdump.h b/include/flatcc/support/cdump.h index 005018995..b58936296 100644 --- a/include/flatcc/support/cdump.h +++ b/include/flatcc/support/cdump.h @@ -10,7 +10,6 @@ extern "C" { /* Generates a constant a C byte array. */ static void cdump(const char *name, void *addr, size_t len, FILE *fp) { unsigned int i; - unsigned char buff[17]; unsigned char *pc = (unsigned char*)addr; // Output description if given. From 3bb38ca996950719bcc46b1edf4004f2939d562c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Sun, 8 Aug 2021 10:47:58 +0200 Subject: [PATCH 052/106] Silence unused param warnings and remove unused variables --- test/monster_test/monster_test.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/monster_test/monster_test.c b/test/monster_test/monster_test.c index dbb8ed8c8..400415c5d 100644 --- a/test/monster_test/monster_test.c +++ b/test/monster_test/monster_test.c @@ -96,6 +96,8 @@ int verify_empty_monster(void *buffer) int test_enums(flatcc_builder_t *B) { + (void)B; + if (ns(neg_enum_neg1) != -12) { printf("neg_enum_neg1 should be -12, was %d\n", ns(neg_enum_neg1)); return -1; @@ -1686,7 +1688,6 @@ int verify_union_vector(void *buffer, size_t size) int color; ns(Monster_table_t) mon; - ns(Stat_table_t) stat; ns(TestSimpleTableWithEnum_table_t) kermit; flatbuffers_generic_vec_t anyvec; ns(Any_vec_t) anyvec_type; @@ -1991,7 +1992,6 @@ int test_recursive_sort(flatcc_builder_t *B) void *buffer = 0; size_t size = 0; - size_t n; int ret = -1; ns(Alt_table_t) alt; ns(Any_union_t) any; @@ -2064,7 +2064,6 @@ int test_mixed_type_union(flatcc_builder_t *B) { void *buffer; size_t size; - size_t n; int ret = -1; /* Builder */ nsf(Character_union_ref_t) ut; @@ -2511,6 +2510,8 @@ int test_nested_buffer_using_nest(flatcc_builder_t *B) int verify_include(void *buffer) { + (void)buffer; + if (MyGame_OtherNameSpace_FromInclude_Foo != 17) { printf("Unexpected enum value `Foo` from included schema\n"); return -1; From 09feb9e4bbc8b2d61d56f585e12c5a520d6bd2cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Sun, 8 Aug 2021 10:51:18 +0200 Subject: [PATCH 053/106] Update CHANGELOG --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76775d3e1..cf39d87ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,11 @@ - Fix larger integer literal types in JSON parser and printer (#194). - Add pattributes.h to portable library and replace GCC fallthrough comments with fallthough attribute to also silence clang warnings (#203). +- Remove misguided include guards from `portable/pdiagnostic_push/pop.h` and fix + related and expected warnings in other code. NOTE: End user code might be + affected because warnigs were disabled more broadly than intended. Also note + that warnings will still be disabled after pop if the compiler does not + support push/pop diagnostics (#205). ## [0.6.0] From a889e487609ec0f2b6aa9b6a920bc8129a8b547f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Sun, 8 Aug 2021 15:14:09 +0200 Subject: [PATCH 054/106] Remove obsolete comment --- include/flatcc/portable/pdiagnostic_push.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/flatcc/portable/pdiagnostic_push.h b/include/flatcc/portable/pdiagnostic_push.h index c9ede8a34..66586d721 100644 --- a/include/flatcc/portable/pdiagnostic_push.h +++ b/include/flatcc/portable/pdiagnostic_push.h @@ -48,8 +48,4 @@ #define PDIAGNOSTIC_PUSHED_GCC 0 #endif // defined(__GNUC__) && !defined(__clang__) -/* - * We cannot handle nested push, but we can add to the parent context - * so keep this outside the header include guard. - */ #include "pdiagnostic.h" From bca3b5fcd77c3e990fef75fae615b8f62f66af0e Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Mon, 1 Nov 2021 07:57:16 +0900 Subject: [PATCH 055/106] src/compiler/semantics.c: Fix a warning (#218) Fix zero init struct warning --- src/compiler/semantics.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/semantics.c b/src/compiler/semantics.c index a2866cf33..d1e277b6c 100644 --- a/src/compiler/semantics.c +++ b/src/compiler/semantics.c @@ -1545,7 +1545,7 @@ static int process_enum(fb_parser_t *P, fb_compound_type_t *ct) fb_symbol_t *sym, *old, *type_sym; fb_member_t *member; fb_metadata_t *knowns[KNOWN_ATTR_COUNT]; - fb_value_t index = { 0 }; + fb_value_t index = { { { 0 } }, 0, 0 }; fb_value_t old_index; int first = 1; int bit_flags = 0; From 38febbc9fe6a67c50788a759bf7b9909bb38c567 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Jourdheuil=20Sellin?= <46419549+Geneo-5@users.noreply.github.com> Date: Thu, 25 Nov 2021 01:20:04 +0100 Subject: [PATCH 056/106] Fix #221 Bad string lenght cause segmentation fault. (#222) If n = 0xFFFFFFFF then n + 1 = 0. end - base (unsigned value) is always greater then 0. Finally the function test then value (buf + base)[0xFFFFFFFF] whish crash. Co-authored-by: Geneo-5 <> --- src/runtime/verifier.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime/verifier.c b/src/runtime/verifier.c index 1831fcf6b..9c43bf613 100644 --- a/src/runtime/verifier.c +++ b/src/runtime/verifier.c @@ -265,7 +265,7 @@ static inline int verify_string(const void *buf, uoffset_t end, uoffset_t base, base += offset; n = read_uoffset(buf, base); base += offset_size; - verify(end - base >= n + 1, flatcc_verify_error_string_out_of_range); + verify(end - base > n, flatcc_verify_error_string_out_of_range); verify(((uint8_t *)buf + base)[n] == 0, flatcc_verify_error_string_not_zero_terminated); return flatcc_verify_ok; } From 5d2a31771924837f714778e364b18839ea335d38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Thu, 25 Nov 2021 01:23:17 +0100 Subject: [PATCH 057/106] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf39d87ce..eebf7efe9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,6 +60,7 @@ affected because warnigs were disabled more broadly than intended. Also note that warnings will still be disabled after pop if the compiler does not support push/pop diagnostics (#205). +- Fix verifier crash on malicious string length input (#221). ## [0.6.0] From 38e7a63a8f9eeda8cff02b5d39e5883685183d50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Fri, 26 Nov 2021 13:04:12 +0100 Subject: [PATCH 058/106] Fix incorrect space parsing on ill-formed JSON --- src/runtime/json_parser.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/runtime/json_parser.c b/src/runtime/json_parser.c index 313bd8085..0e3aeea98 100644 --- a/src/runtime/json_parser.c +++ b/src/runtime/json_parser.c @@ -259,7 +259,7 @@ static inline int decode_utf16_surrogate_pair(uint32_t high, uint32_t low, char } -/* +/* * UTF-8 code points can have up to 4 bytes but JSON can only * encode up to 3 bytes via the \uXXXX syntax. * To handle the range U+10000..U+10FFFF two UTF-16 surrogate @@ -329,7 +329,7 @@ const char *flatcc_json_parser_string_escape(flatcc_json_parser_t *ctx, const ch return flatcc_json_parser_set_error(ctx, buf, end, flatcc_json_parser_error_invalid_escape); }; /* If a high UTF-16 surrogate half pair was detected */ - if (u >= 0xd800 && u <= 0xdbff && + if (u >= 0xd800 && u <= 0xdbff && /* and there is space for a matching low half pair */ end - buf >= 12 && /* and there is a second escape following immediately */ @@ -344,7 +344,7 @@ const char *flatcc_json_parser_string_escape(flatcc_json_parser_t *ctx, const ch return flatcc_json_parser_set_error(ctx, buf, end, flatcc_json_parser_error_invalid_escape); } return buf + 12; - /* + /* * Otherwise decode unmatched surrogate pairs as is any * other UTF-8. Some systems might depend on these surviving. * Leave ignored errors for the next parse step. @@ -489,7 +489,7 @@ const char *flatcc_json_parser_match_constant(flatcc_json_parser_t *ctx, const c *more = 0; return flatcc_json_parser_set_error(ctx, buf, end, flatcc_json_parser_error_invalid_escape); case '\"': - buf = flatcc_json_parser_space(ctx, buf + 1, 0); + buf = flatcc_json_parser_space(ctx, buf + 1, end); *more = 0; return buf; } @@ -855,7 +855,7 @@ const char *flatcc_json_parser_char_array(flatcc_json_parser_t *ctx, if (k > n) { if (!(ctx->flags & flatcc_json_parser_f_skip_array_overflow)) { return flatcc_json_parser_set_error(ctx, buf, end, flatcc_json_parser_error_array_overflow); - } + } k = n; /* Might truncate UTF-8. */ } memcpy(s, mark, k); @@ -869,7 +869,7 @@ const char *flatcc_json_parser_char_array(flatcc_json_parser_t *ctx, if (k > n) { if (!(ctx->flags & flatcc_json_parser_f_skip_array_overflow)) { return flatcc_json_parser_set_error(ctx, buf, end, flatcc_json_parser_error_array_overflow); - } + } k = n; /* Might truncate UTF-8. */ } memcpy(s, mark, k); From 77c1e22941fb8b856693cfb3713366eaf1a39857 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Fri, 26 Nov 2021 13:35:42 +0100 Subject: [PATCH 059/106] Updatee CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index eebf7efe9..ed85e9ed7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,7 @@ that warnings will still be disabled after pop if the compiler does not support push/pop diagnostics (#205). - Fix verifier crash on malicious string length input (#221). +- Fix potential crash parsing unterminated JSON (#223). ## [0.6.0] From 5d87f22adcb33c109f8dea99e6137c8600f32d59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Fri, 26 Nov 2021 13:36:29 +0100 Subject: [PATCH 060/106] Allow 0 and other undefined values on enum bit_flags initializer --- src/compiler/semantics.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/compiler/semantics.c b/src/compiler/semantics.c index d1e277b6c..96d4b9403 100644 --- a/src/compiler/semantics.c +++ b/src/compiler/semantics.c @@ -1146,7 +1146,9 @@ static int process_table(fb_parser_t *P, fb_compound_type_t *ct) member->type.type = vt_invalid; continue; } - if (P->opts.strict_enum_init && !(member->flags & fb_fm_optional)) { + /* Bitflags can have complex combinations of values, and do not nativele have a 0 value. */ + if (P->opts.strict_enum_init && !(member->type.ct->metadata_flags & fb_f_bit_flags) + && !(member->flags & fb_fm_optional)) { if (!is_in_value_set(&member->type.ct->value_set, &member->value)) { error_sym(P, sym, "initializer does not match a defined enum value"); member->type.type = vt_invalid; @@ -1164,6 +1166,7 @@ static int process_table(fb_parser_t *P, fb_compound_type_t *ct) continue; } if (P->opts.strict_enum_init) { + /* TODO: consider if this error is necessary for bit_flags - flatc 2.0.0 errors on this. */ if (!is_in_value_set(&member->type.ct->value_set, &member->value)) { error_sym_2(P, sym, "enum type requires an explicit initializer because it has no 0 value", type_sym); From 07ae7dca8118f9ab6d900a7d4797881cab708ba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Fri, 26 Nov 2021 14:09:17 +0100 Subject: [PATCH 061/106] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed85e9ed7..feb13c78d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -62,6 +62,8 @@ support push/pop diagnostics (#205). - Fix verifier crash on malicious string length input (#221). - Fix potential crash parsing unterminated JSON (#223). +- Allow 0 (and other unknown values) as schema default value for enums with + `bit_flags` attribute. ## [0.6.0] From 18e74bde339d2aeb5493a34822841ebb5ac661ee Mon Sep 17 00:00:00 2001 From: Larry E Date: Tue, 29 Mar 2022 17:50:13 -0400 Subject: [PATCH 062/106] disable pedantic for GCC >= 8 (#228) Disable -pedantic flag for GCC >= 8 --- CMakeLists.txt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7a201691d..4c4351b05 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -179,7 +179,7 @@ if (CMAKE_C_COMPILER_ID MATCHES "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic -Wall -Wextra") # Fix broken C++ alignas - either will do set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") - #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPORTABLE_PATCH_CPLUSPLUS_STDALIGN") + #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPORTABLE_PATCH_CPLUSPLUS_STDALIGN") if (FLATCC_ALLOW_WERROR) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") endif() @@ -209,8 +209,9 @@ elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU") endif() else() message(STATUS "Setting GNU C compiler options with c11 and Posix") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -pedantic -Wall -Wextra") - if (NOT (GCC_VERSION VERSION_LESS 8.0)) + if (GCC_VERSION VERSION_LESS 8.0) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -pedantic -Wall -Wextra") + elseif (NOT (GCC_VERSION VERSION_LESS 8.0)) # Disable some GCC checks: # (warnings exist since 8.0, but are more aggressive in 9.0) # @@ -219,9 +220,11 @@ elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU") # structs, but these are valid as zero-paddded, not zero terminated. # # -Wno-format-overflow: - # GCC 9 warns on mistakenly assumed NULL string when + # GCC 9 warns on mistakenly assumed NULL string when # printing from a required FlatBuffer string field. # + message(STATUS "Disabling -pedantic for GCC >= 8.0") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -Wall -Wextra") message(STATUS "Disabling GNU C compiler warnings: -Wstringop-truncation -Wno-format-overflow") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-stringop-truncation -Wno-format-overflow") endif() From d90ed18ad09824297ffd5fbc578ccb1666d13890 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Tue, 29 Mar 2022 23:57:27 +0200 Subject: [PATCH 063/106] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index feb13c78d..64c276894 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,8 @@ - Fix potential crash parsing unterminated JSON (#223). - Allow 0 (and other unknown values) as schema default value for enums with `bit_flags` attribute. +- Disable -pedantic flag for GCC >= 8, it just keeps breaking perfectly valid + code (#227). ## [0.6.0] From ffc1df050928f18ace3d2e8a5d0fb5e588369f40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Thu, 21 Apr 2022 22:40:42 +0200 Subject: [PATCH 064/106] Add reference to flatc feature --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 78aa7e5d3..8d07cf128 100644 --- a/README.md +++ b/README.md @@ -1233,6 +1233,16 @@ For advanced debugging the [hexdump.h] file can be used to dump the buffer contents. It is used in [test_json.c] and also in [monster_test.c]. See also [FlatBuffers Binary Format]. +As of April 2022, Googles flatc tool has implemented an `--annotate` feature. +This provides an annotated hex dump given a binary buffer and a schema. The +output can be used to troubleshoot and rule out or confirm suspected encoding +bugs in the buffer at hand. The eclectic example in the [FlatBuffers Binary +Format] document contains a hand written annotated example which inspired the +`--annotate` feature, but it is not the exact same output format. Note also that +`flatc` generated buffers tend to have vtables before the table it is referenced +by, while flatcc normally packs all vtables at the end of the buffer for +better padding and cache efficiency. + ## File and Type Identifiers From 2f8d624b1090071c72bb98ea52924602c65c299d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Tue, 10 May 2022 16:10:55 +0200 Subject: [PATCH 065/106] Fix GCC 11 sign conversion warning --- src/compiler/semantics.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/semantics.c b/src/compiler/semantics.c index 96d4b9403..09b98d30e 100644 --- a/src/compiler/semantics.c +++ b/src/compiler/semantics.c @@ -617,7 +617,7 @@ static int analyze_struct(fb_parser_t *P, fb_compound_type_t *ct) } ct->symbol.flags |= fb_circular_closed; - ct->symbol.flags &= ~fb_circular_open; + ct->symbol.flags &= (uint16_t)~fb_circular_open; ct->order = P->schema.ordered_structs; P->schema.ordered_structs = ct; return ret; From 7c451ea4a97b672c05a81f210d6a6fffd5c0068f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Fri, 20 May 2022 14:18:23 +0200 Subject: [PATCH 066/106] Add link to flatc --annotate README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 8d07cf128..6f5f10db5 100644 --- a/README.md +++ b/README.md @@ -1243,6 +1243,8 @@ Format] document contains a hand written annotated example which inspired the by, while flatcc normally packs all vtables at the end of the buffer for better padding and cache efficiency. +See also [flatc --annotate]. + ## File and Type Identifiers @@ -2558,3 +2560,5 @@ See [Benchmarks] [hexdump.h]: https://github.com/dvidelabs/flatcc/blob/master/include/flatcc/support/hexdump.h [readfile.h]: include/flatcc/support/readfile.h [Security Considerations]: https://github.com/dvidelabs/flatcc/blob/master/doc/security.md +[flatc --annotate]: https://github.com/google/flatbuffers/tree/master/tests/annotated_binary + From d17e324e7e595272da486c5b9b20e848b78ba9ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Mon, 23 May 2022 10:18:53 +0200 Subject: [PATCH 067/106] Bump to version 0.6.1 --- CHANGELOG.md | 4 +- README.md | 19 +++++- include/flatcc/flatcc_version.h | 4 +- .../reflection/flatbuffers_common_builder.h | 2 +- .../reflection/flatbuffers_common_reader.h | 2 +- .../flatcc/reflection/reflection_builder.h | 4 +- include/flatcc/reflection/reflection_reader.h | 67 +++++++++++++------ .../flatcc/reflection/reflection_verifier.h | 2 +- src/compiler/codegen_schema.c | 7 +- 9 files changed, 76 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64c276894..ebf4ca510 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,9 @@ # Change Log -## [0.6.1-pre] +## [0.6.1] - Add `flatcc_builder_alloc` and `flatcc_builder_free` to handle situations - where stanard allocation has been redefined via macros so `free` is no longer + where standard allocation has been redefined via macros so `free` is no longer safe to use. These are similar to the existing `aligned_alloc/free` functions. - Fix a potential, but never seen, low level race condition in the builder when writing a union field because the builder might reallocate between type diff --git a/README.md b/README.md index 6f5f10db5..0b976b5cc 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ executable also handle optional json parsing or printing in less than 2 us for a * [Poll on Meson Build](#poll-on-meson-build) * [Reporting Bugs](#reporting-bugs) * [Status](#status) - * [Main features supported as of 0.6.0](#main-features-supported-as-of-060) + * [Main features supported as of 0.6.1](#main-features-supported-as-of-061) * [Supported platforms (CI tested)](#supported-platforms-ci-tested) * [Platforms reported to work by users](#platforms-reported-to-work-by-users) * [Portability](#portability) @@ -292,6 +292,20 @@ fi ## Status +Release 0.6.1 contains primarily bug fixes and numerous contributions +from the community to handle platform edge cases. Additionally, +pendantic GCC warnings are disabled, relying instead on clang, since GCC +is too aggressive, breaks builds frequently and works against +portability. An existing C++ test case ensures that C code also works +with common C++ compilers, but it can break some environments, so there +is now a flag to disable that test without disabling all tests. Support +for Optional Scalar Values in the FlatBuffer format has been added. +There is also improved support for abstracting memory allocation on +various platforms. `
_identifier` has been deprecated in favor +`
_file_identifier` in generated code due to `identifier` easily +leading to name conflicts. `file_extension` constant in generated code +is now without prefixed dot (.). + Release 0.6.0 introduces a "primary" attribute to be used together with a key attribute to chose default key for finding and sorting. If primary is absent, the key with the lowest id becomes primary. Tables and @@ -339,7 +353,7 @@ low-level union interface so the terms { type, value } are used consistently over { type, member } and { types, members }. -### Main features supported as of 0.6.0 +### Main features supported as of 0.6.1 - generated FlatBuffers reader and builder headers for C - generated FlatBuffers verifier headers for C @@ -364,6 +378,7 @@ consistently over { type, member } and { types, members }. - base64(url) encoded binary data in JSON. - sort fields by primary key (as of 0.6.0) - char arrays (as of 0.6.0) +- optional scalar values (as of 0.6.1) There are no plans to make frequent updates once the project becomes stable, but input from the community will always be welcome and included diff --git a/include/flatcc/flatcc_version.h b/include/flatcc/flatcc_version.h index 87158986b..0e677d1c1 100644 --- a/include/flatcc/flatcc_version.h +++ b/include/flatcc/flatcc_version.h @@ -2,12 +2,12 @@ extern "C" { #endif -#define FLATCC_VERSION_TEXT "0.6.1-dev" +#define FLATCC_VERSION_TEXT "0.6.1" #define FLATCC_VERSION_MAJOR 0 #define FLATCC_VERSION_MINOR 6 #define FLATCC_VERSION_PATCH 1 /* 1 or 0 */ -#define FLATCC_VERSION_RELEASED 0 +#define FLATCC_VERSION_RELEASED 1 #ifdef __cplusplus } diff --git a/include/flatcc/reflection/flatbuffers_common_builder.h b/include/flatcc/reflection/flatbuffers_common_builder.h index b5ce8a5ce..a4be1ce6e 100644 --- a/include/flatcc/reflection/flatbuffers_common_builder.h +++ b/include/flatcc/reflection/flatbuffers_common_builder.h @@ -1,7 +1,7 @@ #ifndef FLATBUFFERS_COMMON_BUILDER_H #define FLATBUFFERS_COMMON_BUILDER_H -/* Generated by flatcc 0.6.1-dev FlatBuffers schema compiler for C by dvide.com */ +/* Generated by flatcc 0.6.1 FlatBuffers schema compiler for C by dvide.com */ /* Common FlatBuffers build functionality for C. */ diff --git a/include/flatcc/reflection/flatbuffers_common_reader.h b/include/flatcc/reflection/flatbuffers_common_reader.h index 67971e9af..c57530868 100644 --- a/include/flatcc/reflection/flatbuffers_common_reader.h +++ b/include/flatcc/reflection/flatbuffers_common_reader.h @@ -1,7 +1,7 @@ #ifndef FLATBUFFERS_COMMON_READER_H #define FLATBUFFERS_COMMON_READER_H -/* Generated by flatcc 0.6.1-dev FlatBuffers schema compiler for C by dvide.com */ +/* Generated by flatcc 0.6.1 FlatBuffers schema compiler for C by dvide.com */ /* Common FlatBuffers read functionality for C. */ diff --git a/include/flatcc/reflection/reflection_builder.h b/include/flatcc/reflection/reflection_builder.h index 4b05199ee..65aef73e5 100644 --- a/include/flatcc/reflection/reflection_builder.h +++ b/include/flatcc/reflection/reflection_builder.h @@ -1,7 +1,7 @@ #ifndef REFLECTION_BUILDER_H #define REFLECTION_BUILDER_H -/* Generated by flatcc 0.6.1-dev FlatBuffers schema compiler for C by dvide.com */ +/* Generated by flatcc 0.6.1 FlatBuffers schema compiler for C by dvide.com */ #ifndef REFLECTION_READER_H #include "reflection_reader.h" @@ -13,7 +13,7 @@ #undef flatbuffers_identifier #define flatbuffers_identifier "BFBS" #undef flatbuffers_extension -#define flatbuffers_extension ".bfbs" +#define flatbuffers_extension "bfbs" #define __reflection_BaseType_formal_args , reflection_BaseType_enum_t v0 #define __reflection_BaseType_call_args , v0 diff --git a/include/flatcc/reflection/reflection_reader.h b/include/flatcc/reflection/reflection_reader.h index 06b1dfb46..bf6a0e946 100644 --- a/include/flatcc/reflection/reflection_reader.h +++ b/include/flatcc/reflection/reflection_reader.h @@ -1,7 +1,7 @@ #ifndef REFLECTION_READER_H #define REFLECTION_READER_H -/* Generated by flatcc 0.6.1-dev FlatBuffers schema compiler for C by dvide.com */ +/* Generated by flatcc 0.6.1 FlatBuffers schema compiler for C by dvide.com */ #ifndef FLATBUFFERS_COMMON_READER_H #include "flatbuffers_common_reader.h" @@ -14,7 +14,7 @@ #undef flatbuffers_identifier #define flatbuffers_identifier "BFBS" #undef flatbuffers_extension -#define flatbuffers_extension ".bfbs" +#define flatbuffers_extension "bfbs" typedef const struct reflection_Type_table *reflection_Type_table_t; @@ -54,86 +54,113 @@ typedef struct reflection_Schema_table *reflection_Schema_mutable_table_t; typedef const flatbuffers_uoffset_t *reflection_Schema_vec_t; typedef flatbuffers_uoffset_t *reflection_Schema_mutable_vec_t; #ifndef reflection_Type_file_identifier -#define reflection_Type_file_identifier flatbuffers_identifier +#define reflection_Type_file_identifier "BFBS" #endif /* deprecated, use reflection_Type_file_identifier */ #ifndef reflection_Type_identifier -#define reflection_Type_identifier flatbuffers_identifier +#define reflection_Type_identifier "BFBS" #endif #define reflection_Type_type_hash ((flatbuffers_thash_t)0x44c8fe5e) #define reflection_Type_type_identifier "\x5e\xfe\xc8\x44" +#ifndef reflection_Type_file_extension +#define reflection_Type_file_extension "bfbs" +#endif #ifndef reflection_KeyValue_file_identifier -#define reflection_KeyValue_file_identifier flatbuffers_identifier +#define reflection_KeyValue_file_identifier "BFBS" #endif /* deprecated, use reflection_KeyValue_file_identifier */ #ifndef reflection_KeyValue_identifier -#define reflection_KeyValue_identifier flatbuffers_identifier +#define reflection_KeyValue_identifier "BFBS" #endif #define reflection_KeyValue_type_hash ((flatbuffers_thash_t)0x8c761eaa) #define reflection_KeyValue_type_identifier "\xaa\x1e\x76\x8c" +#ifndef reflection_KeyValue_file_extension +#define reflection_KeyValue_file_extension "bfbs" +#endif #ifndef reflection_EnumVal_file_identifier -#define reflection_EnumVal_file_identifier flatbuffers_identifier +#define reflection_EnumVal_file_identifier "BFBS" #endif /* deprecated, use reflection_EnumVal_file_identifier */ #ifndef reflection_EnumVal_identifier -#define reflection_EnumVal_identifier flatbuffers_identifier +#define reflection_EnumVal_identifier "BFBS" #endif #define reflection_EnumVal_type_hash ((flatbuffers_thash_t)0x9531c946) #define reflection_EnumVal_type_identifier "\x46\xc9\x31\x95" +#ifndef reflection_EnumVal_file_extension +#define reflection_EnumVal_file_extension "bfbs" +#endif #ifndef reflection_Enum_file_identifier -#define reflection_Enum_file_identifier flatbuffers_identifier +#define reflection_Enum_file_identifier "BFBS" #endif /* deprecated, use reflection_Enum_file_identifier */ #ifndef reflection_Enum_identifier -#define reflection_Enum_identifier flatbuffers_identifier +#define reflection_Enum_identifier "BFBS" #endif #define reflection_Enum_type_hash ((flatbuffers_thash_t)0xacffa90f) #define reflection_Enum_type_identifier "\x0f\xa9\xff\xac" +#ifndef reflection_Enum_file_extension +#define reflection_Enum_file_extension "bfbs" +#endif #ifndef reflection_Field_file_identifier -#define reflection_Field_file_identifier flatbuffers_identifier +#define reflection_Field_file_identifier "BFBS" #endif /* deprecated, use reflection_Field_file_identifier */ #ifndef reflection_Field_identifier -#define reflection_Field_identifier flatbuffers_identifier +#define reflection_Field_identifier "BFBS" #endif #define reflection_Field_type_hash ((flatbuffers_thash_t)0x9f7e408a) #define reflection_Field_type_identifier "\x8a\x40\x7e\x9f" +#ifndef reflection_Field_file_extension +#define reflection_Field_file_extension "bfbs" +#endif #ifndef reflection_Object_file_identifier -#define reflection_Object_file_identifier flatbuffers_identifier +#define reflection_Object_file_identifier "BFBS" #endif /* deprecated, use reflection_Object_file_identifier */ #ifndef reflection_Object_identifier -#define reflection_Object_identifier flatbuffers_identifier +#define reflection_Object_identifier "BFBS" #endif #define reflection_Object_type_hash ((flatbuffers_thash_t)0xb09729bd) #define reflection_Object_type_identifier "\xbd\x29\x97\xb0" +#ifndef reflection_Object_file_extension +#define reflection_Object_file_extension "bfbs" +#endif #ifndef reflection_RPCCall_file_identifier -#define reflection_RPCCall_file_identifier flatbuffers_identifier +#define reflection_RPCCall_file_identifier "BFBS" #endif /* deprecated, use reflection_RPCCall_file_identifier */ #ifndef reflection_RPCCall_identifier -#define reflection_RPCCall_identifier flatbuffers_identifier +#define reflection_RPCCall_identifier "BFBS" #endif #define reflection_RPCCall_type_hash ((flatbuffers_thash_t)0xe2d586f1) #define reflection_RPCCall_type_identifier "\xf1\x86\xd5\xe2" +#ifndef reflection_RPCCall_file_extension +#define reflection_RPCCall_file_extension "bfbs" +#endif #ifndef reflection_Service_file_identifier -#define reflection_Service_file_identifier flatbuffers_identifier +#define reflection_Service_file_identifier "BFBS" #endif /* deprecated, use reflection_Service_file_identifier */ #ifndef reflection_Service_identifier -#define reflection_Service_identifier flatbuffers_identifier +#define reflection_Service_identifier "BFBS" #endif #define reflection_Service_type_hash ((flatbuffers_thash_t)0xf31a13b5) #define reflection_Service_type_identifier "\xb5\x13\x1a\xf3" +#ifndef reflection_Service_file_extension +#define reflection_Service_file_extension "bfbs" +#endif #ifndef reflection_Schema_file_identifier -#define reflection_Schema_file_identifier flatbuffers_identifier +#define reflection_Schema_file_identifier "BFBS" #endif /* deprecated, use reflection_Schema_file_identifier */ #ifndef reflection_Schema_identifier -#define reflection_Schema_identifier flatbuffers_identifier +#define reflection_Schema_identifier "BFBS" #endif #define reflection_Schema_type_hash ((flatbuffers_thash_t)0xfaf93779) #define reflection_Schema_type_identifier "\x79\x37\xf9\xfa" +#ifndef reflection_Schema_file_extension +#define reflection_Schema_file_extension "bfbs" +#endif typedef int8_t reflection_BaseType_enum_t; __flatbuffers_define_integer_type(reflection_BaseType, reflection_BaseType_enum_t, 8) diff --git a/include/flatcc/reflection/reflection_verifier.h b/include/flatcc/reflection/reflection_verifier.h index 7d04f34df..5b5bd374a 100644 --- a/include/flatcc/reflection/reflection_verifier.h +++ b/include/flatcc/reflection/reflection_verifier.h @@ -1,7 +1,7 @@ #ifndef REFLECTION_VERIFIER_H #define REFLECTION_VERIFIER_H -/* Generated by flatcc 0.6.1-dev FlatBuffers schema compiler for C by dvide.com */ +/* Generated by flatcc 0.6.1 FlatBuffers schema compiler for C by dvide.com */ #ifndef REFLECTION_READER_H #include "reflection_reader.h" diff --git a/src/compiler/codegen_schema.c b/src/compiler/codegen_schema.c index 0313d9ef8..d0c9fde3c 100644 --- a/src/compiler/codegen_schema.c +++ b/src/compiler/codegen_schema.c @@ -465,17 +465,15 @@ static void sort_objects(void *buffer) static FILE *open_file(fb_options_t *opts, fb_schema_t *S) { FILE *fp = 0; - char *path; + char *path = 0, *ext = 0; const char *prefix = opts->outpath ? opts->outpath : ""; size_t len, prefix_len = strlen(prefix); const char *name; - const char *ext; name = S->basename; len = strlen(name); - ext = flatbuffers_extension; - + ext = fb_create_path_ext(".", flatbuffers_extension); /* We generally should not use cgen options here, but in this case it makes sense. */ if (opts->gen_stdout) { return stdout; @@ -486,6 +484,7 @@ static FILE *open_file(fb_options_t *opts, fb_schema_t *S) fprintf(stderr, "error opening file for writing binary schema: %s\n", path); } free(path); + free(ext); return fp; } From 5774e6361d0241f021c715262a53c0cc8f3b91b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Mon, 23 May 2022 12:33:22 +0200 Subject: [PATCH 068/106] Bump to prerelease --- CHANGELOG.md | 3 +++ include/flatcc/flatcc_version.h | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ebf4ca510..9f32ae441 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Change Log +## [0.6.2-pre] + + ## [0.6.1] - Add `flatcc_builder_alloc` and `flatcc_builder_free` to handle situations diff --git a/include/flatcc/flatcc_version.h b/include/flatcc/flatcc_version.h index 0e677d1c1..78bc9c8d3 100644 --- a/include/flatcc/flatcc_version.h +++ b/include/flatcc/flatcc_version.h @@ -2,12 +2,12 @@ extern "C" { #endif -#define FLATCC_VERSION_TEXT "0.6.1" +#define FLATCC_VERSION_TEXT "0.6.2" #define FLATCC_VERSION_MAJOR 0 #define FLATCC_VERSION_MINOR 6 -#define FLATCC_VERSION_PATCH 1 +#define FLATCC_VERSION_PATCH 2 /* 1 or 0 */ -#define FLATCC_VERSION_RELEASED 1 +#define FLATCC_VERSION_RELEASED 0 #ifdef __cplusplus } From 5ff2e604a3e5a44d3885ff6887890c689b0a6b59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Tue, 7 Jun 2022 09:12:43 +0200 Subject: [PATCH 069/106] Avoid assuming location of build dir during CMake configuration --- CHANGELOG.md | 2 ++ CMakeLists.txt | 4 ---- scripts/test.sh | 4 ---- test/test.sh | 15 ++++++--------- 4 files changed, 8 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f32ae441..3ede11234 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [0.6.2-pre] +- CMake: avoid assuming location of build dir during configuration. + ## [0.6.1] diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c4351b05..096d13ff1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -134,12 +134,8 @@ endif() if (FLATCC_REFLECTION) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFLATCC_REFLECTION=1") - file(WRITE ${PROJECT_SOURCE_DIR}/build/reflection_enabled "REFLECTION=1") - file(REMOVE ${PROJECT_SOURCE_DIR}/build/reflection_disabled) else() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFLATCC_REFLECTION=0") - file(REMOVE ${PROJECT_SOURCE_DIR}/build/reflection_enabled) - file(WRITE ${PROJECT_SOURCE_DIR}/build/reflection_disabled "REFLECTION=0") endif() diff --git a/scripts/test.sh b/scripts/test.sh index 0728e1660..d87924b9e 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -36,7 +36,3 @@ else echo "DEBUG TEST PASSED" fi -if [ ! -e ${ROOT}/build/reflection_enabled ]; then - echo "(reflection disabled, skipping affected test and example)" -fi - diff --git a/test/test.sh b/test/test.sh index 40dc31699..d4fae6fc9 100755 --- a/test/test.sh +++ b/test/test.sh @@ -83,13 +83,13 @@ $CC -O3 -DNDEBUG -DFLATBUFFERS_BENCHMARK -I ${ROOT}/include monster_test.c \ echo "running optimized version of main monster test" ./monster_test -if [ -e ${ROOT}/build/reflection_enabled ]; then - echo "running reflection test" - ${ROOT}/test/reflection_test//reflection_test.sh +# This may fail if reflection feature is disabled +echo "running reflection test" +${ROOT}/test/reflection_test/reflection_test.sh - echo "running reflection sample" - ${ROOT}/samples/reflection/build.sh -fi +# This may fail if reflection feature is disabled +echo "running reflection sample" +${ROOT}/samples/reflection/build.sh echo "running monster sample" ${ROOT}/samples/monster/build.sh @@ -101,6 +101,3 @@ echo "running load test with large buffer" ${ROOT}/test/load_test/load_test.sh echo "TEST PASSED" -if [ ! -e ${ROOT}/build/reflection_enabled ]; then - echo "(reflection disabled, skipping affected test and example)" -fi From ccf393c41ce427a4c8bfab6f20b6100a466620aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?= Date: Thu, 13 Oct 2022 13:02:37 +0200 Subject: [PATCH 070/106] Use an unsigned type for the JSON printer flags Replace the enum flag in `flatcc_json_printer_set_flags()` with an unsigned integer type. In C enums are signed and bitwise operations on signed integer types may lead to undefined or implementation defined behavior. --- include/flatcc/flatcc_json_printer.h | 17 ++++++++--------- test/json_test/test_json.c | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/include/flatcc/flatcc_json_printer.h b/include/flatcc/flatcc_json_printer.h index 0ce49c146..cab49a1a4 100644 --- a/include/flatcc/flatcc_json_printer.h +++ b/include/flatcc/flatcc_json_printer.h @@ -243,14 +243,13 @@ static inline void flatcc_json_printer_set_nonstrict(flatcc_json_printer_t *ctx) flatcc_json_printer_set_noenum(ctx, 0); } -enum flatcc_json_printer_flags { - flatcc_json_printer_f_unquote = 1, - flatcc_json_printer_f_noenum = 2, - flatcc_json_printer_f_skip_default = 4, - flatcc_json_printer_f_force_default = 8, - flatcc_json_printer_f_pretty = 16, - flatcc_json_printer_f_nonstrict = 32, -}; +typedef uint32_t flatcc_json_printer_flags_t; +static const flatcc_json_printer_flags_t flatcc_json_printer_f_unquote = 1; +static const flatcc_json_printer_flags_t flatcc_json_printer_f_noenum = 2; +static const flatcc_json_printer_flags_t flatcc_json_printer_f_skip_default = 4; +static const flatcc_json_printer_flags_t flatcc_json_printer_f_force_default = 8; +static const flatcc_json_printer_flags_t flatcc_json_printer_f_pretty = 16; +static const flatcc_json_printer_flags_t flatcc_json_printer_f_nonstrict = 32; /* * May be called instead of setting operational modes individually. @@ -268,7 +267,7 @@ enum flatcc_json_printer_flags { * `pretty` flag sets indentation to 2. * `nonstrict` implies: `noenum`, `unquote`, `pretty`. */ -static inline void flatcc_json_printer_set_flags(flatcc_json_printer_t *ctx, int flags) +static inline void flatcc_json_printer_set_flags(flatcc_json_printer_t *ctx, flatcc_json_printer_flags_t flags) { ctx->unquote = !!(flags & flatcc_json_printer_f_unquote); ctx->noenum = !!(flags & flatcc_json_printer_f_noenum); diff --git a/test/json_test/test_json.c b/test/json_test/test_json.c index 6d6698b80..4edc7483d 100644 --- a/test/json_test/test_json.c +++ b/test/json_test/test_json.c @@ -47,7 +47,7 @@ static const struct test_scope Movie = { int test_json(const struct test_scope *scope, char *json, char *expect, int expect_err, - int parse_flags, int print_flags, int line) + int parse_flags, flatcc_json_printer_flags_t print_flags, int line) { int ret = -1; int err; From 6e864877b509d308ef40b81a7d4e643c0a748c27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?= Date: Tue, 18 Oct 2022 15:51:37 +0200 Subject: [PATCH 071/106] Use an unsigned type for the JSON parser flags --- include/flatcc/flatcc_json_parser.h | 23 +++++++++++------------ src/compiler/codegen_c_json_parser.c | 8 ++++---- src/runtime/json_parser.c | 4 ++-- test/json_test/test_json.c | 2 +- test/json_test/test_json_parser.c | 2 +- 5 files changed, 19 insertions(+), 20 deletions(-) diff --git a/include/flatcc/flatcc_json_parser.h b/include/flatcc/flatcc_json_parser.h index 1907fc7fc..d86190d79 100644 --- a/include/flatcc/flatcc_json_parser.h +++ b/include/flatcc/flatcc_json_parser.h @@ -22,13 +22,12 @@ extern "C" { #define PDIAGNOSTIC_IGNORE_UNUSED #include "flatcc/portable/pdiagnostic_push.h" -enum flatcc_json_parser_flags { - flatcc_json_parser_f_skip_unknown = 1, - flatcc_json_parser_f_force_add = 2, - flatcc_json_parser_f_with_size = 4, - flatcc_json_parser_f_skip_array_overflow = 8, - flatcc_json_parser_f_reject_array_underflow = 16 -}; +typedef uint32_t flatcc_json_parser_flags_t; +static const flatcc_json_parser_flags_t flatcc_json_parser_f_skip_unknown = 1; +static const flatcc_json_parser_flags_t flatcc_json_parser_f_force_add = 2; +static const flatcc_json_parser_flags_t flatcc_json_parser_f_with_size = 4; +static const flatcc_json_parser_flags_t flatcc_json_parser_f_skip_array_overflow = 8; +static const flatcc_json_parser_flags_t flatcc_json_parser_f_reject_array_underflow = 16; #define FLATCC_JSON_PARSE_ERROR_MAP(XX) \ XX(ok, "ok") \ @@ -92,7 +91,7 @@ typedef struct flatcc_json_parser_ctx flatcc_json_parser_t; struct flatcc_json_parser_ctx { flatcc_builder_t *ctx; const char *line_start; - int flags; + flatcc_json_parser_flags_t flags; #if FLATCC_JSON_PARSE_ALLOW_UNQUOTED int unquoted; #endif @@ -111,7 +110,7 @@ static inline int flatcc_json_parser_get_error(flatcc_json_parser_t *ctx) return ctx->error; } -static inline void flatcc_json_parser_init(flatcc_json_parser_t *ctx, flatcc_builder_t *B, const char *buf, const char *end, int flags) +static inline void flatcc_json_parser_init(flatcc_json_parser_t *ctx, flatcc_builder_t *B, const char *buf, const char *end, flatcc_json_parser_flags_t flags) { memset(ctx, 0, sizeof(*ctx)); ctx->ctx = B; @@ -872,10 +871,10 @@ const char *flatcc_json_parser_union_type_vector(flatcc_json_parser_t *ctx, * `buf`, `bufsiz` may be larger than the parsed json if trailing * space or zeroes are expected, but they must represent a valid memory buffer. * `fid` must be null, or a valid file identifier. - * `flags` default to 0. See also `flatcc_json_parser_flags`. + * `flags` default to 0. See also `flatcc_json_parser_f_` constants. */ int flatcc_json_parser_table_as_root(flatcc_builder_t *B, flatcc_json_parser_t *ctx, - const char *buf, size_t bufsiz, int flags, const char *fid, + const char *buf, size_t bufsiz, flatcc_json_parser_flags_t flags, const char *fid, flatcc_json_parser_table_f *parser); /* @@ -883,7 +882,7 @@ int flatcc_json_parser_table_as_root(flatcc_builder_t *B, flatcc_json_parser_t * * root. */ int flatcc_json_parser_struct_as_root(flatcc_builder_t *B, flatcc_json_parser_t *ctx, - const char *buf, size_t bufsiz, int flags, const char *fid, + const char *buf, size_t bufsiz, flatcc_json_parser_flags_t flags, const char *fid, flatcc_json_parser_struct_f *parser); #include "flatcc/portable/pdiagnostic_pop.h" diff --git a/src/compiler/codegen_c_json_parser.c b/src/compiler/codegen_c_json_parser.c index 29ebc85dd..0e2aa250c 100644 --- a/src/compiler/codegen_c_json_parser.c +++ b/src/compiler/codegen_c_json_parser.c @@ -1424,7 +1424,7 @@ static int gen_struct_parser(fb_output_t *out, fb_compound_type_t *ct) println(out, "return flatcc_json_parser_set_error(ctx, buf, end, flatcc_json_parser_error_runtime);"); unindent(); println(out, "}"); println(out, ""); - println(out, "static inline int %s_parse_json_as_root(flatcc_builder_t *B, flatcc_json_parser_t *ctx, const char *buf, size_t bufsiz, int flags, const char *fid)", snt.text); + println(out, "static inline int %s_parse_json_as_root(flatcc_builder_t *B, flatcc_json_parser_t *ctx, const char *buf, size_t bufsiz, flatcc_json_parser_flags_t flags, const char *fid)", snt.text); println(out, "{"); indent(); println(out, "return flatcc_json_parser_struct_as_root(B, ctx, buf, bufsiz, flags, fid, %s_parse_json_struct);", snt.text); @@ -1527,7 +1527,7 @@ static int gen_table_parser(fb_output_t *out, fb_compound_type_t *ct) println(out, "return flatcc_json_parser_set_error(ctx, buf, end, flatcc_json_parser_error_runtime);"); unindent(); println(out, "}"); println(out, ""); - println(out, "static inline int %s_parse_json_as_root(flatcc_builder_t *B, flatcc_json_parser_t *ctx, const char *buf, size_t bufsiz, int flags, const char *fid)", snt.text); + println(out, "static inline int %s_parse_json_as_root(flatcc_builder_t *B, flatcc_json_parser_t *ctx, const char *buf, size_t bufsiz, flatcc_json_parser_flags_t flags, const char *fid)", snt.text); println(out, "{"); indent(); println(out, "return flatcc_json_parser_table_as_root(B, ctx, buf, bufsiz, flags, fid, %s_parse_json_table);", snt.text); @@ -1661,7 +1661,7 @@ static int gen_root_table_parser(fb_output_t *out, fb_compound_type_t *ct) println(out, "static int %s_parse_json(flatcc_builder_t *B, flatcc_json_parser_t *ctx,", out->S->basename); indent(); indent(); - println(out, "const char *buf, size_t bufsiz, int flags)"); + println(out, "const char *buf, size_t bufsiz, flatcc_json_parser_flags_t flags)"); unindent(); unindent(); println(out, "{"); indent(); println(out, "flatcc_json_parser_t parser;"); @@ -1767,7 +1767,7 @@ static int gen_json_parser_prototypes(fb_output_t *out) println(out, "static int %s_parse_json(flatcc_builder_t *B, flatcc_json_parser_t *ctx,", out->S->basename); indent(); indent(); - println(out, "const char *buf, size_t bufsiz, int flags);"); + println(out, "const char *buf, size_t bufsiz, flatcc_json_parser_flags_t flags);"); unindent(); unindent(); println(out, ""); fallthrough; diff --git a/src/runtime/json_parser.c b/src/runtime/json_parser.c index 0e3aeea98..3f8b70598 100644 --- a/src/runtime/json_parser.c +++ b/src/runtime/json_parser.c @@ -1258,7 +1258,7 @@ const char *flatcc_json_parser_union_type_vector(flatcc_json_parser_t *ctx, } int flatcc_json_parser_table_as_root(flatcc_builder_t *B, flatcc_json_parser_t *ctx, - const char *buf, size_t bufsiz, int flags, const char *fid, + const char *buf, size_t bufsiz, flatcc_json_parser_flags_t flags, const char *fid, flatcc_json_parser_table_f *parser) { flatcc_json_parser_t _ctx; @@ -1278,7 +1278,7 @@ int flatcc_json_parser_table_as_root(flatcc_builder_t *B, flatcc_json_parser_t * } int flatcc_json_parser_struct_as_root(flatcc_builder_t *B, flatcc_json_parser_t *ctx, - const char *buf, size_t bufsiz, int flags, const char *fid, + const char *buf, size_t bufsiz, flatcc_json_parser_flags_t flags, const char *fid, flatcc_json_parser_table_f *parser) { flatcc_json_parser_t _ctx; diff --git a/test/json_test/test_json.c b/test/json_test/test_json.c index 4edc7483d..1a317ea17 100644 --- a/test/json_test/test_json.c +++ b/test/json_test/test_json.c @@ -47,7 +47,7 @@ static const struct test_scope Movie = { int test_json(const struct test_scope *scope, char *json, char *expect, int expect_err, - int parse_flags, flatcc_json_printer_flags_t print_flags, int line) + flatcc_json_parser_flags_t parse_flags, flatcc_json_printer_flags_t print_flags, int line) { int ret = -1; int err; diff --git a/test/json_test/test_json_parser.c b/test/json_test/test_json_parser.c index de2b738b2..a985cfab5 100644 --- a/test/json_test/test_json_parser.c +++ b/test/json_test/test_json_parser.c @@ -80,7 +80,7 @@ int test_parse(void) flatcc_builder_t builder; flatcc_builder_t *B = &builder; int ret = -1; - int flags = 0; + flatcc_json_parser_flags_t flags = 0; flatcc_builder_init(B); From 49d50e2107e9e05075c9aeac9e47f505c13c73c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?= Date: Tue, 18 Oct 2022 17:18:57 +0200 Subject: [PATCH 072/106] Use an unsigned type for the buffer flags --- include/flatcc/flatcc_builder.h | 17 ++++++++++------- src/runtime/builder.c | 12 ++++++------ src/runtime/json_parser.c | 4 ++-- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/include/flatcc/flatcc_builder.h b/include/flatcc/flatcc_builder.h index 3871b1d07..2e84d2979 100644 --- a/include/flatcc/flatcc_builder.h +++ b/include/flatcc/flatcc_builder.h @@ -710,10 +710,13 @@ static inline void flatcc_builder_refmap_reset(flatcc_builder_t *B) } -enum flatcc_builder_buffer_flags { - flatcc_builder_is_nested = 1, - flatcc_builder_with_size = 2, -}; +typedef uint16_t flatcc_builder_buffer_flags_t; +static const flatcc_builder_buffer_flags_t flatcc_builder_is_nested = 1; +static const flatcc_builder_buffer_flags_t flatcc_builder_with_size = 2; + +/* The flag size in the API needs to match the internal size. */ +static_assert(sizeof(flatcc_builder_buffer_flags_t) == + sizeof(((flatcc_builder_t *)0)->buffer_flags), "flag size mismatch"); /** * An alternative to start buffer, start struct/table ... end buffer. @@ -776,7 +779,7 @@ enum flatcc_builder_buffer_flags { flatcc_builder_ref_t flatcc_builder_create_buffer(flatcc_builder_t *B, const char identifier[FLATBUFFERS_IDENTIFIER_SIZE], uint16_t block_align, - flatcc_builder_ref_t ref, uint16_t align, int flags); + flatcc_builder_ref_t ref, uint16_t align, flatcc_builder_buffer_flags_t flags); /** * Creates a struct within the current buffer without using any @@ -867,7 +870,7 @@ flatcc_builder_ref_t flatcc_builder_end_struct(flatcc_builder_t *B); */ int flatcc_builder_start_buffer(flatcc_builder_t *B, const char identifier[FLATBUFFERS_IDENTIFIER_SIZE], - uint16_t block_align, int flags); + uint16_t block_align, flatcc_builder_buffer_flags_t flags); /** * The root object should be a struct or a table to conform to the @@ -923,7 +926,7 @@ flatcc_builder_ref_t flatcc_builder_end_buffer(flatcc_builder_t *B, flatcc_build */ flatcc_builder_ref_t flatcc_builder_embed_buffer(flatcc_builder_t *B, uint16_t block_align, - const void *data, size_t size, uint16_t align, int flags); + const void *data, size_t size, uint16_t align, flatcc_builder_buffer_flags_t flags); /** * Applies to the innermost open buffer. The identifier may be null or diff --git a/src/runtime/builder.c b/src/runtime/builder.c index 9f54d884f..b62c2b667 100644 --- a/src/runtime/builder.c +++ b/src/runtime/builder.c @@ -723,11 +723,11 @@ static int align_to_block(flatcc_builder_t *B, uint16_t *align, uint16_t block_a flatcc_builder_ref_t flatcc_builder_embed_buffer(flatcc_builder_t *B, uint16_t block_align, - const void *data, size_t size, uint16_t align, int flags) + const void *data, size_t size, uint16_t align, flatcc_builder_buffer_flags_t flags) { uoffset_t size_field, pad; iov_state_t iov; - int with_size = flags & flatcc_builder_with_size; + int with_size = (flags & flatcc_builder_with_size) != 0; if (align_to_block(B, &align, block_align, !is_top_buffer(B))) { return 0; @@ -744,7 +744,7 @@ flatcc_builder_ref_t flatcc_builder_embed_buffer(flatcc_builder_t *B, flatcc_builder_ref_t flatcc_builder_create_buffer(flatcc_builder_t *B, const char identifier[identifier_size], uint16_t block_align, - flatcc_builder_ref_t object_ref, uint16_t align, int flags) + flatcc_builder_ref_t object_ref, uint16_t align, flatcc_builder_buffer_flags_t flags) { flatcc_builder_ref_t buffer_ref; uoffset_t header_pad, id_size = 0; @@ -808,7 +808,7 @@ flatcc_builder_ref_t flatcc_builder_create_struct(flatcc_builder_t *B, const voi } int flatcc_builder_start_buffer(flatcc_builder_t *B, - const char identifier[identifier_size], uint16_t block_align, int flags) + const char identifier[identifier_size], uint16_t block_align, flatcc_builder_buffer_flags_t flags) { /* * This saves the parent `min_align` in the align field since we @@ -845,9 +845,9 @@ int flatcc_builder_start_buffer(flatcc_builder_t *B, flatcc_builder_ref_t flatcc_builder_end_buffer(flatcc_builder_t *B, flatcc_builder_ref_t root) { flatcc_builder_ref_t buffer_ref; - int flags; + flatcc_builder_buffer_flags_t flags; - flags = B->buffer_flags & flatcc_builder_with_size; + flags = (flatcc_builder_buffer_flags_t)B->buffer_flags & flatcc_builder_with_size; flags |= is_top_buffer(B) ? 0 : flatcc_builder_is_nested; check(frame(type) == flatcc_builder_buffer, "expected buffer frame"); set_min_align(B, B->block_align); diff --git a/src/runtime/json_parser.c b/src/runtime/json_parser.c index 3f8b70598..5a847e1f8 100644 --- a/src/runtime/json_parser.c +++ b/src/runtime/json_parser.c @@ -1263,7 +1263,7 @@ int flatcc_json_parser_table_as_root(flatcc_builder_t *B, flatcc_json_parser_t * { flatcc_json_parser_t _ctx; flatcc_builder_ref_t root; - int builder_flags = flags & flatcc_json_parser_f_with_size ? flatcc_builder_with_size : 0; + flatcc_builder_buffer_flags_t builder_flags = flags & flatcc_json_parser_f_with_size ? flatcc_builder_with_size : 0; ctx = ctx ? ctx : &_ctx; flatcc_json_parser_init(ctx, B, buf, buf + bufsiz, flags); @@ -1283,7 +1283,7 @@ int flatcc_json_parser_struct_as_root(flatcc_builder_t *B, flatcc_json_parser_t { flatcc_json_parser_t _ctx; flatcc_builder_ref_t root; - int builder_flags = flags & flatcc_json_parser_f_with_size ? flatcc_builder_with_size : 0; + flatcc_builder_buffer_flags_t builder_flags = flags & flatcc_json_parser_f_with_size ? flatcc_builder_with_size : 0; ctx = ctx ? ctx : &_ctx; flatcc_json_parser_init(ctx, B, buf, buf + bufsiz, flags); From dc90c4358108b5829ee718f195034c896018108c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Tue, 18 Oct 2022 19:35:23 +0200 Subject: [PATCH 073/106] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ede11234..0e8d84f4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ ## [0.6.2-pre] - CMake: avoid assuming location of build dir during configuration. +- Use untyped integer constants in place of enums for public interface flags to + allow for safe bit masking operations (PR 248). ## [0.6.1] From 5ce5db0c7936cce8d4559d20a94cfbfab0c075fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Sat, 29 Oct 2022 13:14:26 +0200 Subject: [PATCH 074/106] Add experimental support for clangd config --- .gitignore | 3 +++ CMakeLists.txt | 6 ++++++ README.md | 7 +++++++ 3 files changed, 16 insertions(+) diff --git a/.gitignore b/.gitignore index eba83e37c..2d7483235 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ bin/* lib/* release/* scripts/build.cfg +compile_flags.txt +compile_commands.json +.cache diff --git a/CMakeLists.txt b/CMakeLists.txt index 096d13ff1..f1f1a56c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,12 @@ #cmake_minimum_required (VERSION 2.8.11) cmake_minimum_required (VERSION 2.8) +# Experimental for generating compile_commands.json so editors with +# clangd language server support can use it. Symlink +# build/Debug/compile_commands.json to project root where it is +# gitignored. +#set(CMAKE_EXPORT_COMPILE_COMMANDS 1) + # Disable build of tests and samples. Due to custom build step # dependency on flatcc tool, some custom build configurations may # experience issues, and this option can then help. diff --git a/README.md b/README.md index 0b976b5cc..2a60708ca 100644 --- a/README.md +++ b/README.md @@ -1260,6 +1260,13 @@ better padding and cache efficiency. See also [flatc --annotate]. +Note: There is experimental support for text editor that supports +clangd language server or similar. You can edit `CMakeList.txt` +to generate `build/Debug/compile_comands.json`, at least when +using clang as a compiler, and copy or symlink it from root. Or +come with a better suggestion. There are `.gitignore` entries for +`compile_flags.txt` and `compile_commands.json` in project root. + ## File and Type Identifiers From 7134d8daa0b1338723a056401596fffe66355c3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Sat, 29 Oct 2022 13:20:27 +0200 Subject: [PATCH 075/106] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e8d84f4d..7354a8ee5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ - CMake: avoid assuming location of build dir during configuration. - Use untyped integer constants in place of enums for public interface flags to allow for safe bit masking operations (PR 248). +- Added experimental support for generating `compile_commands.json` via + `CMakeList.txt` for use with clangd. ## [0.6.1] From 41e9e7b0b25d698821072f1603d62ca34b57eaf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Mon, 31 Oct 2022 15:51:15 +0100 Subject: [PATCH 076/106] Clean up indentation of if statement --- src/compiler/semantics.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/compiler/semantics.c b/src/compiler/semantics.c index 09b98d30e..e72dbe989 100644 --- a/src/compiler/semantics.c +++ b/src/compiler/semantics.c @@ -131,10 +131,11 @@ static inline void set_type_hash(fb_compound_type_t *ct) uint32_t hash; hash = fb_hash_fnv1a_32_init(); - if (ct->scope) - for (name = ct->scope->name; name; name = name->link) { - hash = fb_hash_fnv1a_32_append(hash, name->ident->text, (size_t)name->ident->len); - hash = fb_hash_fnv1a_32_append(hash, ".", 1); + if (ct->scope) { + for (name = ct->scope->name; name; name = name->link) { + hash = fb_hash_fnv1a_32_append(hash, name->ident->text, (size_t)name->ident->len); + hash = fb_hash_fnv1a_32_append(hash, ".", 1); + } } sym = &ct->symbol; hash = fb_hash_fnv1a_32_append(hash, sym->ident->text, (size_t)sym->ident->len); From d7f50b25c645c3c77640112625adbf2e09ab5e10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Tue, 1 Nov 2022 11:32:51 +0100 Subject: [PATCH 077/106] Add style guide section to README --- README.md | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2a60708ca..b00ee04b2 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,7 @@ executable also handle optional json parsing or printing in less than 2 us for a * [Using the Compiler and Builder library](#using-the-compiler-and-builder-library) * [FlatBuffers Binary Format](#flatbuffers-binary-format) * [Security Considerations](#security-considerations) +* [Style Guide](#style-guide) * [Benchmarks](#benchmarks) @@ -2561,6 +2562,31 @@ Mostly for implementers: [FlatBuffers Binary Format] See [Security Considerations]. +## Style Guide + +FlatCC coding style is largely similar to the [WebKit Style], with the following notable exceptions: + +* Syntax requiring C99 or later is avoided, except `` types are made available. +* If conditions always use curly brackets. +* NULL and nullptr are generally just represented as `0`. +* Comments are old-school C-style (pre C99). Text is generally cased with punctuation: `/* A comment. */` +* `true` and `false` keywords are not used (pre C99). +* In code generation there is essentially no formatting to avoid excessive bloat. +* Struct names and other types is lower case since this is C, not C++. +* `snake_case` is used over `camelCase`. +* Header guards are used over `#pragma once` because it is non-standard and not always reliable in filesystems with ambigious paths. +* Comma is not placed first in multi-line calls (but maybe that would be a good idea for diff stability). +* `config.h` inclusion might be handled differently in that `flatbuffers.h` includes the config file. +* `unsigned` is not used without `int` for historical reasons. Generally a type like `uint32_t` is preferred. +* Use `TODO:` instead of `FIXME:` in comments for historical reasons. + +All the main source code in compiler and runtime aim to be C11 compatible and +uses many C11 constructs. This is made possible through the included portable +library such that older compilers can also function. Therefore any platform specific adaptations will be provided by updating +the portable library rather than introducing compile time flags in the main +source code. + + ## Benchmarks See [Benchmarks] @@ -2583,4 +2609,4 @@ See [Benchmarks] [readfile.h]: include/flatcc/support/readfile.h [Security Considerations]: https://github.com/dvidelabs/flatcc/blob/master/doc/security.md [flatc --annotate]: https://github.com/google/flatbuffers/tree/master/tests/annotated_binary - +[WebKit Style]: https://webkit.org/code-style-guidelines/ From ba71008384dd60a346f30ab1205ee9fbb54bb7aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?= Date: Tue, 8 Nov 2022 18:29:01 +0100 Subject: [PATCH 078/106] Remove use of fallthrough macro in the compiler --- src/compiler/codegen_c_json_parser.c | 4 +--- src/compiler/codegen_c_json_printer.c | 4 +--- src/compiler/parser.c | 3 +-- src/compiler/semantics.c | 7 ++----- 4 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/compiler/codegen_c_json_parser.c b/src/compiler/codegen_c_json_parser.c index 0e2aa250c..307ce76f4 100644 --- a/src/compiler/codegen_c_json_parser.c +++ b/src/compiler/codegen_c_json_parser.c @@ -8,8 +8,6 @@ #include #endif -#include "flatcc/portable/pattributes.h" /* fallthrough */ - #define PRINTLN_SPMAX 64 static char println_spaces[PRINTLN_SPMAX]; @@ -1770,7 +1768,7 @@ static int gen_json_parser_prototypes(fb_output_t *out) println(out, "const char *buf, size_t bufsiz, flatcc_json_parser_flags_t flags);"); unindent(); unindent(); println(out, ""); - fallthrough; + break; default: break; } diff --git a/src/compiler/codegen_c_json_printer.c b/src/compiler/codegen_c_json_printer.c index 2bdaba63d..efc4c3d14 100644 --- a/src/compiler/codegen_c_json_printer.c +++ b/src/compiler/codegen_c_json_printer.c @@ -6,8 +6,6 @@ #include #endif -#include "flatcc/portable/pattributes.h" /* fallthrough */ - static int gen_json_printer_pretext(fb_output_t *out) { fprintf(out->fp, @@ -583,7 +581,7 @@ static int gen_json_printer_prototypes(fb_output_t *out) fprintf(out->fp, "static int %s_print_json(flatcc_json_printer_t *ctx, const char *buf, size_t bufsiz);\n\n", out->S->basename); - fallthrough; + break; default: break; } diff --git a/src/compiler/parser.c b/src/compiler/parser.c index 250d6600d..4f31e0b95 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -16,7 +16,6 @@ #include "codegen.h" #include "fileio.h" #include "pstrutil.h" -#include "flatcc/portable/pattributes.h" /* fallthrough */ #include "flatcc/portable/pparseint.h" void fb_default_error_out(void *err_ctx, const char *buf, size_t len) @@ -920,7 +919,7 @@ static void parse_enum_decl(fb_parser_t *P, fb_compound_type_t *ct) case tok_kw_float32: case tok_kw_float64: error_tok(P, ct->type.t, "integral type expected"); - fallthrough; + break; default: break; } diff --git a/src/compiler/semantics.c b/src/compiler/semantics.c index e72dbe989..d0a766a61 100644 --- a/src/compiler/semantics.c +++ b/src/compiler/semantics.c @@ -11,8 +11,6 @@ #include #endif -#include "flatcc/portable/pattributes.h" /* fallthrough */ - /* Same order as enum! */ static const char *fb_known_attribute_names[] = { "", @@ -525,7 +523,6 @@ static int analyze_struct(fb_parser_t *P, fb_compound_type_t *ct) member = (fb_member_t *)sym; switch (member->type.type) { case vt_fixed_array_type: - /* fall through */ case vt_scalar_type: t = member->type.t; member->type.st = map_scalar_token_type(t); @@ -538,7 +535,6 @@ static int analyze_struct(fb_parser_t *P, fb_compound_type_t *ct) member->size = size * member->type.len; break; case vt_fixed_array_compound_type_ref: - /* fall through */ case vt_compound_type_ref: /* Enums might not be valid, but then it would be detected earlier. */ if (member->type.ct->symbol.kind == fb_is_enum) { @@ -702,8 +698,9 @@ static int process_struct(fb_parser_t *P, fb_compound_type_t *ct) switch (member->type.type) { case vt_fixed_array_type_ref: key_ok = 0; - fallthrough; + goto lbl_type_ref; case vt_type_ref: +lbl_type_ref: type_sym = lookup_type_reference(P, ct->scope, member->type.ref); if (!type_sym) { error_ref_sym(P, member->type.ref, "unknown type reference used with struct field", sym); From 91a0c559494205f2cc7778b3f3236a63b2cd2ae7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?= Date: Tue, 8 Nov 2022 18:31:13 +0100 Subject: [PATCH 079/106] Replace use of fallthrough with goto in runtime Keeping pattributes in the portable library in case usercode requires it. The fallthrough define is no longer used and therefor not defined by default, i.e PORTABLE_EXPOSE_ATTRIBUTES is not enabled. --- include/flatcc/flatcc_json_parser.h | 48 +++++++++++++++++---------- include/flatcc/portable/pattributes.h | 2 +- src/runtime/json_parser.c | 3 +- 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/include/flatcc/flatcc_json_parser.h b/include/flatcc/flatcc_json_parser.h index d86190d79..f8281295a 100644 --- a/include/flatcc/flatcc_json_parser.h +++ b/include/flatcc/flatcc_json_parser.h @@ -242,24 +242,38 @@ static inline uint64_t flatcc_json_parser_symbol_part_ext(const char *buf, const } /* This can bloat inlining for a rarely executed case. */ #if 1 - /* Fall through comments needed to silence gcc 7 warnings. */ switch (n) { - case 8: w |= ((uint64_t)buf[7]) << (0 * 8); - fallthrough; - case 7: w |= ((uint64_t)buf[6]) << (1 * 8); - fallthrough; - case 6: w |= ((uint64_t)buf[5]) << (2 * 8); - fallthrough; - case 5: w |= ((uint64_t)buf[4]) << (3 * 8); - fallthrough; - case 4: w |= ((uint64_t)buf[3]) << (4 * 8); - fallthrough; - case 3: w |= ((uint64_t)buf[2]) << (5 * 8); - fallthrough; - case 2: w |= ((uint64_t)buf[1]) << (6 * 8); - fallthrough; - case 1: w |= ((uint64_t)buf[0]) << (7 * 8); - fallthrough; + case 8: + w |= ((uint64_t)buf[7]) << (0 * 8); + goto lbl_n_7; + case 7: +lbl_n_7: + w |= ((uint64_t)buf[6]) << (1 * 8); + goto lbl_n_6; + case 6: +lbl_n_6: + w |= ((uint64_t)buf[5]) << (2 * 8); + goto lbl_n_5; + case 5: +lbl_n_5: + w |= ((uint64_t)buf[4]) << (3 * 8); + goto lbl_n_4; + case 4: +lbl_n_4: + w |= ((uint64_t)buf[3]) << (4 * 8); + goto lbl_n_3; + case 3: +lbl_n_3: + w |= ((uint64_t)buf[2]) << (5 * 8); + goto lbl_n_2; + case 2: +lbl_n_2: + w |= ((uint64_t)buf[1]) << (6 * 8); + goto lbl_n_1; + case 1: +lbl_n_1: + w |= ((uint64_t)buf[0]) << (7 * 8); + break; case 0: break; } diff --git a/include/flatcc/portable/pattributes.h b/include/flatcc/portable/pattributes.h index 30b3b23d3..9240fa319 100644 --- a/include/flatcc/portable/pattributes.h +++ b/include/flatcc/portable/pattributes.h @@ -40,7 +40,7 @@ extern "C" { #endif #ifndef PORTABLE_EXPOSE_ATTRIBUTES -#define PORTABLE_EXPOSE_ATTRIBUTES 1 +#define PORTABLE_EXPOSE_ATTRIBUTES 0 #endif #ifdef __has_c_attribute diff --git a/src/runtime/json_parser.c b/src/runtime/json_parser.c index 5a847e1f8..3fa929cca 100644 --- a/src/runtime/json_parser.c +++ b/src/runtime/json_parser.c @@ -141,11 +141,10 @@ const char *flatcc_json_parser_space_ext(flatcc_json_parser_t *ctx, const char * ++buf; } while (buf != end && *buf <= 0x20) { - /* Fall through comments needed to silence gcc 7 warnings. */ switch (*buf) { case 0x0d: buf += (end - buf > 1 && buf[1] == 0x0a); /* Consume following LF or treating CR as LF. */ - fallthrough; + ++ctx->line; ctx->line_start = ++buf; continue; case 0x0a: ++ctx->line; ctx->line_start = ++buf; continue; case 0x09: ++buf; continue; case 0x20: goto again; /* Don't consume here, sync with power of 2 spaces. */ From e5be5bec4442382c42e9a07c664d20b79946b545 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Tue, 8 Nov 2022 21:32:52 +0100 Subject: [PATCH 080/106] Update CHANGELOG --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7354a8ee5..fff3df835 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,10 @@ - CMake: avoid assuming location of build dir during configuration. - Use untyped integer constants in place of enums for public interface flags to - allow for safe bit masking operations (PR 248). + allow for safe bit masking operations (PR #248). - Added experimental support for generating `compile_commands.json` via `CMakeList.txt` for use with clangd. +- Remove `fallthrough` macro for improved portability (#247, #252). ## [0.6.1] From 1f1219c54a3c7c08ef288eaf97cbc735d21d9ab8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Fri, 11 Nov 2022 09:43:33 +0100 Subject: [PATCH 081/106] Update coding style --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b00ee04b2..43ff1a583 100644 --- a/README.md +++ b/README.md @@ -2567,7 +2567,7 @@ See [Security Considerations]. FlatCC coding style is largely similar to the [WebKit Style], with the following notable exceptions: * Syntax requiring C99 or later is avoided, except `` types are made available. -* If conditions always use curly brackets. +* If conditions always use curly brackets, or single line statements without linebreak: `if (err) return -1;`. * NULL and nullptr are generally just represented as `0`. * Comments are old-school C-style (pre C99). Text is generally cased with punctuation: `/* A comment. */` * `true` and `false` keywords are not used (pre C99). From 5885e50f88248bc7ed398880c887ab23db89f05a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?= Date: Thu, 17 Nov 2022 15:57:43 +0100 Subject: [PATCH 082/106] Fix builds when using Clang 15 The diagnostics in Clang 15 is stricter and finds: [-Werror,-Wstrict-prototypes] function declaration without a prototype is deprecated Example: cgen_test.c:44:9: int main() [-Werror,-Wunused-but-set-variable] variable 'present_id' set but not used --- src/compiler/codegen_c_reader.c | 4 ---- test/cgen_test/cgen_test.c | 2 +- test/json_test/test_basic_parse.c | 2 +- test/json_test/test_json.c | 2 +- 4 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/compiler/codegen_c_reader.c b/src/compiler/codegen_c_reader.c index 67f8055bc..6de0f2166 100644 --- a/src/compiler/codegen_c_reader.c +++ b/src/compiler/codegen_c_reader.c @@ -1593,7 +1593,6 @@ static void gen_table(fb_output_t *out, fb_compound_type_t *ct) const char *nsc = out->nsc; fb_scoped_name_t snt; fb_scoped_name_t snref; - uint64_t present_id; fb_literal_t literal; int is_optional; @@ -1629,7 +1628,6 @@ static void gen_table(fb_output_t *out, fb_compound_type_t *ct) for (sym = ct->members; sym; sym = sym->link) { current_key_processed = 0; member = (fb_member_t *)sym; - present_id = member->id; is_primary_key = ct->primary_key == member; is_optional = !!(member->flags & fb_fm_optional); print_doc(out, "", member->doc); @@ -1807,7 +1805,6 @@ static void gen_table(fb_output_t *out, fb_compound_type_t *ct) } break; case fb_is_union: - present_id--; fprintf(out->fp, "__%sdefine_union_field(%s, %"PRIu64", %s, %.*s, %s, %u)\n", nsc, nsc, (uint64_t)member->id, snt.text, n, s, snref.text, r); @@ -1833,7 +1830,6 @@ static void gen_table(fb_output_t *out, fb_compound_type_t *ct) break; } if (member->type.ct->symbol.kind == fb_is_union) { - present_id--; fprintf(out->fp, "__%sdefine_union_vector_field(%s, %"PRIu64", %s, %.*s, %s, %u)\n", nsc, nsc, (uint64_t)member->id, snt.text, n, s, snref.text, r); diff --git a/test/cgen_test/cgen_test.c b/test/cgen_test/cgen_test.c index 94f4bba9b..6d58ed1a9 100644 --- a/test/cgen_test/cgen_test.c +++ b/test/cgen_test/cgen_test.c @@ -41,7 +41,7 @@ #include #include "flatcc/flatcc.h" -int main() +int main(void) { const char *name = "../xyzzy.fbs"; diff --git a/test/json_test/test_basic_parse.c b/test/json_test/test_basic_parse.c index de27ee775..7b8f4bac9 100644 --- a/test/json_test/test_basic_parse.c +++ b/test/json_test/test_basic_parse.c @@ -277,7 +277,7 @@ const char *test(flatcc_builder_t *B, const char *buf, const char *end, int *ret return buf; } -int main() +int main(void) { int ret = -1; flatcc_builder_t builder; diff --git a/test/json_test/test_json.c b/test/json_test/test_json.c index 1a317ea17..aeee13a04 100644 --- a/test/json_test/test_json.c +++ b/test/json_test/test_json.c @@ -582,7 +582,7 @@ int fixed_array_tests(void) * covered in the printer and parser tests using the golden data * set. */ -int main() +int main(void) { BEGIN_TEST(Monster); From f89fe1ed243f3d464dc25bad872eac28f1e62b43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Fri, 18 Nov 2022 11:45:37 +0100 Subject: [PATCH 083/106] Add float compare functions to work around GCC double precision conversion --- include/flatcc/portable/pparsefp.h | 62 +++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/include/flatcc/portable/pparsefp.h b/include/flatcc/portable/pparsefp.h index 1d2b9da26..f10d6a816 100644 --- a/include/flatcc/portable/pparsefp.h +++ b/include/flatcc/portable/pparsefp.h @@ -5,6 +5,8 @@ extern "C" { #endif +#include /* memcpy */ + /* * Parses a float or double number and returns the length parsed if * successful. The length argument is of limited value due to dependency @@ -34,7 +36,7 @@ extern "C" { * Other compilers such as xlc may require linking with -lm which may not * be convienent so a default isinf is provided. If isinf is available * and there is a noticable performance issue, define - * `PORTABLE_USE_ISINF`. + * `PORTABLE_USE_ISINF`. This flag also affects isnan. */ #if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER) || defined(PORTABLE_USE_ISINF) #include @@ -48,8 +50,9 @@ extern "C" { * loss warning with -Wconversion flag when cast is absent. */ #if defined(__clang__) -#if __clang_major__ >= 5 && __clang_major__ <= 8 +#if __clang_major__ >= 3 && __clang_major__ <= 8 #define parse_double_isinf(x) isinf((float)x) +#define parse_double_isnan(x) isnan((float)x) #endif #endif #if !defined(parse_double_isinf) @@ -64,19 +67,29 @@ extern "C" { #endif /* Avoid linking with libmath but depends on float/double being IEEE754 */ -static inline int parse_double_isinf(double x) +static inline int parse_double_isinf(const double x) { - union { uint64_t u64; double f64; } v; - v.f64 = x; - return (v.u64 & 0x7fffffff00000000ULL) == 0x7ff0000000000000ULL; + uint64_t u64x; + + memcpy(&u64x, &x, sizeof(u64x)); + return (u64x & 0x7fffffff00000000ULL) == 0x7ff0000000000000ULL; } static inline int parse_float_isinf(float x) { - union { uint32_t u32; float f32; } v; - v.f32 = x; - return (v.u32 & 0x7fffffff) == 0x7f800000; + uint32_t u32x; + + memcpy(&u32x, &x, sizeof(u32x)); + return (u32x & 0x7fffffff) == 0x7f800000; } + +#endif + +#if !defined(parse_double_isnan) +#define parse_double_isnan isnan +#endif +#if !defined(parse_float_isnan) +#define parse_float_isnan isnan #endif /* Returns 0 when in range, 1 on overflow, and -1 on underflow. */ @@ -131,6 +144,37 @@ static inline const char *parse_float(const char *buf, size_t len, float *result return end; } +/* Inspired by https://bitbashing.io/comparing-floats.html */ +static inline int parse_double_compare(const double x, const double y) +{ + /* This also handles NaN */ + if (x == y) return 0; + return x < y ? -1 : 1; +} + +static inline int parse_float_compare(const float x, const float y) +{ + int32_t i32x, i32y; + + if (x == y) return 0; + if (parse_float_isnan(x)) return 1; + if (parse_float_isnan(y)) return 1; + memcpy(&i32x, &x, sizeof(i32x)); + memcpy(&i32y, &y, sizeof(i32y)); + return i32x < i32y ? -1 : 1; +} + +int parse_double_is_equal(const double x, const double y) +{ + return x == y; +} + +/* Works around GCC double precisoni conversion of floats. */ +static inline int parse_float_is_equal(const float x, const float y) +{ + return parse_float_compare(x, y) == 0; +} + #include "pdiagnostic_pop.h" #ifdef __cplusplus From 195246aa7c6a889887f3f254e883333aeee4f8f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Fri, 18 Nov 2022 11:48:20 +0100 Subject: [PATCH 084/106] Update CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fff3df835..556d32a51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ - Added experimental support for generating `compile_commands.json` via `CMakeList.txt` for use with clangd. - Remove `fallthrough` macro for improved portability (#247, #252). +- Added `parse_float/double_compare`, `parse_float/double_is_equal` to + portable library, and added `parse_float/double_isnan` to mirror isinf. + This should help with GCC 32-bit double precision conversion issue. ## [0.6.1] From 4810b9e9f85d3897776bd13c87d8c1ab059979d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Fri, 18 Nov 2022 12:35:35 +0100 Subject: [PATCH 085/106] Improve on pparse floating point comparison operations --- include/flatcc/portable/pparsefp.h | 64 +++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 11 deletions(-) diff --git a/include/flatcc/portable/pparsefp.h b/include/flatcc/portable/pparsefp.h index f10d6a816..6ece207de 100644 --- a/include/flatcc/portable/pparsefp.h +++ b/include/flatcc/portable/pparsefp.h @@ -145,34 +145,76 @@ static inline const char *parse_float(const char *buf, size_t len, float *result } /* Inspired by https://bitbashing.io/comparing-floats.html */ -static inline int parse_double_compare(const double x, const double y) + +/* Return signed ULP distance or INT64_MAX if any value is nan. */ +static inline int64_t parse_double_compare(const double x, const double y) { - /* This also handles NaN */ + int64_t i64x, i64y; + if (x == y) return 0; - return x < y ? -1 : 1; + if (parse_double_isnan(x)) return INT64_MAX; + if (parse_double_isnan(y)) return INT64_MAX; + memcpy(&i64x, &x, sizeof(i64x)); + memcpy(&i64y, &y, sizeof(i64y)); + if ((i64x < 0) != (i64y < 0)) return INT64_MAX; + return i64x - i64y; } -static inline int parse_float_compare(const float x, const float y) +/* Same as double, but INT32_MAX if nan. */ +static inline int32_t parse_float_compare(const float x, const float y) { int32_t i32x, i32y; if (x == y) return 0; - if (parse_float_isnan(x)) return 1; - if (parse_float_isnan(y)) return 1; + if (parse_float_isnan(x)) return INT32_MAX; + if (parse_float_isnan(y)) return INT32_MAX; memcpy(&i32x, &x, sizeof(i32x)); memcpy(&i32y, &y, sizeof(i32y)); - return i32x < i32y ? -1 : 1; + if ((i32x < 0) != (i32y < 0)) return INT32_MAX; + return i32x - i32y; +} + +/* + * Returns the absolute distance in flaoting point ULP (representational bit difference). + * Uses signed return value so that INT64_MAX and INT32_MAX indicates NaN similar to + * the compare function. + */ +static inline int64_t parse_double_dist(const double x, const double y) +{ + uint64_t m64; + int64_t i64; + + i64 = parse_double_compare(x, y); + /* Absolute integer value of compare. */ + m64 = -(uint64_t)(i64 < 0); + return (int64_t)(((uint64_t)i64 + m64) ^ m64); +} + +/* Same as double, but INT32_MAX if NaN. */ +static inline int32_t parse_float_dist(const float x, const float y) +{ + uint32_t m32; + int32_t i32; + + i32 = parse_float_compare(x, y); + /* Absolute integer value of compare. */ + m32 = -(uint32_t)(i32 < 0); + return (int32_t)(((uint32_t)i32 + m32) ^ m32); } -int parse_double_is_equal(const double x, const double y) +/* + * Returns 1 if no value is NaN, and the difference is at most one ULP (1 bit), and the + * sign is the same, and 0 otherwise. + */ +static inline int parse_double_is_equal(const double x, const double y) { - return x == y; + return parse_double_dist(x, y) >> 1 == 0; } -/* Works around GCC double precisoni conversion of floats. */ +/* Same as double, but at lower precision. */ static inline int parse_float_is_equal(const float x, const float y) { - return parse_float_compare(x, y) == 0; + return parse_float_dist(x, y) >> 1 == 0; } #include "pdiagnostic_pop.h" From 8695d6fa587e5d5d7b500a0308873dbcdfa94fb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Fri, 18 Nov 2022 12:46:01 +0100 Subject: [PATCH 086/106] Add lower precsion floating point tests to handle GCC 32-bit floats --- test/emit_test/emit_test.c | 7 ++++++- test/monster_test/monster_test.c | 7 +++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/test/emit_test/emit_test.c b/test/emit_test/emit_test.c index fa18034ac..ddb973dde 100644 --- a/test/emit_test/emit_test.c +++ b/test/emit_test/emit_test.c @@ -2,8 +2,13 @@ #include #include "emit_test_builder.h" #include "flatcc/support/hexdump.h" +#include "flatcc/portable/pparsefp.h" #define test_assert(x) do { if (!(x)) { assert(0); return -1; }} while(0) +/* Direct floating point comparisons are not always directly comparable, + * especially not for GCC 32-bit compilers. */ +#define test_assert_floateq(x, y) test_assert(parse_float_is_equal((x), (y))) +#define test_assert_doubleeq(x, y) test_assert(parse_double_is_equal((x), (y))) int dbg_emitter(void *emit_context, const flatcc_iovec_t *iov, int iov_count, @@ -112,7 +117,7 @@ int emit_test(void) test_assert(time == 42); test_assert(main_device(mt) == 1); test_assert(flatbuffers_float_vec_len(main_samples(mt)) == 4); - test_assert(flatbuffers_float_vec_at(main_samples(mt), 2) == 1.2f); + test_assert_floateq(flatbuffers_float_vec_at(main_samples(mt), 2), 1.2f); /* We use get_direct_buffer, so we can't clear the builder until last. */ flatcc_builder_clear(B); diff --git a/test/monster_test/monster_test.c b/test/monster_test/monster_test.c index 400415c5d..02fc6444d 100644 --- a/test/monster_test/monster_test.c +++ b/test/monster_test/monster_test.c @@ -5,6 +5,7 @@ #include "flatcc/support/hexdump.h" #include "flatcc/support/elapsed.h" +#include "flatcc/portable/pparsefp.h" #include "../../config/config.h" /* @@ -371,8 +372,10 @@ int verify_monster(void *buffer) if ((size_t)vec & 15) { printf("Force align of Vec3 struct not correct\n"); } - /* -3.2f is actually -3.20000005 and not -3.2 due to representation loss. */ - if (ns(Vec3_z(vec)) != -3.2f) { + /* -3.2f is actually -3.20000005 and not -3.2 due to representation loss. + * For 32-bit GCC compilers, -3.2f might be another value, so use lower + * precision portable comparison. */ + if (!parse_float_is_equal(ns(Vec3_z(vec)), -3.2f)) { printf("Position failing on z coordinate\n"); return -1; } From a6ba3947f7d1c4f8e0053691ab6f50c29ccb4de5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?= Date: Mon, 24 Oct 2022 13:01:33 +0200 Subject: [PATCH 087/106] Add Github CI and weekly test runs Also introduces a new build config for forced 32bit builds: > scripts/initbuild.sh make-32bit --- .github/workflows/ci.yml | 60 ++++++++++ .github/workflows/weekly.yml | 188 ++++++++++++++++++++++++++++++ README.md | 14 ++- scripts/build.cfg.make | 1 + scripts/build.cfg.make-32bit | 3 + scripts/build.cfg.make-concurrent | 1 + scripts/build.cfg.ninja | 1 + scripts/initbuild.sh | 4 +- 8 files changed, 267 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/weekly.yml create mode 100644 scripts/build.cfg.make-32bit diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..42e227d67 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,60 @@ +name: CI + +on: [push, pull_request] + +env: + CTEST_OUTPUT_ON_FAILURE: 1 + +jobs: + ubuntu-ninja-clang: + name: Ubuntu (ninja, clang) + runs-on: ubuntu-22.04 + steps: + - name: Prepare + run: | + sudo apt update + sudo apt install ninja-build + - uses: actions/checkout@v3 + - name: Build and run tests + env: + CC: clang + CXX: clang++ + run: | + scripts/test.sh + + ubuntu-make-gcc: + name: Ubuntu (make, gcc) + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + - name: Build and run tests + env: + CC: gcc + CXX: g++ + run: | + scripts/initbuild.sh make + scripts/test.sh + + macos: + name: macOS + runs-on: macos-12 + steps: + - name: Prepare + run: | + brew install cmake ninja + - uses: actions/checkout@v3 + - name: Build and run tests + run: | + scripts/test.sh + + windows: + name: Windows + runs-on: windows-2022 + steps: + - uses: microsoft/setup-msbuild@v1.1 + - uses: actions/checkout@v3 + - name: Build and run tests + run: | + cmake . + msbuild FlatCC.sln /m /property:Configuration=Release + ctest -VV diff --git a/.github/workflows/weekly.yml b/.github/workflows/weekly.yml new file mode 100644 index 000000000..d88903f66 --- /dev/null +++ b/.github/workflows/weekly.yml @@ -0,0 +1,188 @@ +name: Weekly + +on: + workflow_dispatch: + schedule: + - cron: '0 10 * * 1' # Mon 10.00 UTC + +env: + CTEST_OUTPUT_ON_FAILURE: 1 + +jobs: + clang: + name: Clang ${{ matrix.clang-version }} + runs-on: ubuntu-20.04 + strategy: + fail-fast: false + matrix: + clang-version: [5, 7, 9, 11, 13, 15] + steps: + - name: Setup Clang + uses: aminya/setup-cpp@v1 + with: + llvm: ${{ matrix.clang-version }} + - uses: actions/checkout@v3 + - name: Build and run tests + run: | + scripts/initbuild.sh make-concurrent + scripts/test.sh + + clang-32bit: + name: Clang 32bit + runs-on: ubuntu-20.04 + steps: + - name: Prepare + run: | + sudo apt update + sudo apt install gcc-multilib g++-multilib + - uses: actions/checkout@v3 + - name: Build and run tests + env: + CC: clang + CXX: clang++ + run: | + scripts/initbuild.sh make-32bit + scripts/test.sh + + gcc-old: + name: GCC 4.4 + runs-on: ubuntu-20.04 + steps: + - name: Setup GCC + run: | + wget http://launchpadlibrarian.net/336269522/libmpfr4_3.1.6-1_amd64.deb + wget http://old-releases.ubuntu.com/ubuntu/pool/universe/g/gcc-4.4/gcc-4.4-base_4.4.7-8ubuntu1_amd64.deb + wget http://old-releases.ubuntu.com/ubuntu/pool/universe/g/gcc-4.4/cpp-4.4_4.4.7-8ubuntu1_amd64.deb + wget http://old-releases.ubuntu.com/ubuntu/pool/universe/g/gcc-4.4/gcc-4.4_4.4.7-8ubuntu1_amd64.deb + wget http://old-releases.ubuntu.com/ubuntu/pool/universe/g/gcc-4.4/libstdc++6-4.4-dev_4.4.7-8ubuntu1_amd64.deb + wget http://old-releases.ubuntu.com/ubuntu/pool/universe/g/gcc-4.4/g++-4.4_4.4.7-8ubuntu1_amd64.deb + sudo dpkg -i ./libmpfr4_3.1.6-1_amd64.deb + sudo dpkg -i ./gcc-4.4-base_4.4.7-8ubuntu1_amd64.deb + sudo dpkg -i ./cpp-4.4_4.4.7-8ubuntu1_amd64.deb + sudo dpkg -i ./gcc-4.4_4.4.7-8ubuntu1_amd64.deb + sudo dpkg -i ./libstdc++6-4.4-dev_4.4.7-8ubuntu1_amd64.deb ./g++-4.4_4.4.7-8ubuntu1_amd64.deb + - uses: actions/checkout@v3 + - name: Build and run tests + env: + CC: gcc-4.4 + CXX: g++-4.4 + run: | + scripts/initbuild.sh make-concurrent + scripts/test.sh + + gcc: + name: GCC ${{ matrix.gcc-version }} + runs-on: ubuntu-20.04 + strategy: + fail-fast: false + matrix: + gcc-version: [7, 9, 11] + steps: + - name: Setup GCC + uses: aminya/setup-cpp@v1 + with: + gcc: ${{ matrix.gcc-version }} + - uses: actions/checkout@v3 + - name: Build and run tests + run: | + scripts/initbuild.sh make-concurrent + scripts/test.sh + + gcc-32bit: + name: GCC 32bit + runs-on: ubuntu-20.04 + steps: + - name: Prepare + run: | + sudo apt update + sudo apt install gcc-multilib g++-multilib + - uses: actions/checkout@v3 + - name: Build and run tests + run: | + scripts/initbuild.sh make-32bit + scripts/test.sh + + intel: + name: Intel ${{ matrix.compiler }} + runs-on: ubuntu-20.04 + strategy: + fail-fast: false + matrix: + compiler: [icc, icx] + steps: + - name: Prepare + run: | + wget -qO - https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB | sudo apt-key add - + echo "deb https://apt.repos.intel.com/oneapi all main" | sudo tee /etc/apt/sources.list.d/oneAPI.list + sudo apt update + sudo apt install intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic-2021.4.0 + - name: Setup Intel oneAPI + run: | + source /opt/intel/oneapi/setvars.sh + printenv >> $GITHUB_ENV + - uses: actions/checkout@v3 + - name: Build and run tests + env: + CC: ${{ matrix.compiler }} + CXX: ${{ matrix.compiler }} + run: | + scripts/initbuild.sh make-concurrent + scripts/test.sh + + macos-clang: + name: macOS Clang + runs-on: macos-11 + steps: + - uses: actions/checkout@v3 + - name: Build and run tests + run: | + scripts/initbuild.sh make-concurrent + scripts/test.sh + + macos-gcc: + name: macOS GCC ${{ matrix.gcc-version }} + runs-on: macos-11 + strategy: + fail-fast: false + matrix: + gcc-version: [9, 12] + steps: + - uses: actions/checkout@v3 + - name: Build and run tests + env: + CC: gcc-${{ matrix.gcc-version }} + CXX: g++-${{ matrix.gcc-version }} + run: | + scripts/initbuild.sh make-concurrent + scripts/test.sh + + windows: + name: Windows Visual Studio ${{ matrix.version }} + runs-on: windows-${{ matrix.version }} + strategy: + fail-fast: false + matrix: + version: [2019, 2022] + steps: + - uses: microsoft/setup-msbuild@v1.1 + - uses: actions/checkout@v3 + - name: Build and run tests + run: | + cmake . + msbuild FlatCC.sln /m /property:Configuration=Release + ctest -VV + + cmake-minimum-required: + name: CMake 2.8.12 (min. required) + runs-on: ubuntu-20.04 + steps: + - name: Setup cmake + uses: jwlawson/actions-setup-cmake@v1 + with: + cmake-version: 2.8.12 + - uses: actions/checkout@v3 + - name: Build and run tests + run: | + cmake --version + scripts/initbuild.sh make-concurrent + scripts/test.sh diff --git a/README.md b/README.md index 43ff1a583..95fe80866 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ -OS-X & Ubuntu: [![Build Status](https://travis-ci.org/dvidelabs/flatcc.svg?branch=master)](https://travis-ci.org/dvidelabs/flatcc) +Ubuntu, macOS and Windows: [![Build Status](https://github.com/dvidelabs/flatcc/actions/workflows/ci.yml/badge.svg)](https://github.com/dvidelabs/flatcc/actions/workflows/ci.yml) Windows: [![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/dvidelabs/flatcc?branch=master&svg=true)](https://ci.appveyor.com/project/dvidelabs/flatcc) +Weekly: [![Build Status](https://github.com/dvidelabs/flatcc/actions/workflows/weekly.yml/badge.svg)](https://github.com/dvidelabs/flatcc/actions/workflows/weekly.yml) _The JSON parser may change the interface for parsing union vectors in a @@ -2226,8 +2227,15 @@ Optionally switch to a different build tool by choosing one of: scripts/initbuild.sh make-concurrent scripts/initbuild.sh ninja -where `ninja` is the default and `make-concurrent` is `make` with the `-j` -flag. A custom build configuration `X` can be added by adding a +where `ninja` is the default and `make-concurrent` is `make` with the `-j` flag. + +To enforce a 32-bit build on a 64-bit machine the following configuration +can be used: + + scripts/initbuild.sh make-32bit + +which uses `make` and provides the `-m32` flag to the compiler. +A custom build configuration `X` can be added by adding a `scripts/build.cfg.X` file. `scripts/initbuild.sh` cleans the build if a specific build diff --git a/scripts/build.cfg.make b/scripts/build.cfg.make index 684ecfc81..ae9c33258 100644 --- a/scripts/build.cfg.make +++ b/scripts/build.cfg.make @@ -1,2 +1,3 @@ FLATCC_BUILD_GEN="Unix Makefiles" FLATCC_BUILD_CMD=make +FLATCC_BUILD_FLAGS="" diff --git a/scripts/build.cfg.make-32bit b/scripts/build.cfg.make-32bit new file mode 100644 index 000000000..2299d679e --- /dev/null +++ b/scripts/build.cfg.make-32bit @@ -0,0 +1,3 @@ +FLATCC_BUILD_GEN="Unix Makefiles" +FLATCC_BUILD_CMD=make +FLATCC_BUILD_FLAGS="-DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32" diff --git a/scripts/build.cfg.make-concurrent b/scripts/build.cfg.make-concurrent index 35d82f0ea..76846426b 100644 --- a/scripts/build.cfg.make-concurrent +++ b/scripts/build.cfg.make-concurrent @@ -1,2 +1,3 @@ FLATCC_BUILD_GEN="Unix Makefiles" FLATCC_BUILD_CMD="make -j" +FLATCC_BUILD_FLAGS="" diff --git a/scripts/build.cfg.ninja b/scripts/build.cfg.ninja index d69bb6d24..07ead7000 100644 --- a/scripts/build.cfg.ninja +++ b/scripts/build.cfg.ninja @@ -1,2 +1,3 @@ FLATCC_BUILD_GEN=Ninja FLATCC_BUILD_CMD=ninja +FLATCC_BUILD_FLAGS="" diff --git a/scripts/initbuild.sh b/scripts/initbuild.sh index 00561fa73..2b18cd257 100755 --- a/scripts/initbuild.sh +++ b/scripts/initbuild.sh @@ -36,5 +36,5 @@ mkdir -p ${ROOT}/build/Release rm -rf ${ROOT}/build/Debug/* rm -rf ${ROOT}/build/Release/* -cd ${ROOT}/build/Debug && cmake -G "$FLATCC_BUILD_GEN" ../.. -DCMAKE_BUILD_TYPE=Debug -cd ${ROOT}/build/Release && cmake -G "$FLATCC_BUILD_GEN" ../.. -DCMAKE_BUILD_TYPE=Release +cd ${ROOT}/build/Debug && cmake -G "$FLATCC_BUILD_GEN" $FLATCC_BUILD_FLAGS ../.. -DCMAKE_BUILD_TYPE=Debug +cd ${ROOT}/build/Release && cmake -G "$FLATCC_BUILD_GEN" $FLATCC_BUILD_FLAGS ../.. -DCMAKE_BUILD_TYPE=Release From 015cfece7e5a9c31033cef6ab5605ab19e1f9f74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?= Date: Tue, 15 Nov 2022 09:13:14 +0100 Subject: [PATCH 088/106] Fix GCC on Mac builds aligned_alloc() seems not fully supported when using GCC on Mac, so use posix_memalign() instead. aligned_alloc() returns null in tests and https://en.cppreference.com/w/c/memory/aligned_alloc states: ".. not supported by the implementation causes the function to fail and return a null pointer" --- include/flatcc/portable/paligned_alloc.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/flatcc/portable/paligned_alloc.h b/include/flatcc/portable/paligned_alloc.h index 3dcf4efcd..70b00b9ea 100644 --- a/include/flatcc/portable/paligned_alloc.h +++ b/include/flatcc/portable/paligned_alloc.h @@ -61,6 +61,8 @@ extern "C" { #define PORTABLE_C11_ALIGNED_ALLOC 0 #elif defined (__clang__) #define PORTABLE_C11_ALIGNED_ALLOC 0 +#elif defined (__APPLE__) +#define PORTABLE_C11_ALIGNED_ALLOC 0 #elif defined(__IBMC__) #define PORTABLE_C11_ALIGNED_ALLOC 0 #elif (defined(__STDC__) && __STDC__ && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) From 30712d9174b5bea61121a0fa5a6be911effe68d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?= Date: Tue, 15 Nov 2022 09:42:12 +0100 Subject: [PATCH 089/106] Include clang 3-4 in precision warning workaround --- include/flatcc/portable/pparsefp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/flatcc/portable/pparsefp.h b/include/flatcc/portable/pparsefp.h index 6ece207de..d3e6f59ed 100644 --- a/include/flatcc/portable/pparsefp.h +++ b/include/flatcc/portable/pparsefp.h @@ -46,7 +46,7 @@ extern "C" { #define isinf(x) (!_finite(x)) #endif /* - * clang-5 through clang-8 but not clang-9 issues incorrect precision + * clang-3 through clang-8 but not clang-9 issues incorrect precision * loss warning with -Wconversion flag when cast is absent. */ #if defined(__clang__) From 16ac66aba77704546321b0d6f6698abd5eb72971 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?= Date: Tue, 15 Nov 2022 10:14:15 +0100 Subject: [PATCH 090/106] Suppress missing-field-initializers warning pre-clang6 semantics.c:1551:32: error: missing field 'len' initializer fb_value_t index = { { { 0 } }, 0, 0 }; See https://reviews.llvm.org/D28148 and related https://reviews.llvm.org/rL314838 --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index f1f1a56c5..5a304e2fc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -188,6 +188,10 @@ if (CMAKE_C_COMPILER_ID MATCHES "Clang") if (FLATCC_IGNORE_CONST_COND) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-tautological-constant-out-of-range-compare") endif() + # Suppress warning relaxed in clang-6, see https://reviews.llvm.org/D28148 + if (CMAKE_C_COMPILER_VERSION VERSION_LESS 6) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-field-initializers") + endif() # To get assembly output # set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -save-temps") From 5f07eda43caabd81a2bfa2857af0e3f26dc6d4ee Mon Sep 17 00:00:00 2001 From: Anush Elangovan Date: Mon, 25 Oct 2021 15:46:57 -0700 Subject: [PATCH 091/106] Newer CMake is going to drop <2.8.12 So update to 2.8.12.2 (in Ubuntu 14.04) CentOS 7 has a way to install CMake3. This avoids the warning in newer CMakes: flatcc/CMakeLists.txt:5 (cmake_minimum_required): Compatibility with CMake < 2.8.12 will be removed from a future version of CMake. --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a304e2fc..3bbfe252d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,8 @@ # Ubuntu 14.04 (Trusty) -#cmake_minimum_required (VERSION 2.8.12.2) +cmake_minimum_required (VERSION 2.8.12.2) # Centos 7 #cmake_minimum_required (VERSION 2.8.11) -cmake_minimum_required (VERSION 2.8) +#cmake_minimum_required (VERSION 2.8) # Experimental for generating compile_commands.json so editors with # clangd language server support can use it. Symlink From 53886d26677bf4673be86160434b4263c9ca9342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?= Date: Fri, 18 Nov 2022 14:15:48 +0100 Subject: [PATCH 092/106] Add more lowered precision tests of floats (for GCC 32-bit) --- test/monster_test/monster_test.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/test/monster_test/monster_test.c b/test/monster_test/monster_test.c index 02fc6444d..f3150d8e3 100644 --- a/test/monster_test/monster_test.c +++ b/test/monster_test/monster_test.c @@ -163,8 +163,8 @@ int test_type_aliases(flatcc_builder_t *B) if (ns(TypeAliases_u16(ta)) != UINT16_MAX) goto failed; if (ns(TypeAliases_u32(ta)) != UINT32_MAX) goto failed; if (ns(TypeAliases_u64(ta)) != UINT64_MAX) goto failed; - if (ns(TypeAliases_f32(ta)) != 2.3f) goto failed; - if (ns(TypeAliases_f64(ta)) != 2.3) goto failed; + if (!parse_float_is_equal(ns(TypeAliases_f32(ta)), 2.3f)) goto failed; + if (!parse_double_is_equal(ns(TypeAliases_f64(ta)), 2.3)) goto failed; if (sizeof(ns(TypeAliases_i8(ta))) != 1) goto failed; if (sizeof(ns(TypeAliases_i16(ta))) != 2) goto failed; if (sizeof(ns(TypeAliases_i32(ta))) != 4) goto failed; @@ -380,7 +380,9 @@ int verify_monster(void *buffer) return -1; } if (nsc(is_native_pe())) { - if (vec->x != 1.0f || vec->y != 2.0f || vec->z != -3.2f) { + if (!parse_float_is_equal(vec->x, 1.0f) || + !parse_float_is_equal(vec->y, 2.0f) || + !parse_float_is_equal(vec->z, -3.2f)) { printf("Position is incorrect\n"); return -1; } @@ -399,7 +401,9 @@ int verify_monster(void *buffer) */ ns(Vec3_clear(&v)); /* Not strictly needed here. */ ns(Vec3_copy_from_pe(&v, vec)); - if (v.x != 1.0f || v.y != 2.0f || v.z != -3.2f) { + if (!parse_float_is_equal(v.x, 1.0f) || + !parse_float_is_equal(v.y, 2.0f) || + !parse_float_is_equal(v.z, -3.2f)) { printf("Position is incorrect after copy\n"); return -1; } @@ -1604,7 +1608,7 @@ int test_clone_slice(flatcc_builder_t *B) printf("sliced bool has wrong content\n"); goto done; } - if (ns(Monster_pos(mon2)->x != -42.3f)) { + if (!parse_float_is_equal(ns(Monster_pos(mon2))->x, -42.3f)) { printf("cloned pos struct failed\n"); goto done; }; @@ -2564,8 +2568,8 @@ int test_struct_buffer(flatcc_builder_t *B) /* Convert buffer to native in place - a nop on native platform. */ v = (ns(Vec3_t) *)vec3; ns(Vec3_from_pe(v)); - if (v->x != 1.0f || v->y != 2.0f || v->z != 3.0f - || v->test1 != 4.2 || v->test2 != ns(Color_Blue) + if (!parse_float_is_equal(v->x, 1.0f) || !parse_float_is_equal(v->y, 2.0f) || !parse_float_is_equal(v->z, 3.0f) + || !parse_double_is_equal(v->test1, 4.2) || v->test2 != ns(Color_Blue) || v->test3.a != 2730 || v->test3.b != -17 ) { printf("struct buffer not valid\n"); @@ -2629,8 +2633,8 @@ int test_typed_struct_buffer(flatcc_builder_t *B) /* Convert buffer to native in place - a nop on native platform. */ v = (ns(Vec3_t) *)vec3; ns(Vec3_from_pe(v)); - if (v->x != 1.0f || v->y != 2.0f || v->z != 3.0f - || v->test1 != 4.2 || v->test2 != ns(Color_Blue) + if (!parse_float_is_equal(v->x, 1.0f) || !parse_float_is_equal(v->y, 2.0f) || !parse_float_is_equal(v->z, 3.0f) + || !parse_double_is_equal(v->test1, 4.2) || v->test2 != ns(Color_Blue) || v->test3.a != 2730 || v->test3.b != -17 ) { printf("struct buffer not valid\n"); From d073ffd7280c9d15fef5b8155807bdcdaff96b68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Mon, 21 Nov 2022 12:07:21 +0100 Subject: [PATCH 093/106] Update CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 556d32a51..24c80955a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ - Added `parse_float/double_compare`, `parse_float/double_is_equal` to portable library, and added `parse_float/double_isnan` to mirror isinf. This should help with GCC 32-bit double precision conversion issue. +- Add Github Actions builds to replace stale Travis CI build. This also + includes source code fixes for some build variants. Although + Windows build is included it only covers recent 64-bit Windows. More + work is need for older Windows variants. (#250). ## [0.6.1] From f329ce8d82c88ab2b943be1a2051da2e2aab98b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Tue, 29 Nov 2022 18:34:31 +0100 Subject: [PATCH 094/106] Increase maximum allowed schema file siz --- CHANGELOG.md | 1 + config/config.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24c80955a..bea295697 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ includes source code fixes for some build variants. Although Windows build is included it only covers recent 64-bit Windows. More work is need for older Windows variants. (#250). +- Increase maximum allowed schema file size from 64 KiB to 1 MB (#256). ## [0.6.1] diff --git a/config/config.h b/config/config.h index 041ec228c..b07fa6cc8 100644 --- a/config/config.h +++ b/config/config.h @@ -54,7 +54,7 @@ * is covers the accumulated size of all included files. 0 is unlimited. */ #ifndef FLATCC_MAX_SCHEMA_SIZE -#define FLATCC_MAX_SCHEMA_SIZE 64 * 1024 +#define FLATCC_MAX_SCHEMA_SIZE 1000000 #endif /* From 27a63fbf40676bb91dc7c6b8cbabfaefc204cbc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Mon, 5 Dec 2022 15:37:39 +0100 Subject: [PATCH 095/106] Fix seg fault in json parser --- CHANGELOG.md | 3 ++- src/runtime/json_parser.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bea295697..7ff4a4a95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,8 @@ Windows build is included it only covers recent 64-bit Windows. More work is need for older Windows variants. (#250). - Increase maximum allowed schema file size from 64 KiB to 1 MB (#256). - +- Fix seg fault in json parser while adding null characters to a too + short input string for a fixed length char array struct field (#257). ## [0.6.1] diff --git a/src/runtime/json_parser.c b/src/runtime/json_parser.c index 3fa929cca..4472af2d8 100644 --- a/src/runtime/json_parser.c +++ b/src/runtime/json_parser.c @@ -879,7 +879,7 @@ const char *flatcc_json_parser_char_array(flatcc_json_parser_t *ctx, if (ctx->flags & flatcc_json_parser_f_reject_array_underflow) { return flatcc_json_parser_set_error(ctx, buf, end, flatcc_json_parser_error_array_underflow); } - memset(s, 0, n - k); + memset(s, 0, n); } return flatcc_json_parser_string_end(ctx, buf, end); } From b20f5d1059d50394415453e2a6f719532ee6278d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Thu, 8 Dec 2022 14:56:06 +0100 Subject: [PATCH 096/106] Fix unary minus of unsigned warning --- include/flatcc/portable/pparsefp.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/flatcc/portable/pparsefp.h b/include/flatcc/portable/pparsefp.h index d3e6f59ed..7fa1c247d 100644 --- a/include/flatcc/portable/pparsefp.h +++ b/include/flatcc/portable/pparsefp.h @@ -175,7 +175,7 @@ static inline int32_t parse_float_compare(const float x, const float y) } /* - * Returns the absolute distance in flaoting point ULP (representational bit difference). + * Returns the absolute distance in floating point ULP (representational bit difference). * Uses signed return value so that INT64_MAX and INT32_MAX indicates NaN similar to * the compare function. */ @@ -186,7 +186,7 @@ static inline int64_t parse_double_dist(const double x, const double y) i64 = parse_double_compare(x, y); /* Absolute integer value of compare. */ - m64 = -(uint64_t)(i64 < 0); + m64 = (uint64_t)-(i64 < 0); return (int64_t)(((uint64_t)i64 + m64) ^ m64); } @@ -198,7 +198,7 @@ static inline int32_t parse_float_dist(const float x, const float y) i32 = parse_float_compare(x, y); /* Absolute integer value of compare. */ - m32 = -(uint32_t)(i32 < 0); + m32 = (uint32_t)-(i32 < 0); return (int32_t)(((uint32_t)i32 + m32) ^ m32); } From f892ef1fcab1805811de1e5c5f13182645fbc72b Mon Sep 17 00:00:00 2001 From: taloz5 <122386516+taloz5@users.noreply.github.com> Date: Sun, 15 Jan 2023 13:51:42 +0200 Subject: [PATCH 097/106] Avoid false detection of Clang while using Clang-cl --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3bbfe252d..492ec8bca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -171,7 +171,7 @@ message(STATUS "lib install dir ${dist_dir}/${lib_dir}") # and constants should be turned off - those are plentiful. They are # silenced for Clang, GCC and MSVC in generated headers.headers. -if (CMAKE_C_COMPILER_ID MATCHES "Clang") +if (CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC") # Clang or AppleClang message(STATUS "Setting Clang compiler options") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wstrict-prototypes") From 17cc4304d80145a5e70911687f646e76834cb99e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?= Date: Fri, 28 Apr 2023 09:05:03 +0200 Subject: [PATCH 098/106] Install required gcc version in weekly CI for macOS gcc-9 was removed from Githubs macOS runner via: https://github.com/actions/runner-images/issues/7136 Adds a prepare step which installs required gcc version. --- .github/workflows/weekly.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/weekly.yml b/.github/workflows/weekly.yml index d88903f66..a46f27502 100644 --- a/.github/workflows/weekly.yml +++ b/.github/workflows/weekly.yml @@ -148,6 +148,9 @@ jobs: gcc-version: [9, 12] steps: - uses: actions/checkout@v3 + - name: Prepare + run: | + brew install gcc@${{ matrix.gcc-version }} - name: Build and run tests env: CC: gcc-${{ matrix.gcc-version }} From 05295db85a7c15fd0983b918fc8efddb9b1b5519 Mon Sep 17 00:00:00 2001 From: mikkelfj Date: Tue, 15 Aug 2023 17:11:19 +0200 Subject: [PATCH 099/106] Fix regression on root scope when setting empty namespace --- src/compiler/parser.c | 5 +++-- src/compiler/parser.h | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/compiler/parser.c b/src/compiler/parser.c index 4f31e0b95..e6a9bc99b 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -1069,7 +1069,7 @@ static void parse_namespace(fb_parser_t *P) if (optional(P, ';') && t) { /* Revert to global namespace. */ - P->current_scope = 0; + P->current_scope = P->root_scope; return; } if (P->token->id != LEX_TOK_ID) { @@ -1436,7 +1436,8 @@ int fb_init_parser(fb_parser_t *P, fb_options_t *opts, const char *name, P->schema.prefix.s = (char *)opts->ns; P->schema.prefix.len = (int)strlen(opts->ns); } - P->current_scope = fb_add_scope(P, 0); + P->root_scope = fb_add_scope(P, 0); + P->current_scope = P->root_scope; assert(P->current_scope == fb_scope_table_find(&P->schema.root_schema->scope_index, 0, 0)); return 0; } diff --git a/src/compiler/parser.h b/src/compiler/parser.h index ef2ecc15a..f09337fe2 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -71,6 +71,7 @@ struct fb_parser { int has_schema; fb_options_t opts; fb_schema_t schema; + fb_scope_t *root_scope; fb_scope_t *current_scope; char *path; char *referer_path; From eb5228f76d395bffe31a33398ff73e60dfba5914 Mon Sep 17 00:00:00 2001 From: mikkelfj Date: Tue, 15 Aug 2023 17:17:59 +0200 Subject: [PATCH 100/106] Update CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ff4a4a95..3cd18d4bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ - Increase maximum allowed schema file size from 64 KiB to 1 MB (#256). - Fix seg fault in json parser while adding null characters to a too short input string for a fixed length char array struct field (#257). +- Fix regression where empty namespace in schema does not reset root scope + correctly in parser (#265). ## [0.6.1] From fcaec3543913960cb4038ca96c9f800c5ead8c7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Svensson?= Date: Wed, 4 Oct 2023 15:44:29 +0200 Subject: [PATCH 101/106] Update the apt key for Intel compilers in weekly CI Download the recommended keyfile for Intels APT repository and replace the deprecated `apt-key` command with `gpg`. `apt-key` has security flaws and will be removed after Ubuntu 22.04. --- .github/workflows/weekly.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/weekly.yml b/.github/workflows/weekly.yml index a46f27502..ba78294e4 100644 --- a/.github/workflows/weekly.yml +++ b/.github/workflows/weekly.yml @@ -112,8 +112,10 @@ jobs: steps: - name: Prepare run: | - wget -qO - https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB | sudo apt-key add - - echo "deb https://apt.repos.intel.com/oneapi all main" | sudo tee /etc/apt/sources.list.d/oneAPI.list + wget -O- https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB | \ + gpg --dearmor | sudo tee /usr/share/keyrings/oneapi-archive-keyring.gpg > /dev/null + echo "deb [signed-by=/usr/share/keyrings/oneapi-archive-keyring.gpg] https://apt.repos.intel.com/oneapi all main" | \ + sudo tee /etc/apt/sources.list.d/oneAPI.list sudo apt update sudo apt install intel-oneapi-compiler-dpcpp-cpp-and-cpp-classic-2021.4.0 - name: Setup Intel oneAPI From 7455d13c128f80841974110925b18aa9bd9cc6ef Mon Sep 17 00:00:00 2001 From: mikkelfj Date: Thu, 12 Oct 2023 15:34:53 +0200 Subject: [PATCH 102/106] Add missing unsigned cast to lexer character tests --- external/lex/luthor.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/external/lex/luthor.c b/external/lex/luthor.c index fc81985f3..5f037d726 100644 --- a/external/lex/luthor.c +++ b/external/lex/luthor.c @@ -176,16 +176,16 @@ static const char lex_alnum[256] = { #endif #ifndef lex_isdigit -#define lex_isdigit(c) ((c) >= '0' && (c) <= '9') +#define lex_isdigit(c) ((unsigned)(c) >= '0' && (unsigned)(c) <= '9') #endif #ifndef lex_ishexdigit -#define lex_ishexdigit(c) (((c) >= '0' && (c) <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'f')) +#define lex_ishexdigit(c) (((c) >= '0' && ((unsigned)c) <= '9') || ((unsigned)(c | 0x20) >= 'a' && (unsigned)(c | 0x20) <= 'f')) #endif #ifndef lex_isctrl #include -#define lex_isctrl(c) ((c) < 0x20 || (c) == 0x7f) +#define lex_isctrl(c) (((unsigned)c) < 0x20 || (c) == 0x7f) #endif #ifndef lex_isblank From 29aa9b2d2e1286a1ff852c1067db1fdbbd38760e Mon Sep 17 00:00:00 2001 From: mikkelfj Date: Thu, 12 Oct 2023 15:35:32 +0200 Subject: [PATCH 103/106] Fix utf-8 mistaken for ctrl chars in comments --- src/compiler/parser.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/compiler/parser.c b/src/compiler/parser.c index e6a9bc99b..76a720258 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -155,8 +155,6 @@ void error_ref_sym(fb_parser_t *P, fb_ref_t *ref, const char *msg, fb_symbol_t * /* Accept numbers like -0x42 as integer literals. */ #define LEX_HEX_NUMERIC -#define lex_isblank(c) ((c) == ' ' || (c) == '\t') - #include "parser.h" #ifdef LEX_DEBUG @@ -1335,10 +1333,10 @@ static void inject_token(fb_token_t *t, const char *lex, long id) push_token((fb_parser_t*)context, LEX_TOK_COMMENT_UNTERMINATED, pos, pos) #define lex_emit_comment_ctrl(pos) \ - if (lex_isblank(*pos)) { \ + if (lex_isblank(*pos) || !lex_isctrl(*pos)) { \ push_comment((fb_parser_t*)context, pos, pos + 1); \ } else { \ - push_token((fb_parser_t*)context, LEX_TOK_COMMENT_CTRL, \ + push_token((fb_parser_t*)context, LEX_TOK_CTRL, \ pos, pos + 1); \ } From aefd0c8d56f6b24bbd4edb27f3f57cce4cd7cd0a Mon Sep 17 00:00:00 2001 From: mikkelfj Date: Thu, 12 Oct 2023 15:41:01 +0200 Subject: [PATCH 104/106] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cd18d4bf..d2d701c3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ short input string for a fixed length char array struct field (#257). - Fix regression where empty namespace in schema does not reset root scope correctly in parser (#265). +- Fix lexer checks that breaks with UTF-8, notably UTF-8 schema comments (#267). ## [0.6.1] From d53371009403012565746127fdfe3ee6a226c316 Mon Sep 17 00:00:00 2001 From: mikkelfj Date: Mon, 23 Oct 2023 17:52:30 +0200 Subject: [PATCH 105/106] Avoid uninitialized scope prefix leading to UB on memcpy, though len is 0 --- CHANGELOG.md | 1 + src/compiler/parser.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2d701c3f..ec7bece8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ - Fix regression where empty namespace in schema does not reset root scope correctly in parser (#265). - Fix lexer checks that breaks with UTF-8, notably UTF-8 schema comments (#267). +- Fix UB in memcpy(p, 0, 0) by initializing scope prefix (mostly to silence sanitizers). ## [0.6.1] diff --git a/src/compiler/parser.c b/src/compiler/parser.c index 76a720258..88c946132 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -1430,6 +1430,8 @@ int fb_init_parser(fb_parser_t *P, fb_options_t *opts, const char *name, P->schema.name.name.s.s = s; P->schema.name.name.s.len = (int)n; checkmem((P->schema.errorname = fb_create_basename(name, name_len, ""))); + P->schema.prefix.s = ""; + P->schema.prefix.len = 0; if (opts->ns) { P->schema.prefix.s = (char *)opts->ns; P->schema.prefix.len = (int)strlen(opts->ns); From 0e925e103529f1a76ba84f8f68e8a2cc4510393e Mon Sep 17 00:00:00 2001 From: mikkelfj Date: Tue, 24 Oct 2023 16:19:34 +0200 Subject: [PATCH 106/106] Add clang debug sanitizer flag and fix related warnings --- CHANGELOG.md | 2 +- CMakeLists.txt | 4 ++++ src/compiler/parser.c | 1 - src/runtime/builder.c | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec7bece8f..c9acb87e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,7 @@ - Fix regression where empty namespace in schema does not reset root scope correctly in parser (#265). - Fix lexer checks that breaks with UTF-8, notably UTF-8 schema comments (#267). -- Fix UB in memcpy(p, 0, 0) by initializing scope prefix (mostly to silence sanitizers). +- Add sanitizer flag for clang debug and related warnings (input from several PRs incl. #237) ## [0.6.1] diff --git a/CMakeLists.txt b/CMakeLists.txt index 492ec8bca..ace0368e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -188,6 +188,10 @@ if (CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT "${CMAKE_CXX_SIMULATE_ID}" STREQ if (FLATCC_IGNORE_CONST_COND) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-tautological-constant-out-of-range-compare") endif() + if (CMAKE_BUILD_TYPE MATCHES Debug) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined") + endif() # Suppress warning relaxed in clang-6, see https://reviews.llvm.org/D28148 if (CMAKE_C_COMPILER_VERSION VERSION_LESS 6) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-field-initializers") diff --git a/src/compiler/parser.c b/src/compiler/parser.c index 88c946132..006bb86f0 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -1270,7 +1270,6 @@ static void push_token(fb_parser_t *P, long id, const char *first, const char *l size_t offset; fb_token_t *t; - P->te = P->ts + P->tcapacity; if (P->token == P->te) { offset = (size_t)(P->token - P->ts); P->tcapacity = P->tcapacity ? 2 * P->tcapacity : 1024; diff --git a/src/runtime/builder.c b/src/runtime/builder.c index b62c2b667..1e5f8164a 100644 --- a/src/runtime/builder.c +++ b/src/runtime/builder.c @@ -177,7 +177,7 @@ int flatcc_builder_default_alloc(void *alloc_context, iovec_t *b, size_t request return 0; } -#define T_ptr(base, pos) ((void *)((uint8_t *)(base) + (uoffset_t)(pos))) +#define T_ptr(base, pos) ((void *)((size_t)(base) + (size_t)(pos))) #define ds_ptr(pos) (T_ptr(B->buffers[flatcc_builder_alloc_ds].iov_base, (pos))) #define vs_ptr(pos) (T_ptr(B->buffers[flatcc_builder_alloc_vs].iov_base, (pos))) #define pl_ptr(pos) (T_ptr(B->buffers[flatcc_builder_alloc_pl].iov_base, (pos)))