diff options
author | Andrew Bartlett <abartlet@samba.org> | 2010-01-12 18:16:45 +1100 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2010-03-27 11:51:27 +1100 |
commit | 89eaef025376339ef25d07cdc4748920fceaa968 (patch) | |
tree | f514f4632c9d54a372a7f1f0ca845a0c3a488fbf /source4/heimdal/lib/asn1/gen.c | |
parent | fac8ca52ade6e490eea3cf3d0fc98287da321c13 (diff) | |
download | samba-89eaef025376339ef25d07cdc4748920fceaa968.tar.gz samba-89eaef025376339ef25d07cdc4748920fceaa968.tar.bz2 samba-89eaef025376339ef25d07cdc4748920fceaa968.zip |
s4:heimdal: import lorikeet-heimdal-201001120029 (commit a5e675fed7c5db8a7370b77ed0bfa724196aa84d)
Diffstat (limited to 'source4/heimdal/lib/asn1/gen.c')
-rw-r--r-- | source4/heimdal/lib/asn1/gen.c | 267 |
1 files changed, 231 insertions, 36 deletions
diff --git a/source4/heimdal/lib/asn1/gen.c b/source4/heimdal/lib/asn1/gen.c index 780c18b36f..8c13434203 100644 --- a/source4/heimdal/lib/asn1/gen.c +++ b/source4/heimdal/lib/asn1/gen.c @@ -3,6 +3,8 @@ * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * + * Portions Copyright (c) 2009 Apple Inc. All rights reserved. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -35,12 +37,12 @@ RCSID("$Id$"); -FILE *headerfile, *codefile, *logfile; +FILE *privheaderfile, *headerfile, *codefile, *logfile, *templatefile; #define STEM "asn1" static const char *orig_filename; -static char *header; +static char *privheader, *header, *template; static const char *headerbase = STEM; /* @@ -66,6 +68,45 @@ add_import (const char *module) fprintf (headerfile, "#include <%s_asn1.h>\n", module); } +/* + * List of all exported symbols + */ + +struct sexport { + const char *name; + int defined; + struct sexport *next; +}; + +static struct sexport *exports = NULL; + +void +add_export (const char *name) +{ + struct sexport *tmp = emalloc (sizeof(*tmp)); + + tmp->name = name; + tmp->next = exports; + exports = tmp; +} + +int +is_export(const char *name) +{ + struct sexport *tmp; + + if (exports == NULL) /* no export list, all exported */ + return 1; + + for (tmp = exports; tmp != NULL; tmp = tmp->next) { + if (strcmp(tmp->name, name) == 0) { + tmp->defined = 1; + return 1; + } + } + return 0; +} + const char * get_filename (void) { @@ -96,6 +137,23 @@ init_generate (const char *filename, const char *base) err (1, "open %s", fn); free(fn); + /* private header file */ + asprintf(&privheader, "%s-priv.h", headerbase); + if (privheader == NULL) + errx(1, "malloc"); + asprintf(&fn, "%s-priv.hx", headerbase); + if (fn == NULL) + errx(1, "malloc"); + privheaderfile = fopen (fn, "w"); + if (privheaderfile == NULL) + err (1, "open %s", fn); + free(fn); + + /* template file */ + asprintf(&template, "%s-template.c", headerbase); + if (template == NULL) + errx(1, "malloc"); + fprintf (headerfile, "/* Generated from %s */\n" "/* Do not edit */\n\n", @@ -182,6 +240,36 @@ init_generate (const char *filename, const char *base) logfile = fopen(fn, "w"); if (logfile == NULL) err (1, "open %s", fn); + + /* if one code file, write into the one codefile */ + if (one_code_file) + return; + + templatefile = fopen (template, "w"); + if (templatefile == NULL) + err (1, "open %s", template); + + fprintf (templatefile, + "/* Generated from %s */\n" + "/* Do not edit */\n\n" + "#include <stdio.h>\n" + "#include <stdlib.h>\n" + "#include <time.h>\n" + "#include <string.h>\n" + "#include <errno.h>\n" + "#include <limits.h>\n" + "#include <krb5-types.h>\n", + filename); + + fprintf (templatefile, + "#include <%s>\n" + "#include <%s>\n" + "#include <der.h>\n" + "#include <der-private.h>\n" + "#include <asn1-template.h>\n", + header, privheader); + + } void @@ -189,9 +277,15 @@ close_generate (void) { fprintf (headerfile, "#endif /* __%s_h__ */\n", headerbase); - fclose (headerfile); - fprintf (logfile, "\n"); - fclose (logfile); + if (headerfile) + fclose (headerfile); + if (privheaderfile) + fclose (privheaderfile); + if (templatefile) + fclose (templatefile); + if (logfile) + fprintf (logfile, "\n"); + fclose (logfile); } void @@ -265,11 +359,14 @@ generate_header_of_codefile(const char *name) orig_filename); fprintf (codefile, - "#include <%s.h>\n", - headerbase); + "#include <%s>\n" + "#include <%s>\n", + header, privheader); fprintf (codefile, "#include <asn1_err.h>\n" "#include <der.h>\n" + "#include <der-private.h>\n" + "#include <asn1-template.h>\n" "#include <parse_units.h>\n\n"); } @@ -328,8 +425,6 @@ generate_constant (const Symbol *s) } fprintf (headerfile, "} */\n"); - fprintf (headerfile, "const heim_oid *oid_%s(void);\n", - s->gen_name); fprintf (headerfile, "extern const heim_oid asn1_oid_%s;\n\n", s->gen_name); @@ -346,12 +441,6 @@ generate_constant (const Symbol *s) "{ %d, oid_%s_variable_num };\n\n", s->gen_name, len, s->gen_name); - fprintf (codefile, "const heim_oid *oid_%s(void)\n" - "{\n" - "return &asn1_oid_%s;\n" - "}\n\n", - s->gen_name, s->gen_name); - free(list); if (!one_code_file) @@ -364,6 +453,33 @@ generate_constant (const Symbol *s) } } +int +is_primitive_type(int type) +{ + switch(type) { + case TInteger: + case TBoolean: + case TOctetString: + case TBitString: + case TEnumerated: + case TGeneralizedTime: + case TGeneralString: + case TTeletexString: + case TOID: + case TUTCTime: + case TUTF8String: + case TPrintableString: + case TIA5String: + case TBMPString: + case TUniversalString: + case TVisibleString: + case TNull: + return 1; + default: + return 0; + } +} + static void space(int level) { @@ -550,8 +666,24 @@ define_asn1 (int level, Type *t) } static void -define_type (int level, const char *name, Type *t, int typedefp, int preservep) +getnewbasename(char **newbasename, int typedefp, const char *basename, const char *name) +{ + if (typedefp) + *newbasename = strdup(name); + else { + if (name[0] == '*') + name++; + asprintf(newbasename, "%s_%s", basename, name); + } + if (*newbasename == NULL) + err(1, "malloc"); +} + +static void +define_type (int level, const char *name, const char *basename, Type *t, int typedefp, int preservep) { + char *newbasename = NULL; + switch (t->type) { case TType: space(level); @@ -602,16 +734,37 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep) if(ASN1_TAILQ_EMPTY(t->members)) fprintf (headerfile, "heim_bit_string %s;\n", name); else { - fprintf (headerfile, "struct %s {\n", typedefp ? name : ""); + int pos = 0; + getnewbasename(&newbasename, typedefp, basename, name); + + fprintf (headerfile, "struct %s {\n", newbasename); ASN1_TAILQ_FOREACH(m, t->members, members) { char *n; + /* pad unused */ + while (pos < m->val) { + asprintf (&n, "_unused%d:1", pos); + define_type (level + 1, n, newbasename, &i, FALSE, FALSE); + free(n); + pos++; + } + asprintf (&n, "%s:1", m->gen_name); if (n == NULL) errx(1, "malloc"); - define_type (level + 1, n, &i, FALSE, FALSE); + define_type (level + 1, n, newbasename, &i, FALSE, FALSE); free (n); + pos++; + } + /* pad to 32 elements */ + while (pos < 32) { + char *n; + asprintf (&n, "_unused%d:1", pos); + define_type (level + 1, n, newbasename, &i, FALSE, FALSE); + free(n); + pos++; } + space(level); fprintf (headerfile, "} %s;\n\n", name); } @@ -638,8 +791,10 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep) case TSequence: { Member *m; + getnewbasename(&newbasename, typedefp, basename, name); + space(level); - fprintf (headerfile, "struct %s {\n", typedefp ? name : ""); + fprintf (headerfile, "struct %s {\n", newbasename); if (t->type == TSequence && preservep) { space(level + 1); fprintf(headerfile, "heim_octet_string _save;\n"); @@ -653,10 +808,10 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep) asprintf (&n, "*%s", m->gen_name); if (n == NULL) errx(1, "malloc"); - define_type (level + 1, n, m->type, FALSE, FALSE); + define_type (level + 1, n, newbasename, m->type, FALSE, FALSE); free (n); } else - define_type (level + 1, m->gen_name, m->type, FALSE, FALSE); + define_type (level + 1, m->gen_name, newbasename, m->type, FALSE, FALSE); } space(level); fprintf (headerfile, "} %s;\n", name); @@ -667,15 +822,17 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep) Type i; struct range range = { 0, INT_MAX }; + getnewbasename(&newbasename, typedefp, basename, name); + i.type = TInteger; i.range = ⦥ i.members = NULL; i.constraint = NULL; space(level); - fprintf (headerfile, "struct %s {\n", typedefp ? name : ""); - define_type (level + 1, "len", &i, FALSE, FALSE); - define_type (level + 1, "*val", t->subtype, FALSE, FALSE); + fprintf (headerfile, "struct %s {\n", newbasename); + define_type (level + 1, "len", newbasename, &i, FALSE, FALSE); + define_type (level + 1, "*val", newbasename, t->subtype, FALSE, FALSE); space(level); fprintf (headerfile, "} %s;\n", name); break; @@ -693,14 +850,16 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep) fprintf (headerfile, "heim_general_string %s;\n", name); break; case TTag: - define_type (level, name, t->subtype, typedefp, preservep); + define_type (level, name, basename, t->subtype, typedefp, preservep); break; case TChoice: { int first = 1; Member *m; + getnewbasename(&newbasename, typedefp, basename, name); + space(level); - fprintf (headerfile, "struct %s {\n", typedefp ? name : ""); + fprintf (headerfile, "struct %s {\n", newbasename); if (preservep) { space(level + 1); fprintf(headerfile, "heim_octet_string _save;\n"); @@ -737,10 +896,10 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep) asprintf (&n, "*%s", m->gen_name); if (n == NULL) errx(1, "malloc"); - define_type (level + 2, n, m->type, FALSE, FALSE); + define_type (level + 2, n, newbasename, m->type, FALSE, FALSE); free (n); } else - define_type (level + 2, m->gen_name, m->type, FALSE, FALSE); + define_type (level + 2, m->gen_name, newbasename, m->type, FALSE, FALSE); } space(level + 1); fprintf (headerfile, "} u;\n"); @@ -787,6 +946,8 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep) default: abort (); } + if (newbasename) + free(newbasename); } static void @@ -800,27 +961,61 @@ generate_type_header (const Symbol *s) fprintf (headerfile, "\n*/\n\n"); fprintf (headerfile, "typedef "); - define_type (0, s->gen_name, s->type, TRUE, preservep); + define_type (0, s->gen_name, s->gen_name, s->type, TRUE, preservep); fprintf (headerfile, "\n"); } - void generate_type (const Symbol *s) { + FILE *h; + if (!one_code_file) generate_header_of_codefile(s->gen_name); generate_type_header (s); - generate_type_encode (s); - generate_type_decode (s); - generate_type_free (s); - generate_type_length (s); - generate_type_copy (s); + + if (template_flag) + generate_template(s); + + if (template_flag == 0 || is_template_compat(s) == 0) { + generate_type_encode (s); + generate_type_decode (s); + generate_type_free (s); + generate_type_length (s); + generate_type_copy (s); + } generate_type_seq (s); generate_glue (s->type, s->gen_name); - fprintf(headerfile, "\n\n"); + + /* generate prototypes */ + + if (is_export(s->name)) + h = headerfile; + else + h = privheaderfile; + + fprintf (h, + "int " + "decode_%s(const unsigned char *, size_t, %s *, size_t *);\n", + s->gen_name, s->gen_name); + fprintf (h, + "int " + "encode_%s(unsigned char *, size_t, const %s *, size_t *);\n", + s->gen_name, s->gen_name); + fprintf (h, + "size_t length_%s(const %s *);\n", + s->gen_name, s->gen_name); + fprintf (h, + "int copy_%s (const %s *, %s *);\n", + s->gen_name, s->gen_name, s->gen_name); + fprintf (h, + "void free_%s (%s *);\n", + s->gen_name, s->gen_name); + + + fprintf(h, "\n\n"); if (!one_code_file) { fprintf(codefile, "\n\n"); |