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?
This commit is contained in:
Nicolas Williams
2020-12-21 00:20:13 -06:00
parent d336730534
commit 07d4b1fc74
2 changed files with 24 additions and 4 deletions

View File

@@ -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);

View File

@@ -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 },