asn1: Add support for decoration w/ external types
This adds support for asn1_compile --decorate=... variation that causes decoration of an ASN.1 SET/SEQUENCE type with a field of a non-ASN.1 type. This means we can now have an ASN.1 type to represent a request that can then have a "hidden" field -- hidden in that it is neither encoded nor decoded. This field will be copied and freed when the decoration is of an ASN.1 type or of a external, C type that comes with copy constructor and destructor functions. Decoration with a `void *` field which is neither copied nor freed is also supported. We may end up using this to, for example, replace the `hdb_entry_ex` type by decorating `HDB_entry` with a C type that points to the `HDB` in which the entry was found or to which it should be written.
This commit is contained in:
@@ -228,10 +228,9 @@ copy_type (const char *from, const char *to, const Type *t, int preserve)
|
||||
void
|
||||
generate_type_copy (const Symbol *s)
|
||||
{
|
||||
struct decoration deco;
|
||||
int preserve = preserve_type(s->name) ? TRUE : FALSE;
|
||||
int save_used_fail = used_fail;
|
||||
int deco_opt;
|
||||
char *ft, *fn;
|
||||
|
||||
used_fail = 0;
|
||||
|
||||
@@ -241,18 +240,41 @@ generate_type_copy (const Symbol *s)
|
||||
"memset(to, 0, sizeof(*to));\n",
|
||||
s->gen_name, s->gen_name, s->gen_name);
|
||||
copy_type ("from", "to", s->type, preserve);
|
||||
if (decorate_type(s->gen_name, &ft, &fn, &deco_opt)) {
|
||||
if (deco_opt) {
|
||||
fprintf(codefile, "if (from->%s) {\n", fn);
|
||||
fprintf(codefile, "(to)->%s = malloc(sizeof(*(to)->%s));\n", fn, fn);
|
||||
fprintf(codefile, "if (copy_%s((from)->%s, (to)->%s)) goto fail;\n", ft, fn, fn);
|
||||
if (decorate_type(s->gen_name, &deco)) {
|
||||
if (deco.ext &&
|
||||
(deco.copy_function_name == NULL ||
|
||||
deco.copy_function_name[0] == '\0')) {
|
||||
/* Decorated with field of external type but no copy function */
|
||||
if (deco.opt || deco.void_star)
|
||||
fprintf(codefile, "(to)->%s = 0;\n", deco.field_name);
|
||||
else
|
||||
fprintf(codefile, "memset(&(to)->%s, 0, sizeof((to)->%s));\n",
|
||||
deco.field_name, deco.field_name);
|
||||
} else if (deco.ext) {
|
||||
/* Decorated with field of external type w/ copy function */
|
||||
if (deco.opt) {
|
||||
fprintf(codefile, "if (from->%s) {\n", deco.field_name);
|
||||
fprintf(codefile, "(to)->%s = malloc(sizeof(*(to)->%s));\n",
|
||||
deco.field_name, deco.field_name);
|
||||
fprintf(codefile, "if (%s((from)->%s, (to)->%s)) goto fail;\n",
|
||||
deco.copy_function_name, deco.field_name, deco.field_name);
|
||||
fprintf(codefile, "}\n");
|
||||
} else {
|
||||
fprintf(codefile, "if (%s(&(from)->%s, &(to)->%s)) goto fail;\n",
|
||||
deco.copy_function_name, deco.field_name, deco.field_name);
|
||||
}
|
||||
} else if (deco.opt) {
|
||||
/* Decorated with optional field of ASN.1 type */
|
||||
fprintf(codefile, "if (from->%s) {\n", deco.field_name);
|
||||
fprintf(codefile, "(to)->%s = malloc(sizeof(*(to)->%s));\n", deco.field_name, deco.field_name);
|
||||
fprintf(codefile, "if (copy_%s((from)->%s, (to)->%s)) goto fail;\n", deco.field_type, deco.field_name, deco.field_name);
|
||||
fprintf(codefile, "}\n");
|
||||
} else {
|
||||
fprintf(codefile, "if (copy_%s(&(from)->%s, &(to)->%s)) goto fail;\n", ft, fn, fn);
|
||||
/* Decorated with required field of ASN.1 type */
|
||||
fprintf(codefile, "if (copy_%s(&(from)->%s, &(to)->%s)) goto fail;\n", deco.field_type, deco.field_name, deco.field_name);
|
||||
}
|
||||
used_fail++;
|
||||
free(ft);
|
||||
free(fn);
|
||||
free(deco.field_type);
|
||||
}
|
||||
fprintf (codefile, "return 0;\n");
|
||||
|
||||
|
Reference in New Issue
Block a user