naming abstraction
diff --git a/libasn1compiler/Makefile.am b/libasn1compiler/Makefile.am
index 590ae28..8993de2 100644
--- a/libasn1compiler/Makefile.am
+++ b/libasn1compiler/Makefile.am
@@ -9,15 +9,16 @@
noinst_LTLIBRARIES = libasn1compiler.la
-libasn1compiler_la_SOURCES = \
- asn1compiler.c asn1compiler.h \
- asn1c_misc.c asn1c_misc.h \
- asn1c_out.c asn1c_out.h \
- asn1c_lang.c asn1c_lang.h \
- asn1c_save.c asn1c_save.h \
- asn1c_C.c asn1c_C.h \
- asn1c_constraint.c asn1c_constraint.h \
- asn1c_compat.c asn1c_compat.h \
- asn1c_ioc.c asn1c_ioc.h \
- asn1c_fdeps.c asn1c_fdeps.h \
- asn1c_internal.h
+libasn1compiler_la_SOURCES = \
+ asn1compiler.c asn1compiler.h \
+ asn1c_misc.c asn1c_misc.h \
+ asn1c_out.c asn1c_out.h \
+ asn1c_lang.c asn1c_lang.h \
+ asn1c_naming.c asn1c_naming.h \
+ asn1c_save.c asn1c_save.h \
+ asn1c_C.c asn1c_C.h \
+ asn1c_constraint.c asn1c_constraint.h \
+ asn1c_compat.c asn1c_compat.h \
+ asn1c_ioc.c asn1c_ioc.h \
+ asn1c_fdeps.c asn1c_fdeps.h \
+ asn1c_internal.h
diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c
index e5ec734..82d67ef 100644
--- a/libasn1compiler/asn1c_C.c
+++ b/libasn1compiler/asn1c_C.c
@@ -8,6 +8,7 @@
#include "asn1c_out.h"
#include "asn1c_misc.h"
#include "asn1c_ioc.h"
+#include "asn1c_naming.h"
#include <asn1print.h>
#include <asn1fix_crange.h> /* constraint groker from libasn1fix */
#include <asn1fix_export.h> /* other exportables from libasn1fix */
@@ -140,15 +141,12 @@
if(expr->expr_type == ASN_BASIC_ENUMERATED || el_count) {
eidx = 0;
REDIR(OT_DEPS);
- OUT("typedef enum ");
- out_name_chain(arg, ONC_avoid_keywords);
- OUT(" {\n");
+ OUT("typedef %s {\n", c_name(arg).members_enum);
TQ_FOR(v, &(expr->members), next) {
switch(v->expr_type) {
case A1TC_UNIVERVAL:
OUT("\t");
- out_name_chain(arg, ONC_noflags);
- OUT("_%s", MKID(v));
+ OUT("%s", c_member_name(arg, v));
OUT("\t= %s%s\n",
asn1p_itoa(v->value->value.v_integer),
(eidx+1 < el_count) ? "," : "");
@@ -167,9 +165,7 @@
return -1;
}
}
- OUT("} e_");
- out_name_chain(arg, ONC_noflags);
- OUT(";\n");
+ OUT("} %s;\n", c_name(arg).members_name);
assert(eidx == el_count);
}
@@ -275,9 +271,7 @@
if(el_count) {
int eidx = 0;
REDIR(OT_DEPS);
- OUT("typedef enum ");
- out_name_chain(arg, ONC_avoid_keywords);
- OUT(" {\n");
+ OUT("typedef %s {\n", c_name(arg).members_enum);
TQ_FOR(v, &(expr->members), next) {
if(v->expr_type != A1TC_UNIVERVAL) {
OUT("/* Unexpected BIT STRING element: %s */\n",
@@ -286,15 +280,12 @@
}
eidx++;
OUT("\t");
- out_name_chain(arg, ONC_noflags);
- OUT("_%s", MKID(v));
+ OUT("%s", c_member_name(arg, v));
OUT("\t= %s%s\n",
asn1p_itoa(v->value->value.v_integer),
(eidx < el_count) ? "," : "");
}
- OUT("} e_");
- out_name_chain(arg, ONC_noflags);
- OUT(";\n");
+ OUT("} %s;\n", c_name(arg).members_name);
assert(eidx == el_count);
}
@@ -355,13 +346,10 @@
REDIR(OT_FWD_DEFS);
OUT("typedef ");
}
- OUT("struct ");
- out_name_chain(arg, ONC_avoid_keywords);
- OUT(" {\n");
+ OUT("%s {\n", c_name(arg).full_name);
} else {
REDIR(OT_TYPE_DECLS);
- OUT("typedef struct %s {\n",
- MKID_safe(expr));
+ OUT("typedef %s {\n", c_name(arg).full_name);
}
TQ_FOR(v, &(expr->members), next) {
@@ -390,21 +378,16 @@
PCTX_DEF;
if (arg->embed && expr->_anonymous_type) {
- OUT("} %s", (expr->marker.flags & EM_INDIRECT)?"*":"");
- out_name_chain(arg, ONC_avoid_keywords);
- OUT("%s;\n", arg->embed ? "" : "_t");
+ OUT("} %s%s;\n", (expr->marker.flags & EM_INDIRECT)?"*":"",
+ c_name(arg).base_name);
REDIR(saved_target);
- OUT("%s", (expr->marker.flags & EM_INDIRECT)?"*":"");
- out_name_chain(arg, ONC_avoid_keywords);
+ OUT("%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
+ c_name(arg).base_name);
} else {
- OUT("} %s%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
- expr->_anonymous_type ? "" :
- arg->embed
- ? MKID_safe(expr)
- : MKID(expr),
- arg->embed ? "" : "_t");
+ OUT("} %s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
+ c_name(arg).short_name);
}
return asn1c_lang_C_type_SEQUENCE_def(arg, ioc_tao.ioct ? &ioc_tao : 0);
@@ -550,10 +533,8 @@
OUT("asn_SEQUENCE_specifics_t asn_SPC_%s_specs_%d = {\n",
MKID(expr), expr->_type_unique_index);
INDENT(+1);
- OUT("sizeof(struct ");
- out_name_chain(arg, ONC_avoid_keywords); OUT("),\n");
- OUT("offsetof(struct ");
- out_name_chain(arg, ONC_avoid_keywords); OUT(", _asn_ctx),\n");
+ OUT("sizeof(%s),\n", c_name(arg).full_name);
+ OUT("offsetof(%s, _asn_ctx),\n", c_name(arg).full_name);
emit_tag2member_reference(arg, expr, tag2el_count);
if(roms_count + aoms_count) {
OUT("asn_MAP_%s_oms_%d,\t/* Optional members */\n",
@@ -587,7 +568,7 @@
asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *v;
long mcount;
- char *id;
+ const char *id;
int comp_mode = 0; /* {root,ext=1,root,root,...} */
int saved_target = arg->target->target;
@@ -600,21 +581,16 @@
OUT(" * Method of determining the components presence\n");
OUT(" */\n");
mcount = 0;
- OUT("typedef enum ");
- out_name_chain(arg, ONC_noflags);
- OUT("_PR {\n");
+ OUT("typedef %s {\n", c_name(arg).presence_enum);
TQ_FOR(v, &(expr->members), next) {
if(v->expr_type == A1TC_EXTENSIBLE) continue;
INDENTED(
- out_name_chain(arg, ONC_noflags);
- OUT("_PR_");
- id = MKID(v);
- OUT("%s,\t/* Member %s is present */\n",
- id, id)
+ OUT("%s,", c_presence_name(arg, v));
+ OUT("\t/* Member %s is present */\n", MKID(v));
);
mcount++;
}
- OUT("} "); out_name_chain(arg, ONC_noflags); OUT("_PR;\n");
+ OUT("} %s;\n", c_name(arg).presence_name);
REDIR(saved_target);
@@ -623,13 +599,10 @@
REDIR(OT_FWD_DEFS);
OUT("typedef ");
}
- OUT("struct ");
- out_name_chain(arg, ONC_avoid_keywords);
- OUT(" {\n");
+ OUT("%s {\n", c_name(arg).full_name);
} else {
REDIR(OT_TYPE_DECLS);
- OUT("typedef struct %s {\n",
- MKID_safe(expr));
+ OUT("typedef %s {\n", c_name(arg).full_name);
}
TQ_FOR(v, &(expr->members), next) {
@@ -653,18 +626,16 @@
PCTX_DEF;
if (arg->embed && expr->_anonymous_type) {
- OUT("} %s", (expr->marker.flags & EM_INDIRECT)?"*":"");
- out_name_chain(arg, ONC_avoid_keywords);
- OUT("%s;\n", arg->embed ? "" : "_t");
+ OUT("} %s%s;\n", (expr->marker.flags & EM_INDIRECT)?"*":"",
+ c_name(arg).base_name);
REDIR(saved_target);
- OUT("%s", (expr->marker.flags & EM_INDIRECT)?"*":"");
- out_name_chain(arg, ONC_avoid_keywords);
+ OUT("%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
+ c_name(arg).base_name);
} else {
- OUT("} %s%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
- expr->_anonymous_type ? "" : MKID_safe(expr),
- arg->embed ? "" : "_t");
+ OUT("} %s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
+ c_name(arg).short_name);
}
return asn1c_lang_C_type_SET_def(arg);
@@ -682,7 +653,7 @@
int tags_count;
int all_tags_count;
enum tvm_compat tv_mode;
- char *p;
+ const char *p;
int saved_target = arg->target->target;
/*
@@ -780,15 +751,9 @@
OUT("asn_SET_specifics_t asn_SPC_%s_specs_%d = {\n",
MKID(expr), expr->_type_unique_index);
INDENTED(
- OUT("sizeof(struct ");
- out_name_chain(arg, ONC_avoid_keywords);
- OUT("),\n");
- OUT("offsetof(struct ");
- out_name_chain(arg, ONC_avoid_keywords);
- OUT(", _asn_ctx),\n");
- OUT("offsetof(struct ");
- out_name_chain(arg, ONC_avoid_keywords);
- OUT(", _presence_map),\n");
+ OUT("sizeof(%s),\n", c_name(arg).full_name);
+ OUT("offsetof(%s, _asn_ctx),\n", c_name(arg).full_name);
+ OUT("offsetof(%s, _presence_map),\n", c_name(arg).full_name);
emit_tag2member_reference(arg, expr, tag2el_count);
p = MKID(expr);
if(tag2el_cxer)
@@ -833,11 +798,9 @@
REDIR(OT_FWD_DEFS);
OUT("typedef ");
}
- OUT("struct ");
- out_name_chain(arg, ONC_avoid_keywords);
- OUT(" {\n");
+ OUT("%s {\n", c_name(arg).full_name);
} else {
- OUT("typedef struct %s {\n", MKID_safe(expr));
+ OUT("typedef %s {\n", c_name(arg).full_name);
}
INDENT(+1);
@@ -892,18 +855,16 @@
PCTX_DEF;
if (arg->embed && expr->_anonymous_type) {
- OUT("} %s", (expr->marker.flags & EM_INDIRECT)?"*":"");
- out_name_chain(arg, ONC_avoid_keywords);
- OUT("%s;\n", arg->embed ? "" : "_t");
+ OUT("} %s%s;\n", (expr->marker.flags & EM_INDIRECT)?"*":"",
+ c_name(arg).base_name);
REDIR(saved_target);
- OUT("%s", (expr->marker.flags & EM_INDIRECT)?"*":"");
- out_name_chain(arg, ONC_avoid_keywords);
+ OUT("%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
+ c_name(arg).base_name);
} else {
- OUT("} %s%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
- expr->_anonymous_type ? "" : MKID_safe(expr),
- arg->embed ? "" : "_t");
+ OUT("} %s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
+ c_name(arg).short_name);
}
/*
@@ -965,12 +926,8 @@
OUT("asn_SET_OF_specifics_t asn_SPC_%s_specs_%d = {\n",
MKID(expr), expr->_type_unique_index);
INDENTED(
- OUT("sizeof(struct ");
- out_name_chain(arg, ONC_avoid_keywords);
- OUT("),\n");
- OUT("offsetof(struct ");
- out_name_chain(arg, ONC_avoid_keywords);
- OUT(", _asn_ctx),\n");
+ OUT("sizeof(%s),\n", c_name(arg).full_name);
+ OUT("offsetof(%s, _asn_ctx),\n", c_name(arg).full_name);
{
int as_xvl = expr_as_xmlvaluelist(arg, v);
OUT("%d,\t/* XER encoding is %s */\n",
@@ -995,20 +952,16 @@
asn1c_lang_C_type_CHOICE(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *v;
- char *id;
int saved_target = arg->target->target;
DEPENDENCIES;
REDIR(OT_DEPS);
- OUT("typedef enum ");
- out_name_chain(arg, ONC_noflags);
- OUT("_PR {\n");
+ OUT("typedef %s {\n", c_name(arg).presence_enum);
INDENTED(
int skipComma = 1;
- out_name_chain(arg, ONC_noflags);
- OUT("_PR_NOTHING,\t/* No components present */\n");
+ OUT("%s,\t/* No components present */\n", c_presence_name(arg, 0));
TQ_FOR(v, &(expr->members), next) {
if(skipComma) skipComma = 0;
else if (v->expr_type == A1TC_EXTENSIBLE && !TQ_NEXT(v, next)) OUT("\n");
@@ -1018,13 +971,11 @@
skipComma = 1;
continue;
}
- out_name_chain(arg, ONC_noflags);
- id = MKID(v);
- OUT("_PR_%s", id);
+ OUT("%s", c_presence_name(arg, v));
}
OUT("\n");
);
- OUT("} "); out_name_chain(arg, ONC_noflags); OUT("_PR;\n");
+ OUT("} %s;\n", c_name(arg).presence_name);
REDIR(saved_target);
@@ -1033,15 +984,14 @@
REDIR(OT_FWD_DEFS);
OUT("typedef ");
}
- OUT("struct "); out_name_chain(arg, ONC_avoid_keywords); OUT(" {\n");
+ OUT("%s {\n", c_name(arg).full_name);
} else {
REDIR(OT_TYPE_DECLS);
- OUT("typedef struct %s {\n", MKID_safe(expr));
+ OUT("typedef %s {\n", c_name(arg).full_name);
}
INDENTED(
- out_name_chain(arg, ONC_noflags);
- OUT("_PR present;\n");
+ OUT("%s present;\n", c_name(arg).presence_name);
OUT("union ");
if(UNNAMED_UNIONS == 0) {
out_name_chain(arg, ONC_force_compound_name);
@@ -1058,21 +1008,16 @@
PCTX_DEF;
if (arg->embed && expr->_anonymous_type) {
- OUT("} %s", (expr->marker.flags & EM_INDIRECT)?"*":"");
- out_name_chain(arg, ONC_avoid_keywords);
- OUT("%s;\n", arg->embed ? "" : "_t");
+ OUT("} %s%s;\n", (expr->marker.flags & EM_INDIRECT)?"*":"",
+ c_name(arg).base_name);
REDIR(saved_target);
- OUT("%s", (expr->marker.flags & EM_INDIRECT)?"*":"");
- out_name_chain(arg, ONC_avoid_keywords);
+ OUT("%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
+ c_name(arg).base_name);
} else {
- OUT("} %s%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
- expr->_anonymous_type ? "" :
- arg->embed
- ? MKID_safe(expr)
- : MKID(expr),
- arg->embed ? "" : "_t");
+ OUT("} %s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
+ c_name(arg).short_name);
}
return asn1c_lang_C_type_CHOICE_def(arg);
@@ -1219,18 +1164,10 @@
OUT("asn_CHOICE_specifics_t asn_SPC_%s_specs_%d = {\n",
MKID(expr), expr->_type_unique_index);
INDENTED(
- OUT("sizeof(struct ");
- out_name_chain(arg, ONC_avoid_keywords);
- OUT("),\n");
- OUT("offsetof(struct ");
- out_name_chain(arg, ONC_avoid_keywords);
- OUT(", _asn_ctx),\n");
- OUT("offsetof(struct ");
- out_name_chain(arg, ONC_avoid_keywords);
- OUT(", present),\n");
- OUT("sizeof(((struct ");
- out_name_chain(arg, ONC_avoid_keywords);
- OUT(" *)0)->present),\n");
+ OUT("sizeof(%s),\n", c_name(arg).full_name);
+ OUT("offsetof(%s, _asn_ctx),\n", c_name(arg).full_name);
+ OUT("offsetof(%s, present),\n", c_name(arg).full_name);
+ OUT("sizeof(((%s *)0)->present),\n", c_name(arg).full_name);
emit_tag2member_reference(arg, expr, tag2el_count);
if(C99_MODE) OUT(".canonical_order = ");
if(cmap) OUT("asn_MAP_%s_cmap_%d,\t/* Canonically sorted */\n",
@@ -1306,7 +1243,7 @@
int all_tags_count;
enum tvm_compat tv_mode;
enum etd_spec etd_spec;
- char *p;
+ const char *p;
int saved_target = arg->target->target;
if(arg->embed) {
@@ -2890,8 +2827,7 @@
const char *tname = asn1c_type_name(arg, constraining_memb, TNF_SAFE);
if(constraining_memb->marker.flags & EM_INDIRECT) {
OUT("const void *memb_ptr = *(const void **)");
- OUT("((const char *)parent_sptr + offsetof(struct ");
- out_name_chain(arg, ONC_avoid_keywords);
+ OUT("((const char *)parent_sptr + offsetof(%s", c_name(arg).full_name);
OUT(", %s));", MKID_safe(constraining_memb));
OUT("if(!memb_ptr) return result;\n");
OUT("\n");
@@ -2912,8 +2848,7 @@
if(constraining_memb->marker.flags & EM_INDIRECT) {
OUT("memb_ptr;\n");
} else {
- OUT("((const char *)parent_sptr + offsetof(struct ");
- out_name_chain(arg, ONC_avoid_keywords);
+ OUT("((const char *)parent_sptr + offsetof(%s", c_name(arg).full_name);
OUT(", %s));\n", MKID_safe(constraining_memb));
}
OUT("\n");
@@ -2987,9 +2922,7 @@
|| arg->expr->expr_type == ASN_CONSTR_SEQUENCE_OF);
OUT("0,\n");
} else {
- OUT("offsetof(struct ");
- out_name_chain(arg, ONC_avoid_keywords);
- OUT(", ");
+ OUT("offsetof(%s, ", c_name(arg).full_name);
if((arg->expr->expr_type == ASN_CONSTR_CHOICE
|| arg->expr->expr_type == ASN_CONSTR_OPEN_TYPE)
&& (!UNNAMED_UNIONS))
@@ -3372,7 +3305,7 @@
static int
out_name_chain(arg_t *arg, enum onc_flags onc_flags) {
asn1p_expr_t *expr = arg->expr;
- char *id;
+ const char *id;
if((arg->flags & A1C_COMPOUND_NAMES
|| onc_flags & ONC_force_compound_name
diff --git a/libasn1compiler/asn1c_misc.c b/libasn1compiler/asn1c_misc.c
index 99c275b..59cb497 100644
--- a/libasn1compiler/asn1c_misc.c
+++ b/libasn1compiler/asn1c_misc.c
@@ -42,7 +42,7 @@
* Construct identifier from multiple parts.
* Convert unsafe characters to underscores.
*/
-char *
+const char *
asn1c_make_identifier(enum ami_flags_e flags, asn1p_expr_t *expr, ...) {
static char *storage;
static int storage_size;
diff --git a/libasn1compiler/asn1c_misc.h b/libasn1compiler/asn1c_misc.h
index ff6d672..f9f3c45 100644
--- a/libasn1compiler/asn1c_misc.h
+++ b/libasn1compiler/asn1c_misc.h
@@ -12,7 +12,7 @@
AMI_NODELIMITER = 4, /* Do not put delimiter, just concatenate */
AMI_USE_PREFIX = 8, /* Use Prefix when generating identifier */
};
-char *asn1c_make_identifier(enum ami_flags_e, asn1p_expr_t *expr, ...);
+const char *asn1c_make_identifier(enum ami_flags_e, asn1p_expr_t *expr, ...);
/*
* Return the type name of the specified expression.
diff --git a/libasn1compiler/asn1c_naming.c b/libasn1compiler/asn1c_naming.c
new file mode 100644
index 0000000..6ab3c4a
--- /dev/null
+++ b/libasn1compiler/asn1c_naming.c
@@ -0,0 +1,137 @@
+#include "asn1c_internal.h"
+#include "asn1c_naming.h"
+#include "asn1c_misc.h"
+#include "asn1c_misc.h"
+#include <asn1_buffer.h>
+
+static abuf *
+construct_base_name(abuf *buf, arg_t *arg, int compound_names,
+ int avoid_keywords) {
+ const char *id;
+
+ if(!buf) buf = abuf_new();
+
+ if(compound_names && arg->expr->parent_expr) {
+ arg_t tmparg = *arg;
+ tmparg.expr = arg->expr->parent_expr;
+ construct_base_name(buf, &tmparg, compound_names, 0);
+ if(buf->length) {
+ abuf_str(buf, "__"); /* component separator */
+ }
+ }
+
+ id = asn1c_make_identifier(
+ ((avoid_keywords && !buf->length) ? AMI_CHECK_RESERVED : 0), arg->expr,
+ 0);
+
+ abuf_str(buf, id);
+
+ return buf;
+}
+
+static struct c_names
+c_name_impl(arg_t *arg, int avoid_keywords) {
+ asn1p_expr_type_e expr_type = arg->expr->expr_type;
+ struct c_names names;
+ int compound_names = 0;
+
+ static abuf b_base_name;
+ static abuf b_short_name;
+ static abuf b_full_name;
+ static abuf b_as_member;
+ static abuf b_presence_enum;
+ static abuf b_presence_name;
+ static abuf b_members_enum;
+ static abuf b_members_name;
+
+ abuf_clear(&b_base_name);
+ abuf_clear(&b_short_name);
+ abuf_clear(&b_full_name);
+ abuf_clear(&b_as_member);
+ abuf_clear(&b_presence_enum);
+ abuf_clear(&b_presence_name);
+ abuf_clear(&b_members_enum);
+ abuf_clear(&b_members_name);
+
+ if((arg->flags & A1C_COMPOUND_NAMES)) {
+ if((expr_type & ASN_CONSTR_MASK)
+ || expr_type == ASN_BASIC_ENUMERATED
+ || ((expr_type == ASN_BASIC_INTEGER
+ || expr_type == ASN_BASIC_BIT_STRING))) {
+ compound_names = 1;
+ }
+ }
+
+ abuf *base_name =
+ construct_base_name(NULL, arg, compound_names, avoid_keywords);
+ abuf *part_name =
+ construct_base_name(NULL, arg, compound_names, 0);
+ abuf *member_name =
+ construct_base_name(NULL, arg, 0, 1);
+
+ abuf_printf(&b_base_name, "%s", base_name->buffer);
+ if(!arg->expr->_anonymous_type) {
+ if(arg->embed) {
+ abuf_printf(&b_short_name, "%s", member_name->buffer);
+ } else {
+ abuf_printf(&b_short_name, "%s_t", member_name->buffer);
+ }
+ }
+ abuf_printf(&b_full_name, "struct %s", base_name->buffer);
+ abuf_printf(&b_as_member, "%s", member_name->buffer);
+ abuf_printf(&b_presence_enum, "enum %s_PR", part_name->buffer);
+ abuf_printf(&b_presence_name, "%s_PR", part_name->buffer);
+ abuf_printf(&b_members_enum, "enum %s", base_name->buffer);
+ abuf_printf(&b_members_name, "e_%s", part_name->buffer);
+
+ names.base_name = b_base_name.buffer;
+ names.short_name = b_short_name.buffer;
+ names.full_name = b_full_name.buffer;
+ names.as_member = b_as_member.buffer;
+ names.presence_enum = b_presence_enum.buffer;
+ names.presence_name = b_presence_name.buffer;
+ names.members_enum = b_members_enum.buffer;
+ names.members_name = b_members_name.buffer;
+
+ abuf_free(base_name);
+ abuf_free(part_name);
+ abuf_free(member_name);
+
+ return names;
+}
+
+struct c_names
+c_name(arg_t *arg) {
+ return c_name_impl(arg, 1);
+}
+
+const char *
+c_member_name(arg_t *arg, asn1p_expr_t *expr) {
+ static abuf ab;
+
+ abuf_clear(&ab);
+
+ abuf_printf(&ab, "%s_%s", c_name_impl(arg, 0).base_name,
+ asn1c_make_identifier(0, expr, 0));
+
+ return ab.buffer;
+}
+
+
+const char *
+c_presence_name(arg_t *arg, asn1p_expr_t *expr) {
+ static abuf ab;
+
+ abuf_clear(&ab);
+
+ if(expr) {
+ abuf_printf(&ab, "%s_PR_%s", c_name_impl(arg, 0).base_name,
+ asn1c_make_identifier(0, expr, 0));
+ } else {
+ abuf_printf(&ab, "%s_PR_NOTHING", c_name_impl(arg, 0).base_name);
+ }
+
+ return ab.buffer;
+}
+
+
diff --git a/libasn1compiler/asn1c_naming.h b/libasn1compiler/asn1c_naming.h
new file mode 100644
index 0000000..2e0e88d
--- /dev/null
+++ b/libasn1compiler/asn1c_naming.h
@@ -0,0 +1,19 @@
+#ifndef ASN1_COMPILER_NAMING_H
+#define ASN1_COMPILER_NAMING_H
+
+struct c_names {
+ const char *base_name; /* "foo" */
+ const char *short_name; /* "foo_t", "e_foo" */
+ const char *full_name; /* "struct foo", "enum foo" */
+ const char *as_member; /* "foo" (not compounded) */
+ const char *presence_enum; /* "enum foo_PR" */
+ const char *presence_name; /* "foo_PR" */
+ const char *members_enum; /* "enum foo" */
+ const char *members_name; /* "e_foo" */
+};
+
+struct c_names c_name(arg_t *);
+const char *c_member_name(arg_t *, asn1p_expr_t *); /* %s_%s */
+const char *c_presence_name(arg_t *, asn1p_expr_t *); /* %s_PR_%s */
+
+#endif /* ASN1_COMPILER_NAMING_H */
diff --git a/libasn1compiler/asn1c_save.c b/libasn1compiler/asn1c_save.c
index 76f312b..d43da4f 100644
--- a/libasn1compiler/asn1c_save.c
+++ b/libasn1compiler/asn1c_save.c
@@ -243,7 +243,7 @@
FILE *fp_c, *fp_h;
char *tmpname_c, *tmpname_h;
char *name_buf;
- char *header_id;
+ const char *header_id;
const char *c_retained = "";
const char *h_retained = "";
char *filename;