Skip to content

Commit

Permalink
lcmgen: Emit file level comments
Browse files Browse the repository at this point in the history
Parse any comment before the `package` statement in the .lcm file
and apply it to the top of generated source files right after the
'generated with LCM' statement.

Does not apply if the package is defined via CLI flags.

Implemented for:
- [x] c
- [x] cpp
- [x] java
- [x] python
- [ ] go
- [ ] lua
- [ ] c#

See test/types/lcmtest/comments_t.lcm and
build/test/types/lcmtest/comments_t.*
  • Loading branch information
judfs authored and nosracd committed Sep 22, 2024
1 parent f18f8a6 commit 0aab43e
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 120 deletions.
118 changes: 60 additions & 58 deletions lcmgen/emit_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,62 +100,6 @@ static const char *map_type_name(const char *type_name)
return dots_to_underscores(type_name);
}

void setup_c_options(getopt_t *gopt)
{
getopt_add_string(gopt, 0, "c-cpath", ".", "Location for .c files");
getopt_add_string(gopt, 0, "c-hpath", ".", "Location for .h files");
getopt_add_string(gopt, 0, "c-export-include", "", "#include that provides the export symbol");
getopt_add_string(gopt, 0, "c-export-symbol", "", "ABI export decoration symbol");
getopt_add_string(gopt, 0, "cinclude", "", "Generated #include lines reference this folder");
getopt_add_bool(gopt, 0, "c-no-pubsub", 0, "Do not generate _publish and _subscribe functions");
getopt_add_bool(gopt, 0, "c-typeinfo", 0, "Generate typeinfo functions for each type");
}

/** Emit output that is common to every header file **/
static void emit_header_top(lcmgen_t *lcm, FILE *f, char *name)
{
emit_auto_generated_warning(f);

fprintf(f, "#ifndef _%s_h\n", name);
fprintf(f, "#define _%s_h\n", name);
fprintf(f, "\n");

fprintf(f, "#include <stdint.h>\n");
fprintf(f, "#include <stdlib.h>\n");
if (getopt_get_bool(lcm->gopt, "use-quotes-for-includes"))
fprintf(f, "#include \"lcm/lcm_coretypes.h\"\n");
else
fprintf(f, "#include <lcm/lcm_coretypes.h>\n");

if (!getopt_get_bool(lcm->gopt, "c-no-pubsub")) {
if (getopt_get_bool(lcm->gopt, "use-quotes-for-includes"))
fprintf(f, "#include \"lcm/lcm.h\"\n");
else
fprintf(f, "#include <lcm/lcm.h>\n");
}
if (strlen(getopt_get_string(lcm->gopt, "c-export-include"))) {
fprintf(f, "#include \"%s%s%s\"\n", getopt_get_string(lcm->gopt, "cinclude"),
strlen(getopt_get_string(lcm->gopt, "cinclude")) > 0 ? "/" : "",
getopt_get_string(lcm->gopt, "c-export-include"));
}
fprintf(f, "\n");

fprintf(f, "#ifdef __cplusplus\n");
fprintf(f, "extern \"C\" {\n");
fprintf(f, "#endif\n");
fprintf(f, "\n");
}

/** Emit output that is common to every header file **/
static void emit_header_bottom(lcmgen_t *lcm, FILE *f)
{
fprintf(f, "#ifdef __cplusplus\n");
fprintf(f, "}\n");
fprintf(f, "#endif\n");
fprintf(f, "\n");
fprintf(f, "#endif\n");
}

static void emit_type_comment(FILE *f, lcm_member_t *structure_member)
{
/* Might be nicer to construct a string. Eh. */
Expand Down Expand Up @@ -234,6 +178,63 @@ static void emit_comment(FILE *f, int indent, const char *comment)
g_strfreev(lines);
}

void setup_c_options(getopt_t *gopt)
{
getopt_add_string(gopt, 0, "c-cpath", ".", "Location for .c files");
getopt_add_string(gopt, 0, "c-hpath", ".", "Location for .h files");
getopt_add_string(gopt, 0, "c-export-include", "", "#include that provides the export symbol");
getopt_add_string(gopt, 0, "c-export-symbol", "", "ABI export decoration symbol");
getopt_add_string(gopt, 0, "cinclude", "", "Generated #include lines reference this folder");
getopt_add_bool(gopt, 0, "c-no-pubsub", 0, "Do not generate _publish and _subscribe functions");
getopt_add_bool(gopt, 0, "c-typeinfo", 0, "Generate typeinfo functions for each type");
}

/** Emit output that is common to every header file **/
static void emit_header_top(lcmgen_t *lcm, FILE *f, char *name, char *file_comment)
{
emit_auto_generated_warning(f);
emit_comment(f, 0, file_comment);

fprintf(f, "#ifndef _%s_h\n", name);
fprintf(f, "#define _%s_h\n", name);
fprintf(f, "\n");

fprintf(f, "#include <stdint.h>\n");
fprintf(f, "#include <stdlib.h>\n");
if (getopt_get_bool(lcm->gopt, "use-quotes-for-includes"))
fprintf(f, "#include \"lcm/lcm_coretypes.h\"\n");
else
fprintf(f, "#include <lcm/lcm_coretypes.h>\n");

if (!getopt_get_bool(lcm->gopt, "c-no-pubsub")) {
if (getopt_get_bool(lcm->gopt, "use-quotes-for-includes"))
fprintf(f, "#include \"lcm/lcm.h\"\n");
else
fprintf(f, "#include <lcm/lcm.h>\n");
}
if (strlen(getopt_get_string(lcm->gopt, "c-export-include"))) {
fprintf(f, "#include \"%s%s%s\"\n", getopt_get_string(lcm->gopt, "cinclude"),
strlen(getopt_get_string(lcm->gopt, "cinclude")) > 0 ? "/" : "",
getopt_get_string(lcm->gopt, "c-export-include"));
}
fprintf(f, "\n");

fprintf(f, "#ifdef __cplusplus\n");
fprintf(f, "extern \"C\" {\n");
fprintf(f, "#endif\n");
fprintf(f, "\n");
}

/** Emit output that is common to every header file **/
static void emit_header_bottom(lcmgen_t *lcm, FILE *f)
{
fprintf(f, "#ifdef __cplusplus\n");
fprintf(f, "}\n");
fprintf(f, "#endif\n");
fprintf(f, "\n");
fprintf(f, "#endif\n");
}

/** Emit header file output specific to a particular type of struct. **/
static void emit_header_struct(lcmgen_t *lcm, FILE *f, lcm_struct_t *structure)
{
Expand Down Expand Up @@ -1087,7 +1088,7 @@ int emit_enum(lcmgen_t *lcmgen, lcm_enum_t *enumeration)
if (f == NULL)
return -1;

emit_header_top(lcmgen, f, type_name);
emit_header_top(lcmgen, f, type_name, NULL);

char *tn_upper = g_ascii_strup(type_name, strlen(type_name));

Expand Down Expand Up @@ -1278,7 +1279,7 @@ int emit_struct(lcmgen_t *lcmgen, lcm_struct_t *structure)
if (f == NULL)
return -1;

emit_header_top(lcmgen, f, type_name);
emit_header_top(lcmgen, f, type_name, structure->file_comment);
emit_header_struct(lcmgen, f, structure);
emit_header_prototypes(lcmgen, f, structure);

Expand All @@ -1293,6 +1294,7 @@ int emit_struct(lcmgen_t *lcmgen, lcm_struct_t *structure)
return -1;

emit_auto_generated_warning(f);
emit_comment(f, 0, structure->file_comment);
fprintf(f, "#include <string.h>\n");
fprintf(f, "#include \"%s%s%s.h\"\n", getopt_get_string(lcmgen->gopt, "cinclude"),
strlen(getopt_get_string(lcmgen->gopt, "cinclude")) > 0 ? "/" : "", type_name);
Expand Down
31 changes: 16 additions & 15 deletions lcmgen/emit_cpp.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ static void emit_header_start(lcmgen_t *lcmgen, FILE *f, lcm_struct_t *structure
char *tn_ = dots_to_underscores(tn);

emit_auto_generated_warning(f);
emit_comment(f, 0, structure->file_comment);

fprintf(f, "#ifndef __%s_hpp__\n", tn_);
fprintf(f, "#define __%s_hpp__\n", tn_);
Expand Down Expand Up @@ -847,9 +848,9 @@ int emit_cpp(lcmgen_t *lcmgen)
{
// iterate through all defined message types
for (unsigned int i = 0; i < g_ptr_array_size(lcmgen->structs); i++) {
lcm_struct_t *lr = (lcm_struct_t *) g_ptr_array_index(lcmgen->structs, i);
lcm_struct_t *structure = (lcm_struct_t *) g_ptr_array_index(lcmgen->structs, i);

const char *tn = lr->structname->lctypename;
const char *tn = structure->structname->lctypename;
char *tn_ = dots_to_slashes(tn);

// compute the target filename
Expand All @@ -858,33 +859,33 @@ int emit_cpp(lcmgen_t *lcmgen)
strlen(getopt_get_string(lcmgen->gopt, "cpp-hpath")) > 0 ? G_DIR_SEPARATOR_S : "", tn_);

// generate code if needed
if (lcm_needs_generation(lcmgen, lr->lcmfile, header_name)) {
if (lcm_needs_generation(lcmgen, structure->lcmfile, header_name)) {
make_dirs_for_file(header_name);

FILE *f = fopen(header_name, "w");
if (f == NULL)
return -1;

emit_header_start(lcmgen, f, lr);
emit_encode(lcmgen, f, lr);
emit_decode(lcmgen, f, lr);
emit_encoded_size(lcmgen, f, lr);
emit_get_hash(lcmgen, f, lr);
emit_header_start(lcmgen, f, structure);
emit_encode(lcmgen, f, structure);
emit_decode(lcmgen, f, structure);
emit_encoded_size(lcmgen, f, structure);
emit_get_hash(lcmgen, f, structure);

// clang-format off
emit(0, "const char* %s::getTypeName()", lr->structname->shortname);
emit(0, "const char* %s::getTypeName()", structure->structname->shortname);
emit(0, "{");
emit(1, "return \"%s\";", lr->structname->shortname);
emit(1, "return \"%s\";", structure->structname->shortname);
emit(0, "}");
emit(0, "");
// clang-format on

emit_encode_nohash(lcmgen, f, lr);
emit_decode_nohash(lcmgen, f, lr);
emit_encoded_size_nohash(lcmgen, f, lr);
emit_compute_hash(lcmgen, f, lr);
emit_encode_nohash(lcmgen, f, structure);
emit_decode_nohash(lcmgen, f, structure);
emit_encoded_size_nohash(lcmgen, f, structure);
emit_compute_hash(lcmgen, f, structure);

emit_package_namespace_close(lcmgen, f, lr);
emit_package_namespace_close(lcmgen, f, structure);
emit(0, "#endif");

fclose(f);
Expand Down
2 changes: 1 addition & 1 deletion lcmgen/emit_go.c
Original file line number Diff line number Diff line change
Expand Up @@ -1556,7 +1556,7 @@ int emit_go(lcmgen_t *lcm)
goto ret;
}

if (!strlen(lcm->package)) {
if (!strlen(lcm->parse_cache.package)) {
fprintf(stderr, "Not yet implemented: go-default-package\n");
res = -1;
goto ret;
Expand Down
1 change: 1 addition & 0 deletions lcmgen/emit_java.c
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,7 @@ int emit_java(lcmgen_t *lcm)
" * lcm-gen " LCM_VERSION_STRING
"\n"
" */\n");
emit_comment(f, 0, structure->file_comment);

if (strlen(structure->structname->package) > 0)
emit(0, "package %s;", structure->structname->package);
Expand Down
5 changes: 5 additions & 0 deletions lcmgen/emit_python.c
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,11 @@ emit_package (lcmgen_t *lcm, _package_contents_t *package)
"This file automatically generated by lcm.\n"
"DO NOT MODIFY BY HAND!!!!\n"
"\"\"\"\n"
"\n");

emit_comment(f, 0, structure->file_comment);

fprintf(f,
"\n"
"from io import BytesIO\n"
"import struct\n\n");
Expand Down
Loading

0 comments on commit 0aab43e

Please sign in to comment.