diff options
Diffstat (limited to 'lib/asn1/gen_copy.c')
-rw-r--r-- | lib/asn1/gen_copy.c | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/lib/asn1/gen_copy.c b/lib/asn1/gen_copy.c index b494c5d85292..c6d420a2f16a 100644 --- a/lib/asn1/gen_copy.c +++ b/lib/asn1/gen_copy.c @@ -62,7 +62,7 @@ copy_type (const char *from, const char *to, const Type *t, int preserve) copy_primitive ("heim_integer", from, to); break; } - /* fallthrough */ + HEIM_FALLTHROUGH; case TBoolean: case TEnumerated : fprintf(codefile, "*(%s) = *(%s);\n", to, from); @@ -71,7 +71,7 @@ copy_type (const char *from, const char *to, const Type *t, int preserve) copy_primitive ("octet_string", from, to); break; case TBitString: - if (ASN1_TAILQ_EMPTY(t->members)) + if (HEIM_TAILQ_EMPTY(t->members)) copy_primitive ("bit_string", from, to); else fprintf(codefile, "*(%s) = *(%s);\n", to, from); @@ -99,7 +99,7 @@ copy_type (const char *from, const char *to, const Type *t, int preserve) fprintf(codefile, "switch((%s)->element) {\n", from); } - ASN1_TAILQ_FOREACH(m, t->members, members) { + HEIM_TAILQ_FOREACH(m, t->members, members) { char *fs; char *ts; @@ -125,7 +125,7 @@ copy_type (const char *from, const char *to, const Type *t, int preserve) errx(1, "malloc"); if(m->optional){ fprintf(codefile, "if(%s) {\n", fs); - fprintf(codefile, "%s = malloc(sizeof(*%s));\n", ts, ts); + fprintf(codefile, "%s = calloc(1, sizeof(*%s));\n", ts, ts); fprintf(codefile, "if(%s == NULL) goto fail;\n", ts); used_fail++; } @@ -161,7 +161,7 @@ copy_type (const char *from, const char *to, const Type *t, int preserve) char *f = NULL, *T = NULL; fprintf (codefile, "if(((%s)->val = " - "malloc((%s)->len * sizeof(*(%s)->val))) == NULL && (%s)->len != 0)\n", + "calloc(1, (%s)->len * sizeof(*(%s)->val))) == NULL && (%s)->len != 0)\n", to, from, to, from); fprintf (codefile, "goto fail;\n"); used_fail++; @@ -228,7 +228,10 @@ copy_type (const char *from, const char *to, const Type *t, int preserve) void generate_type_copy (const Symbol *s) { + struct decoration deco; + ssize_t more_deco = -1; int preserve = preserve_type(s->name) ? TRUE : FALSE; + int save_used_fail = used_fail; used_fail = 0; @@ -238,6 +241,40 @@ 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); + while (decorate_type(s->gen_name, &deco, &more_deco)) { + if (deco.ext && deco.copy_function_name == NULL) { + /* Decorated with field of external type but no copy function */ + if (deco.ptr) + 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.ptr) { + fprintf(codefile, "if (from->%s) {\n", deco.field_name); + fprintf(codefile, "(to)->%s = calloc(1, 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 = calloc(1, 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 { + /* 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(deco.field_type); + } fprintf (codefile, "return 0;\n"); if (used_fail) @@ -248,5 +285,6 @@ generate_type_copy (const Symbol *s) fprintf(codefile, "}\n\n"); + used_fail = save_used_fail; } |