From 07d4b1fc74fcbcdfa31392c0f479943a36a72590 Mon Sep 17 00:00:00 2001 From: Nicolas Williams Date: Mon, 21 Dec 2020 00:20:13 -0600 Subject: [PATCH] asn1: Add compiler --enum-prefix=PREFIX option C enum labels have to be globally unique. ASN.1 module ENUMERATED and INTEGER types with named values are not globally unique. This means that ASN.1 integer type value names and enumerations can cause conflicts when compiled to C. This new option allows the user to specify a prefix to apply to such names. Then this: Foo ::= ENUMERATED { v1 (0) } can generate: typedef enum Foo { prefix_v1 = 0, } Foo; instead of typedef enum Foo { v1 = 0, } Foo; which is very likely to conflict. TBD: Add option to use the type name as the prefix? --- lib/asn1/gen.c | 20 ++++++++++++++++---- lib/asn1/main.c | 8 ++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/lib/asn1/gen.c b/lib/asn1/gen.c index 1df8b720d..b2b559f6f 100644 --- a/lib/asn1/gen.c +++ b/lib/asn1/gen.c @@ -35,6 +35,9 @@ #include "gen_locl.h" +extern const char *enum_prefix; +extern int prefix_enum; + RCSID("$Id$"); FILE *privheaderfile, *headerfile, *oidsfile, *codefile, *logfile, *templatefile; @@ -742,6 +745,8 @@ getnewbasename(char **newbasename, int typedefp, const char *basename, const cha static void define_type (int level, const char *name, const char *basename, Type *t, int typedefp, int preservep) { + const char *label_prefix = NULL; + const char *label_prefix_sep = NULL; char *newbasename = NULL; switch (t->type) { @@ -753,11 +758,15 @@ define_type (int level, const char *name, const char *basename, Type *t, int typ space(level); if(t->members) { Member *m; + + label_prefix = prefix_enum ? name : (enum_prefix ? enum_prefix : ""); + label_prefix_sep = prefix_enum ? "_" : ""; fprintf (headerfile, "enum %s {\n", typedefp ? name : ""); HEIM_TAILQ_FOREACH(m, t->members, members) { space (level + 1); - fprintf(headerfile, "%s = %d%s\n", m->gen_name, m->val, - last_member_p(m)); + fprintf(headerfile, "%s%s%s = %d%s\n", + label_prefix, label_prefix_sep, + m->gen_name, m->val, last_member_p(m)); } fprintf (headerfile, "} %s;\n", name); } else if (t->range == NULL) { @@ -867,6 +876,8 @@ define_type (int level, const char *name, const char *basename, Type *t, int typ case TEnumerated: { Member *m; + label_prefix = prefix_enum ? name : (enum_prefix ? enum_prefix : ""); + label_prefix_sep = prefix_enum ? "_" : ""; space(level); fprintf (headerfile, "enum %s {\n", typedefp ? name : ""); HEIM_TAILQ_FOREACH(m, t->members, members) { @@ -874,8 +885,9 @@ define_type (int level, const char *name, const char *basename, Type *t, int typ if (m->ellipsis) fprintf (headerfile, "/* ... */\n"); else - fprintf (headerfile, "%s = %d%s\n", m->gen_name, m->val, - last_member_p(m)); + fprintf(headerfile, "%s%s%s = %d%s\n", + label_prefix, label_prefix_sep, + m->gen_name, m->val, last_member_p(m)); } space(level); fprintf (headerfile, "} %s;\n\n", name); diff --git a/lib/asn1/main.c b/lib/asn1/main.c index 80038cd37..752a582a8 100644 --- a/lib/asn1/main.c +++ b/lib/asn1/main.c @@ -61,6 +61,8 @@ seq_type(const char *p) } const char *fuzzer_string = ""; +const char *enum_prefix; +int prefix_enum; int fuzzer_flag; int support_ber; int template_flag; @@ -74,6 +76,12 @@ int help_flag; struct getargs args[] = { { "fuzzer", 0, arg_flag, &fuzzer_flag, NULL, NULL }, { "template", 0, arg_flag, &template_flag, NULL, NULL }, + { "prefix-enum", 0, arg_flag, &prefix_enum, + "prefix C enum labels for ENUMERATED types and INTEGER types with the " + "type's name", NULL }, + { "enum-prefix", 0, arg_string, &enum_prefix, + "prefix for C enum labels for ENUMERATED types and INTEGER types with " + "enumerated values", "PREFIX" }, { "encode-rfc1510-bit-string", 0, arg_flag, &rfc1510_bitstring, NULL, NULL }, { "decode-dce-ber", 0, arg_flag, &support_ber, NULL, NULL }, { "support-ber", 0, arg_flag, &support_ber, NULL, NULL },