Skip to content

Commit

Permalink
https://github.com/eclipse-cyclonedds/cyclonedds/issues/2123
Browse files Browse the repository at this point in the history
- Create branch issue-2123-add-deepcopy-func from master @ d8cef89
- Work in progress, build currently fails on compiling
  CdrStreamOptimize.c generated for src/core/ddsc/tests/
  CdrStreamOptimize.idl.

src/idl/include/idl/tree.h
src/idl/src/tree.c
- Add function idl_is_scalar_type.

src/core/ddsc/include/dds/ddsc/dds_public_alloc.h
- Add defines for __alloc functions of primitive types.

src/tools/idlc/src/libidlc/libidlc__generator.c
- In function print_includes add generation of #include <string.h> for
  strcat() / strcpy() required by libidlc__types.c emit_struct() added
  generation of _copy function.

src/tools/idlc/src/libidlc/libidlc__types.c
- In various emit() functions remove superfluous ending semicolon in
  generated __alloc() macros.
- In function emit_implicit_sequence add generation of _copy function.
- In function emit_struct start adding generation of _copy function.
  Generation for @optional and @external members is work in progress
  and struct supertypes have not yet been considered.
  Also, have not started adding _copy generation in emit_union().
  • Loading branch information
Oliver Kellogg committed Nov 5, 2024
1 parent d8cef89 commit 58033b8
Show file tree
Hide file tree
Showing 5 changed files with 216 additions and 24 deletions.
14 changes: 14 additions & 0 deletions src/core/ddsc/include/dds/ddsc/dds_public_alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,20 @@ DDS_EXPORT void dds_string_free (char * str);
*/
DDS_EXPORT void dds_sample_free (void * sample, const struct dds_topic_descriptor * desc, dds_free_op_t op);

#define bool__alloc() (bool *)dds_alloc(sizeof(bool))
#define char__alloc() (char *)dds_alloc(sizeof(char))
#define octet__alloc() (octet *)dds_alloc(sizeof(octet))
#define int8_t__alloc() (int8_t *)dds_alloc(sizeof(int8_t))
#define uint8_t__alloc() (uint8_t *)dds_alloc(sizeof(uint8_t))
#define int16_t__alloc() (int16_t *)dds_alloc(sizeof(int16_t))
#define uint16_t__alloc() (uint16_t *)dds_alloc(sizeof(uint16_t))
#define int32_t__alloc() (int32_t *)dds_alloc(sizeof(int32_t))
#define uint32_t__alloc() (uint32_t *)dds_alloc(sizeof(uint32_t))
#define int64_t__alloc() (int64_t *)dds_alloc(sizeof(int64_t))
#define uint64_t__alloc() (uint64_t *)dds_alloc(sizeof(uint64_t))
#define float__alloc() (float *)dds_alloc(sizeof(float))
#define double__alloc() (double *)dds_alloc(sizeof(double))

#if defined (__cplusplus)
}
#endif
Expand Down
3 changes: 2 additions & 1 deletion src/idl/include/idl/tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
contain the result from an expression, pragmas contain compiler-specific
instructions that apply to a specific declaration, much like annotations.
the exact type of a node is stored in the mask property of the base node
and is an constructed by combining preprocessor defines. unique bits are
and is constructed by combining preprocessor defines. unique bits are
reserved for categories and properties that generators are likely to filter
on when applying a visitor pattern. */

Expand Down Expand Up @@ -522,6 +522,7 @@ IDL_EXPORT bool idl_is_type_spec(const void *node);
IDL_EXPORT bool idl_is_base_type(const void *node);
IDL_EXPORT bool idl_is_floating_pt_type(const void *node);
IDL_EXPORT bool idl_is_integer_type(const void *node);
IDL_EXPORT bool idl_is_scalar_type(const void *node);
IDL_EXPORT bool idl_is_templ_type(const void *node);
IDL_EXPORT bool idl_is_bounded(const void *node);
IDL_EXPORT bool idl_is_sequence(const void *node);
Expand Down
17 changes: 17 additions & 0 deletions src/idl/src/tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,23 @@ bool idl_is_integer_type(const void *node)
return (idl_mask(node) & IDL_INTEGER_TYPE) != 0;
}

bool idl_is_scalar_type(const void *node)
{
idl_mask_t mask;
if (idl_mask(node) & IDL_DECLARATOR)
node = idl_parent(node);
mask = idl_mask(node);
if (mask & (IDL_BASE_TYPE|IDL_ENUM|IDL_ENUMERATOR|IDL_BITMASK))
return (mask != IDL_ANY);
if (!(mask & IDL_TYPEDEF))
return false;
{
idl_typedef_t *_typedef = (idl_typedef_t*) node;
void *type_spec = idl_unalias(_typedef->type_spec);
return idl_is_scalar_type(type_spec);
}
}

static void delete_base_type(void *ptr)
{
idl_free(ptr);
Expand Down
2 changes: 2 additions & 0 deletions src/tools/idlc/src/libidlc/libidlc__generator.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ static idl_retcode_t print_includes(FILE *fh, const idl_source_t *source)
return IDL_RETCODE_NO_MEMORY;
}

if (fputs("#include <string.h>\n\n", fh) < 0)
return IDL_RETCODE_NO_MEMORY;
return IDL_RETCODE_OK;
}

Expand Down
204 changes: 181 additions & 23 deletions src/tools/idlc/src/libidlc/libidlc__types.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,47 @@ emit_implicit_sequence(
" bool _release;\n"
"} %2$s;\n\n"
"#define %2$s__alloc() \\\n"
"((%2$s*) dds_alloc (sizeof (%2$s)));\n\n"
"((%2$s*) dds_alloc (sizeof (%2$s)))\n\n"
"#define %2$s_allocbuf(l) \\\n"
"((%3$s%4$s %5$s%6$s*%7$s%8$s) dds_alloc ((l) * sizeof (%3$s%4$s%5$s%8$s)))\n"
"#endif /* %1$s_DEFINED */\n\n";
"((%3$s%4$s %5$s%6$s*%7$s%8$s) dds_alloc ((l) * sizeof (%3$s%4$s%5$s%8$s)))\n";
if (idl_fprintf(gen->header.handle, fmt, macro, name, type_prefix, type, star, lpar, rpar, dims) < 0)
return IDL_RETCODE_NO_MEMORY;

/* generate function _copy() */
if (gen->config.export_macro && idl_fprintf(gen->header.handle, "%1$s ", gen->config.export_macro) < 0)
return IDL_RETCODE_NO_MEMORY;
fmt = "extern void %1$s_copy(%1$s *d, const %1$s *s);\n\n";
if (idl_fprintf(gen->header.handle, fmt, name) < 0)
return IDL_RETCODE_NO_MEMORY;
fmt = "void %1$s_copy(%1$s *d, const %1$s *s) {\n";
if (idl_fprintf(gen->source.handle, fmt, name) < 0)
return IDL_RETCODE_NO_MEMORY;
fmt = /* " size_t elemsize = sizeof (%1$s%2$s);\n" */
" %1$s%2$s *dptr = %3$s_allocbuf(s->_maximum);\n"
" const %1$s%2$s *sptr = (const %1$s%2$s *)s->_buffer;\n"
" d->_maximum = s->_maximum;\n"
" d->_length = s->_length;\n"
" d->_release = true;\n"
" d->_buffer = dptr;\n"
" for (unsigned i = 0; i < s->_length; i++) {\n";
if (idl_fprintf(gen->source.handle, fmt, type_prefix, type, name) < 0)
return IDL_RETCODE_NO_MEMORY;
if (idl_is_scalar_type(type_spec)) {
if (idl_fprintf(gen->source.handle, " *(dptr + i) = *(sptr + i);\n") < 0)
return IDL_RETCODE_NO_MEMORY;
} else {
fmt = " %1$s_copy(dptr + i, sptr + i);\n";
if (idl_fprintf(gen->source.handle, fmt, type) < 0)
return IDL_RETCODE_NO_MEMORY;
}
if (idl_fprintf(gen->source.handle, " }\n") < 0)
return IDL_RETCODE_NO_MEMORY;
if (idl_fprintf(gen->source.handle, "}\n\n") < 0)
return IDL_RETCODE_NO_MEMORY;

if (idl_fprintf(gen->header.handle, "#endif /* %1$s_DEFINED */\n\n", macro) < 0)
return IDL_RETCODE_NO_MEMORY;

return IDL_VISIT_DONT_RECURSE;
}

Expand Down Expand Up @@ -221,6 +255,8 @@ emit_struct(
char *name = NULL;
const char *fmt;
bool empty = idl_is_empty(node);
const idl_struct_t *_struct = (const idl_struct_t *)node;
idl_member_t *members = _struct->members;

if (IDL_PRINTA(&name, print_type, node) < 0)
return IDL_RETCODE_NO_MEMORY;
Expand All @@ -231,36 +267,158 @@ emit_struct(
return IDL_RETCODE_NO_MEMORY;
if (!empty && idl_fprintf(gen->header.handle, "\n") < 0)
return IDL_RETCODE_NO_MEMORY;
if (!empty && idl_is_topic(node, (pstate->config.flags & IDL_FLAG_KEYLIST) != 0)) {
if (gen->config.export_macro && idl_fprintf(gen->header.handle, "%1$s ", gen->config.export_macro) < 0)
return IDL_RETCODE_NO_MEMORY;
fmt = "extern const dds_topic_descriptor_t %1$s_desc;\n"
"\n"
"#define %1$s__alloc() \\\n"
"((%1$s*) dds_alloc (sizeof (%1$s)));\n"
"\n"
"#define %1$s_free(d,o) \\\n"
"dds_sample_free ((d), &%1$s_desc, (o))\n"
if (!empty) {
fmt = "#define %1$s__alloc() \\\n"
"((%1$s*) dds_alloc (sizeof (%1$s)))\n"
"\n";
if (idl_fprintf(gen->header.handle, fmt, name) < 0)
return IDL_RETCODE_NO_MEMORY;
if (gen->config.generate_cdrstream_desc)
if (idl_is_topic(node, (pstate->config.flags & IDL_FLAG_KEYLIST) != 0)) {
if (gen->config.export_macro && idl_fprintf(gen->header.handle, "%1$s ", gen->config.export_macro) < 0)
return IDL_RETCODE_NO_MEMORY;
fmt = "extern const dds_topic_descriptor_t %1$s_desc;\n\n";
if (idl_fprintf(gen->header.handle, fmt, name) < 0)
return IDL_RETCODE_NO_MEMORY;
if (gen->config.export_macro && idl_fprintf(gen->header.handle, "%1$s ", gen->config.export_macro) < 0)
return IDL_RETCODE_NO_MEMORY;
fmt = "extern void %1$s_free(void *d, dds_free_op_t o);\n\n";
if (idl_fprintf(gen->header.handle, fmt, name) < 0)
return IDL_RETCODE_NO_MEMORY;
fmt = "void %1$s_free(void *d, dds_free_op_t o) {\n"
" dds_sample_free ((d), &%1$s_desc, (o));\n"
"}\n\n";
if (idl_fprintf(gen->source.handle, fmt, name) < 0)
return IDL_RETCODE_NO_MEMORY;
if (gen->config.generate_cdrstream_desc)
{
if (gen->config.export_macro && idl_fprintf(gen->header.handle, "%1$s ", gen->config.export_macro) < 0)
return IDL_RETCODE_NO_MEMORY;
fmt = "extern const struct dds_cdrstream_desc %1$s_cdrstream_desc;\n\n";
if (idl_fprintf(gen->header.handle, fmt, name) < 0)
return IDL_RETCODE_NO_MEMORY;
}
if ((ret = generate_descriptor(pstate, gen, node)))
return ret;
} else {
/* generate _free() */
if (gen->config.export_macro && idl_fprintf(gen->header.handle, "%1$s ", gen->config.export_macro) < 0)
return IDL_RETCODE_NO_MEMORY;
fmt = "extern void %1$s_free(void *d);\n\n";
if (idl_fprintf(gen->header.handle, fmt, name) < 0)
return IDL_RETCODE_NO_MEMORY;
fmt = "void %1$s_free(void *d) {\n";
if (idl_fprintf(gen->source.handle, fmt, name) < 0)
return IDL_RETCODE_NO_MEMORY;
if (idl_fprintf(gen->source.handle, " dds_free(d);\n") < 0)
return IDL_RETCODE_NO_MEMORY;
if (idl_fprintf(gen->source.handle, "}\n\n") < 0)
return IDL_RETCODE_NO_MEMORY;
}
{
/* generate _copy() */
idl_member_t *member;
if (gen->config.export_macro && idl_fprintf(gen->header.handle, "%1$s ", gen->config.export_macro) < 0)
return IDL_RETCODE_NO_MEMORY;
fmt = "extern const struct dds_cdrstream_desc %1$s_cdrstream_desc;\n\n";
fmt = "extern void %1$s_copy(%1$s *d, const %1$s *s);\n\n";
if (idl_fprintf(gen->header.handle, fmt, name) < 0)
return IDL_RETCODE_NO_MEMORY;
fmt = "void %1$s_copy(%1$s *d, const %1$s *s) {\n";
if (idl_fprintf(gen->source.handle, fmt, name) < 0)
return IDL_RETCODE_NO_MEMORY;
IDL_FOREACH(member, members) {
bool is_scalar = idl_is_scalar_type(member->type_spec);
bool is_string = idl_is_string(member->type_spec);
bool is_bounded = idl_is_bounded(member->type_spec);
bool is_external = idl_is_external((idl_node_t*)member);
bool is_optional = idl_is_optional((idl_node_t*)member);
bool is_pointer = is_external || is_optional;
idl_declarator_t *decl;
IDL_FOREACH(decl, member->declarators) {
const char *declname = decl->name->identifier;
unsigned dimindex = 0;
char dimbuf[64]; /* buffer for array index syntax */
dimbuf[0] = '\0';
if (is_pointer) {
char *membertype;
if (IDL_PRINTA(&membertype, print_type, member->type_spec) < 0)
return IDL_RETCODE_NO_MEMORY;
fmt = " if (s->%1$s == NULL) {\n"
" d->%1$s = NULL;\n"
" } else {\n"
" d->%1$s = %2$s__alloc();\n"
" }\n"
" if (d->%1$s) {\n";
if (idl_fprintf(gen->source.handle, fmt, declname, membertype) < 0)
return IDL_RETCODE_NO_MEMORY;
}
if (decl->const_expr) {
for (idl_const_expr_t *ce = decl->const_expr; ce; ce = idl_next(ce)) {
idl_literal_t const * const lit = ce;
char ndxbuf[16];
int res;
fmt = " for (unsigned i%1$u = 0; i%1$u < %2$u; i%1$u++) {\n";
if (idl_fprintf(gen->source.handle, fmt, dimindex, lit->value.uint32) < 0)
return IDL_RETCODE_NO_MEMORY;
res = snprintf(ndxbuf, sizeof(ndxbuf), "[i%u]", dimindex);
if (res < 0 || (size_t)res >= sizeof(ndxbuf))
return IDL_RETCODE_NO_MEMORY;
if (strlen(dimbuf) + strlen(ndxbuf) >= sizeof(dimbuf))
return IDL_RETCODE_NO_MEMORY;
strcat(dimbuf, ndxbuf);
++dimindex;
}
}
if (is_scalar) {
if (is_pointer) {
fmt = " *(d->%1$s%2$s) = *(s->%1$s%2$s);\n";
} else {
fmt = " d->%1$s%2$s = s->%1$s%2$s;\n";
}
if (idl_fprintf(gen->source.handle, fmt, declname, dimbuf) < 0)
return IDL_RETCODE_NO_MEMORY;
} else if (is_string) {
if (is_pointer) {
fmt = " *(d->%1$s%2$s = dds_string_dup(*(s->%1$s%2$s));\n";
} else if (is_bounded) {
fmt = " strcpy(d->%1$s%2$s, s->%1$s%2$s);\n";
} else {
fmt = " d->%1$s%2$s = dds_string_dup(s->%1$s%2$s);\n";
}
if (idl_fprintf(gen->source.handle, fmt, declname, dimbuf) < 0)
return IDL_RETCODE_NO_MEMORY;
} else {
char *membertype;
if (IDL_PRINTA(&membertype, print_type, member->type_spec) < 0)
return IDL_RETCODE_NO_MEMORY;
if (is_pointer) {
fmt = " %s_copy(&((*d)->%2$s%3$s), &((*s)->%2$s%3$s));\n";
} else {
fmt = " %s_copy(&(d->%2$s%3$s), &(s->%2$s%3$s));\n";
}
if (idl_fprintf(gen->source.handle, fmt, membertype, declname, dimbuf) < 0)
return IDL_RETCODE_NO_MEMORY;
}
for (unsigned i = 0; i < dimindex; i++) {
if (idl_fprintf(gen->source.handle, " }\n") < 0)
return IDL_RETCODE_NO_MEMORY;
}
if (is_optional) {
if (idl_fprintf(gen->source.handle, " } /* optional is non NULL */\n") < 0)
return IDL_RETCODE_NO_MEMORY;
} else if (is_external) {
if (idl_fprintf(gen->source.handle, " } /* external is non NULL */\n") < 0)
return IDL_RETCODE_NO_MEMORY;
}
}
}
if (idl_fprintf(gen->source.handle, "}\n\n") < 0)
return IDL_RETCODE_NO_MEMORY;
}
if ((ret = generate_descriptor(pstate, gen, node)))
return ret;
}
if (empty)
if (idl_fprintf(gen->header.handle, "#endif /* empty struct */\n\n") < 0)
return IDL_RETCODE_NO_MEMORY;
} else {
const idl_struct_t *_struct = (const idl_struct_t *)node;
const idl_member_t *members = _struct->members;
/* ensure typedefs for unnamed sequences exist beforehand */
if (members && (ret = generate_implicit_sequences(pstate, revisit, path, members, user_data)))
return ret;
Expand Down Expand Up @@ -324,7 +482,7 @@ emit_union(
fmt = "extern const dds_topic_descriptor_t %1$s_desc;\n"
"\n"
"#define %1$s__alloc() \\\n"
"((%1$s*) dds_alloc (sizeof (%1$s)));\n"
"((%1$s*) dds_alloc (sizeof (%1$s)))\n"
"\n"
"#define %1$s_free(d,o) \\\n"
"dds_sample_free ((d), &%1$s_desc, (o))\n"
Expand Down Expand Up @@ -443,7 +601,7 @@ emit_sequence_typedef(
}
fmt = ";\n\n"
"#define %1$s__alloc() \\\n"
"((%1$s*) dds_alloc (sizeof (%1$s)));\n\n"
"((%1$s*) dds_alloc (sizeof (%1$s)))\n\n"
"#define %1$s_allocbuf(l) \\\n"
"((%2$s%3$s %4$s%5$s*%6$s%7$s) dds_alloc ((l) * sizeof (%2$s%3$s%4$s%7$s)))\n";
if (idl_fprintf(gen->header.handle, fmt, name, type_prefix, type, star, lpar, rpar, dims) < 0)
Expand Down Expand Up @@ -497,7 +655,7 @@ emit_typedef(
}
fmt = ";\n\n"
"#define %1$s__alloc() \\\n"
"((%1$s*) dds_alloc (sizeof (%1$s)));\n\n";
"((%1$s*) dds_alloc (sizeof (%1$s)))\n\n";
if (idl_fprintf(gen->header.handle, fmt, name) < 0)
return IDL_RETCODE_NO_MEMORY;
}
Expand Down Expand Up @@ -545,7 +703,7 @@ emit_enum(

fmt = "\n} %1$s;\n\n"
"#define %1$s__alloc() \\\n"
"((%1$s*) dds_alloc (sizeof (%1$s)));\n\n";
"((%1$s*) dds_alloc (sizeof (%1$s)))\n\n";
if (idl_fprintf(gen->header.handle, fmt, type) < 0)
return IDL_RETCODE_NO_MEMORY;

Expand Down

0 comments on commit 58033b8

Please sign in to comment.