diff --git a/src/compiler/codegen_c_reader.c b/src/compiler/codegen_c_reader.c index fb5994bce..751b62867 100644 --- a/src/compiler/codegen_c_reader.c +++ b/src/compiler/codegen_c_reader.c @@ -1252,6 +1252,7 @@ static void gen_struct(fb_output_t *out, fb_compound_type_t *ct) fprintf(out->fp, " uint8_t __padding%u[%u];\n", pad_index, pad); } + print_doc(out, " ", ct->trailing_doc); fprintf(out->fp, "};\n"); if (do_pad) { fprintf(out->fp, "#pragma pack()\n"); diff --git a/src/compiler/parser.c b/src/compiler/parser.c index 45b5c9da2..272673a77 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -1063,6 +1063,11 @@ static void parse_compound_type(fb_parser_t *P, fb_compound_type_t *ct, long tok goto fail; } } + if (ct->symbol.kind == fb_is_struct) { + revert_symbols(&P->doc); + ct->trailing_doc = P->doc; + } + P->doc = 0; if (!optional(P, '}') && t) { error_tok_2(P, P->token, "Declaration missing closing '}' to match", t); } diff --git a/src/compiler/symbols.h b/src/compiler/symbols.h index 075206806..50d9b6d14 100644 --- a/src/compiler/symbols.h +++ b/src/compiler/symbols.h @@ -265,6 +265,7 @@ struct fb_compound_type { fb_member_t *primary_key; fb_metadata_t *metadata; fb_doc_t *doc; + fb_doc_t *trailing_doc; fb_value_t type; fb_symbol_table_t index; /* Only for enums. */ diff --git a/test/cgen_test/cgen_test.c b/test/cgen_test/cgen_test.c index 6d58ed1a9..33b9efee8 100644 --- a/test/cgen_test/cgen_test.c +++ b/test/cgen_test/cgen_test.c @@ -1,7 +1,7 @@ /* - * Parse and verify schema complex nonsense schema, then generate common - * and schema specific files for reader and builder, all outfileenated to - * stdout, followed by the schema source in a comment. + * Parse and verify a complex schema, generate reader and builder C code + * to a temporary file, check doc-comment placement, then write the + * generated code and schema source to stdout. * * Notes: * @@ -38,8 +38,10 @@ * */ #include +#include #include #include "flatcc/flatcc.h" +#include "flatcc/support/readfile.h" int main(void) { @@ -72,6 +74,18 @@ int main(void) "struct shade (force_align:2) { x: byte; y: byte; z: byte;\n" "/// alpha is unsigned!\n" "alpha: ubyte (key); }\n" + "struct comment_source { value: int;\n" + "/// trailing_doc_comment_should_be_kept\n" + "/// second_trailing_doc_comment_should_be_kept\n" + "}\n" + "/// following_type_doc_should_remain\n" + "struct comment_target { value: int; }\n" + "table comment_table { value: int;\n" + "/// drop table comment\n" + "}\n" + "union comment_union { point,\n" + "/// drop union comment\n" + "}\n" "/// the.ui is a union\n" "///\n" "/// We got one blank comment line above.\n" @@ -126,14 +140,17 @@ int main(void) flatcc_options_t opts; flatcc_context_t ctx = 0; + char *output = 0, *resized_output; + size_t output_size = 0; int ret = -1; + const char *outfile = "cgen_test_output.tmp"; flatcc_init_options(&opts); opts.cgen_common_reader = 1; opts.cgen_reader = 1; opts.cgen_common_builder = 1; opts.cgen_builder = 1; - opts.gen_stdout = 1; + opts.gen_outfile = outfile; /* The basename xyzzy is derived from path. */ if (!(ctx = flatcc_create_context(&opts, name, 0, 0))) { @@ -150,6 +167,40 @@ int main(void) fprintf(stderr, "failed to generate output for C\n"); goto done; }; + if (!(output = readfile(outfile, 0, &output_size))) { + fprintf(stderr, "failed to read generated output for C\n"); + goto done; + } + if (!(resized_output = (char *)realloc(output, output_size + 1))) { + fprintf(stderr, "failed to allocate generated output buffer\n"); + goto done; + } + output = resized_output; + output[output_size] = '\0'; + if (!strstr(output, + "struct the_comment_source {\n" + " alignas(4) int32_t value;\n" + " /** trailing_doc_comment_should_be_kept\n" + " * second_trailing_doc_comment_should_be_kept */\n" + "};")) { + fprintf(stderr, "trailing struct doc comments were not kept inside comment_source\n"); + goto done; + } + if (!strstr(output, + "/** following_type_doc_should_remain */\n" + "struct the_comment_target {")) { + fprintf(stderr, "doc comment after closing brace was not attached to comment_target\n"); + goto done; + } + if (strstr(output, "drop table comment") || + strstr(output, "drop union comment")) { + fprintf(stderr, "trailing table or union doc comments were unexpectedly emitted\n"); + goto done; + } + if (fwrite(output, 1, output_size, stdout) != output_size) { + fprintf(stderr, "failed to write generated output to stdout\n"); + goto done; + } fprintf(stdout, "\n#if 0 /* FlatBuffers Schema Source */\n" "%s\n" @@ -158,6 +209,8 @@ int main(void) } ret = 0; done: + free(output); + remove(outfile); flatcc_destroy_context(ctx); return ret; }