Commit b8a6be0a authored by Bi-Ruei, Chiu's avatar Bi-Ruei, Chiu

Prefix generated types using a ASN1C_PREFIX environment variable

When generating code for multiple ASN.1 syntaxes that have clashing
names, we need to add a prefix in order to prevent clashes in the global
C symbol namespace.  Using the ASN1C_PREFIX environment variable and
this patch serves as a work-around to that.  All non-basic type names
as well as references to that type and source code + header file names
will be pre-fixed accordingly.

This is a re-implementation of this feature due to osmocom's
implementation version can not work on newest asn1c repository.
parent 1979a097
......@@ -94,7 +94,7 @@ static int emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, enum tvm_compat tv_mode
} while(0)
/* MKID_safe() without checking for reserved keywords */
#define MKID(expr) (asn1c_make_identifier(0, expr, 0))
#define MKID(expr) (asn1c_make_identifier(AMI_USE_PREFIX, expr, 0))
#define MKID_safe(expr) (asn1c_make_identifier(AMI_CHECK_RESERVED, expr, 0))
int
......@@ -389,7 +389,7 @@ asn1c_lang_C_type_SEQUENCE(arg_t *arg) {
c_name(arg).base_name);
} else {
OUT("} %s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
c_name(arg).short_name);
arg->embed ? c_name(arg).as_member : c_name(arg).short_name);
if(!expr->_anonymous_type) OUT(";\n");
}
......@@ -632,7 +632,7 @@ asn1c_lang_C_type_SET(arg_t *arg) {
c_name(arg).base_name);
} else {
OUT("} %s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
c_name(arg).short_name);
arg->embed ? c_name(arg).as_member : c_name(arg).short_name);
if(!expr->_anonymous_type) OUT(";\n");
}
......@@ -861,7 +861,7 @@ asn1c_lang_C_type_SEx_OF(arg_t *arg) {
c_name(arg).base_name);
} else {
OUT("} %s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
c_name(arg).short_name);
arg->embed ? c_name(arg).as_member : c_name(arg).short_name);
if(!expr->_anonymous_type) OUT(";\n");
}
......@@ -1016,7 +1016,7 @@ asn1c_lang_C_type_CHOICE(arg_t *arg) {
c_name(arg).base_name);
} else {
OUT("} %s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
c_name(arg).short_name);
arg->embed ? c_name(arg).as_member : c_name(arg).short_name);
}
if(!expr->_anonymous_type) OUT(";\n");
......@@ -1237,7 +1237,7 @@ asn1c_lang_C_type_REFERENCE_Value(arg_t *arg) {
if((ref_type->expr_type == ASN_BASIC_INTEGER) ||
(ref_type->expr_type == ASN_BASIC_ENUMERATED)) {
OUT("#define %s_", MKID(ref_type));
OUT("%s\t", MKID(expr));
OUT("%s\t", c_name(arg).base_name);
OUT("((%s)", asn1c_type_name(arg, expr, TNF_CTYPE));
OUT("%s)\n", asn1p_itoa(expr->value->value.v_integer));
}
......
......@@ -5,7 +5,7 @@
#include <asn1fix_export.h>
#include <asn1print.h>
#define MKID(expr) asn1c_make_identifier(0, (expr), 0)
#define MKID(expr) asn1c_make_identifier(AMI_USE_PREFIX, (expr), 0)
/*
* Given the table constraint or component relation constraint
......
......@@ -38,6 +38,16 @@ reserved_keyword(const char *str) {
return 0;
}
const char *
asn1c_prefix()
{
const char *prefix = getenv("ASN1C_PREFIX");
if(!prefix) prefix = "";
return prefix;
}
/*
* Construct identifier from multiple parts.
* Convert unsafe characters to underscores.
......@@ -53,10 +63,13 @@ asn1c_make_identifier(enum ami_flags_e flags, asn1p_expr_t *expr, ...) {
char *first = 0;
ssize_t size = 0;
char *p;
char *prefix = NULL;
const char *prefix = NULL;
char *sptr[4], **psptr = &sptr[0];
int sptr_cnt = 0;
if(flags & AMI_USE_PREFIX)
prefix = asn1c_prefix();
if(expr) {
/*
* Estimate the necessary storage size
......@@ -114,6 +127,7 @@ asn1c_make_identifier(enum ami_flags_e flags, asn1p_expr_t *expr, ...) {
if(prefix) {
strcpy(storage, prefix);
p += strlen(prefix);
nodelimiter = 1;
}
nextstr = "";
for(str = 0; str || nextstr; str = nextstr) {
......@@ -126,6 +140,11 @@ asn1c_make_identifier(enum ami_flags_e flags, asn1p_expr_t *expr, ...) {
if (!first) continue;
}
if(str[0] == '\0') {
nodelimiter = 1; /* No delimiter */
continue;
}
if(str[0] == ' ' && str[1] == '\0') {
*p++ = ' ';
nodelimiter = 1; /* No delimiter */
......@@ -175,6 +194,7 @@ asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format) {
asn1p_expr_t *terminal = 0;
int stdname = 0;
const char *typename;
const char *prefix;
/* Rewind to the topmost parent expression */
if((top_parent = expr->parent_expr))
......@@ -317,28 +337,30 @@ asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format) {
}
}
prefix = stdname ? "" : asn1c_prefix();
switch(_format) {
case TNF_UNMODIFIED:
return asn1c_make_identifier(AMI_MASK_ONLY_SPACES | AMI_NODELIMITER,
0, MODULE_NAME_OF(exprid), exprid ? exprid->Identifier : typename, (char*)0);
return asn1c_make_identifier(AMI_MASK_ONLY_SPACES | AMI_NODELIMITER | (stdname ? 0 : AMI_USE_PREFIX),
0, prefix, MODULE_NAME_OF(exprid), exprid ? exprid->Identifier : typename, (char*)0);
case TNF_INCLUDE:
return asn1c_make_identifier(
AMI_MASK_ONLY_SPACES | AMI_NODELIMITER,
0, ((!stdname || (arg->flags & A1C_INCLUDES_QUOTED))
? "\"" : "<"),
MODULE_NAME_OF(exprid),
prefix, MODULE_NAME_OF(exprid),
exprid ? exprid->Identifier : typename,
((!stdname || (arg->flags & A1C_INCLUDES_QUOTED))
? ".h\"" : ".h>"), (char*)0);
case TNF_SAFE:
return asn1c_make_identifier(0, exprid, typename, (char*)0);
return asn1c_make_identifier(stdname ? 0 : AMI_USE_PREFIX, exprid, typename, (char*)0);
case TNF_CTYPE: /* C type */
case TNF_CONSTYPE: /* C type */
return asn1c_make_identifier(0, exprid,
return asn1c_make_identifier(stdname ? 0 : AMI_USE_PREFIX, exprid,
exprid?"t":typename, exprid?0:"t", (char*)0);
case TNF_RSAFE: /* Recursion-safe type */
return asn1c_make_identifier(AMI_CHECK_RESERVED | AMI_NODELIMITER, 0,
"struct", " ", MODULE_NAME_OF(exprid), typename, (char*)0);
"struct", " ", prefix, MODULE_NAME_OF(exprid), typename, (char*)0);
}
assert(!"unreachable");
......@@ -505,4 +527,3 @@ asn1c_type_fits_long(arg_t *arg, asn1p_expr_t *expr) {
return FL_FITS_SIGNED;
}
......@@ -52,5 +52,6 @@ enum asn1c_fitsfloat_e {
RL_FITS_DOUBLE64
};
enum asn1c_fitsfloat_e asn1c_REAL_fits(arg_t *arg, asn1p_expr_t *expr);
const char *asn1c_prefix(void);
#endif /* ASN1_COMPILER_MISC_H */
#include "asn1c_internal.h"
#include "asn1c_naming.h"
#include "asn1c_misc.h"
#include "asn1c_misc.h"
#include <asn1_buffer.h>
#include <genhash.h>
......@@ -107,20 +106,20 @@ c_name_clash(arg_t *arg) {
static abuf *
construct_base_name(abuf *buf, asn1p_expr_t *expr, int compound_names,
int avoid_keywords) {
int avoid_keywords, enum ami_flags_e flag) {
const char *id;
assert(buf);
if(compound_names && expr->parent_expr) {
construct_base_name(buf, expr->parent_expr, compound_names, 0);
construct_base_name(buf, expr->parent_expr, compound_names, 0, flag);
if(buf->length) {
abuf_str(buf, "__"); /* component separator */
}
}
id = asn1c_make_identifier(
((avoid_keywords && !buf->length) ? AMI_CHECK_RESERVED : 0), expr, 0);
((avoid_keywords && !buf->length) ? AMI_CHECK_RESERVED : 0) | flag, expr, 0);
abuf_str(buf, id);
......@@ -165,7 +164,6 @@ c_name_impl(arg_t *arg, asn1p_expr_t *expr, int avoid_keywords) {
abuf_clear(&b_members_enum);
abuf_clear(&b_members_name);
abuf_str(&b_type_asn_name, asn1c_type_name(arg, expr, TNF_UNMODIFIED));
abuf_str(&b_type_part_name, asn1c_type_name(arg, expr, TNF_SAFE));
abuf_str(&b_type_base_name, asn1c_type_name(arg, expr, TNF_SAFE));
......@@ -183,30 +181,45 @@ c_name_impl(arg_t *arg, asn1p_expr_t *expr, int avoid_keywords) {
}
}
construct_base_name(&b_asn_name, expr, 0, 0);
construct_base_name(&b_part_name, expr, 0, 0);
construct_base_name(&b_base_name, expr, compound_names, avoid_keywords);
construct_base_name(&b_as_member, expr, 0, 1);
construct_base_name(&b_asn_name, expr, 0, 0, 0);
construct_base_name(&b_part_name, expr, 0, 0, AMI_USE_PREFIX);
construct_base_name(&b_base_name, expr, compound_names, avoid_keywords, 0);
construct_base_name(&b_as_member, expr, 0, 1, 0);
static abuf tmp_compoundable_part_name;
static abuf compound_part_name;
abuf_clear(&tmp_compoundable_part_name);
abuf_clear(&compound_part_name);
construct_base_name(&tmp_compoundable_part_name, expr, compound_names, 0);
construct_base_name(&compound_part_name, expr, 1, 0);
if(!expr->_anonymous_type) {
if(arg->embed) {
abuf_printf(&b_short_name, "%s", b_as_member.buffer);
} else {
abuf_printf(&b_short_name, "%s_t", b_as_member.buffer);
construct_base_name(&tmp_compoundable_part_name, expr, compound_names, 0, 0);
construct_base_name(&compound_part_name, expr, 1, 0, 0);
if(strlen(asn1c_prefix()) == 0) {
if(!expr->_anonymous_type) {
if(arg->embed) {
abuf_printf(&b_short_name, "%s", b_as_member.buffer);
} else {
abuf_printf(&b_short_name, "%s_t", b_as_member.buffer);
}
}
abuf_printf(&b_full_name, "struct %s", b_base_name.buffer);
abuf_printf(&b_presence_enum, "enum %s_PR", tmp_compoundable_part_name.buffer);
abuf_printf(&b_presence_name, "%s_PR", tmp_compoundable_part_name.buffer);
abuf_printf(&b_members_enum, "enum %s", b_base_name.buffer);
abuf_printf(&b_members_name, "e_%s", tmp_compoundable_part_name.buffer);
} else {
if(!expr->_anonymous_type) {
if(arg->embed) {
abuf_printf(&b_short_name, "%s%s", asn1c_prefix(), b_as_member.buffer);
} else {
abuf_printf(&b_short_name, "%s%s_t", asn1c_prefix(), b_as_member.buffer);
}
}
abuf_printf(&b_full_name, "struct %s%s", asn1c_prefix(), b_base_name.buffer);
abuf_printf(&b_presence_enum, "enum %s%s_PR", asn1c_prefix(), tmp_compoundable_part_name.buffer);
abuf_printf(&b_presence_name, "%s%s_PR", asn1c_prefix(), tmp_compoundable_part_name.buffer);
abuf_printf(&b_members_enum, "enum %s%s", asn1c_prefix(), b_base_name.buffer);
abuf_printf(&b_members_name, "e_%s%s", asn1c_prefix(), tmp_compoundable_part_name.buffer);
}
abuf_printf(&b_full_name, "struct %s", b_base_name.buffer);
abuf_printf(&b_presence_enum, "enum %s_PR", tmp_compoundable_part_name.buffer);
abuf_printf(&b_presence_name, "%s_PR", tmp_compoundable_part_name.buffer);
abuf_printf(&b_members_enum, "enum %s", b_base_name.buffer);
abuf_printf(&b_members_name, "e_%s", tmp_compoundable_part_name.buffer);
names.type.asn_name = b_type_asn_name.buffer;
names.type.base_name = b_type_base_name.buffer;
......@@ -255,6 +268,7 @@ c_member_name(arg_t *arg, asn1p_expr_t *expr) {
abuf_clear(&ab);
/* NB: do not use part_name, doesn't work for -fcompound-names */
abuf_str(&ab, asn1c_prefix());
abuf_str(&ab, c_name_impl(arg, arg->expr, 0).base_name);
abuf_str(&ab, "_");
abuf_str(&ab, asn1c_make_identifier(0, expr, 0));
......@@ -269,6 +283,7 @@ c_presence_name(arg_t *arg, asn1p_expr_t *expr) {
abuf_clear(&ab);
abuf_str(&ab, asn1c_prefix());
if(expr) {
/* NB: do not use part_name, doesn't work for -fcompound-names */
abuf_str(&ab, c_name_impl(arg, arg->expr, 0).base_name);
......
......@@ -76,7 +76,7 @@ asn1c__save_library_makefile(arg_t *arg, const asn1c_dep_chainset *deps,
[arg->expr->expr_type].type_cb &&
(arg->expr->meta_type != AMT_VALUE)) {
safe_fprintf(mkf, "\t\\\n\t%s%s.c", destdir,
asn1c_make_identifier(AMI_MASK_ONLY_SPACES, arg->expr, 0));
asn1c_make_identifier(AMI_MASK_ONLY_SPACES | AMI_USE_PREFIX, arg->expr, 0));
}
}
}
......@@ -88,7 +88,7 @@ asn1c__save_library_makefile(arg_t *arg, const asn1c_dep_chainset *deps,
(arg->expr->meta_type != AMT_VALUE)) {
safe_fprintf(
mkf, "\t\\\n\t%s%s.h", destdir,
asn1c_make_identifier(AMI_MASK_ONLY_SPACES, arg->expr, 0));
asn1c_make_identifier(AMI_MASK_ONLY_SPACES | AMI_USE_PREFIX, arg->expr, 0));
}
}
}
......@@ -501,7 +501,8 @@ asn1c_save_streams(arg_t *arg, asn1c_dep_chainset *deps, const char *destdir,
return -1;
}
filename = strdup(asn1c_make_identifier(AMI_MASK_ONLY_SPACES, expr, (char*)0));
filename = strdup(asn1c_make_identifier(AMI_MASK_ONLY_SPACES | AMI_USE_PREFIX,
expr, (char*)0));
fp_c = asn1c_open_file(destdir, filename, ".c", &tmpname_c);
if(fp_c == NULL) {
return -1;
......@@ -517,7 +518,7 @@ asn1c_save_streams(arg_t *arg, asn1c_dep_chainset *deps, const char *destdir,
generate_preamble(arg, fp_c, optc, argv);
generate_preamble(arg, fp_h, optc, argv);
header_id = asn1c_make_identifier(0, expr, NULL);
header_id = asn1c_make_identifier(AMI_USE_PREFIX, expr, NULL);
safe_fprintf(fp_h,
"#ifndef\t_%s_H_\n"
"#define\t_%s_H_\n"
......@@ -541,7 +542,7 @@ asn1c_save_streams(arg_t *arg, asn1c_dep_chainset *deps, const char *destdir,
SAVE_STREAM(fp_h, OT_DEPS, "Dependencies", 0);
SAVE_STREAM(fp_h, OT_FWD_DECLS, "Forward declarations", 0);
SAVE_STREAM(fp_h, OT_FWD_DEFS, "Forward definitions", 0);
SAVE_STREAM(fp_h, OT_TYPE_DECLS, expr->Identifier, 0);
SAVE_STREAM(fp_h, OT_TYPE_DECLS, filename, 0);
SAVE_STREAM(fp_h, OT_FUNC_DECLS,"Implementation", 0);
safe_fprintf(fp_h, "\n#ifdef __cplusplus\n}\n#endif\n");
......@@ -797,7 +798,7 @@ generate_pdu_collection(arg_t *arg) {
abuf_printf(buf,
"extern struct asn_TYPE_descriptor_s "
"asn_DEF_%s;\n",
asn1c_make_identifier(0, arg->expr, NULL));
asn1c_make_identifier(AMI_USE_PREFIX, arg->expr, NULL));
}
}
......@@ -822,7 +823,7 @@ generate_pdu_collection(arg_t *arg) {
arg->expr->module->source_file_name);
}
abuf_printf(buf, "\t&asn_DEF_%s,\t\n",
asn1c_make_identifier(0, arg->expr, NULL));
asn1c_make_identifier(AMI_USE_PREFIX, arg->expr, NULL));
}
}
......@@ -960,7 +961,7 @@ generate_constant_collection(arg_t *arg) {
abuf_printf(buf, "/*\n * Generated by asn1c-" VERSION
" (http://lionet.info/asn1c)\n */\n\n");
abuf_printf(buf, "#ifndef _ASN_CONSTANT_H\n#define _ASN_CONSTANT_H\n\n");
abuf_printf(buf, "#ifndef _%sASN_CONSTANT_H\n#define _%sASN_CONSTANT_H\n\n", asn1c_prefix(), asn1c_prefix());
abuf_printf(buf, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n");
......@@ -971,14 +972,14 @@ generate_constant_collection(arg_t *arg) {
if(arg->expr->expr_type == ASN_BASIC_INTEGER) {
abuf_printf(buf, "#define %s (%s)\n",
asn1c_make_identifier(0, arg->expr, 0),
asn1c_make_identifier(AMI_USE_PREFIX, arg->expr, 0),
asn1p_itoa(arg->expr->value->value.v_integer));
empty_file = 0;
}
}
}
abuf_printf(buf, "\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _ASN_CONSTANT_H */\n");
abuf_printf(buf, "\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* _%sASN_CONSTANT_H */\n", asn1c_prefix());
if(empty_file) {
abuf_free(buf);
......@@ -990,15 +991,21 @@ generate_constant_collection(arg_t *arg) {
static int
generate_constant_file(arg_t *arg, const char *destdir) {
abuf *buf = generate_constant_collection(arg);
char *filename;
int filename_len;
if(!buf) return 0;
filename_len = strlen(asn1c_prefix()) + strlen("asn_constant");
filename = calloc(filename_len + 1, 1);
snprintf(filename, filename_len + 1, "%sasn_constant", asn1c_prefix());
if(arg->flags & A1C_PRINT_COMPILED) {
printf("\n/*** <<< asn_constant.h >>> ***/\n\n");
safe_fwrite(buf->buffer, buf->length, 1, stdout);
} else {
FILE *fp = asn1c_open_file(destdir, "asn_constant", ".h", 0);
FILE *fp = asn1c_open_file(destdir, filename, ".h", 0);
if(fp == NULL) {
perror("asn_constant.h");
return -1;
......@@ -1006,8 +1013,8 @@ generate_constant_file(arg_t *arg, const char *destdir) {
safe_fwrite(buf->buffer, buf->length, 1, fp);
fclose(fp);
}
safe_fprintf(stderr, "Generated asn_constant.h\n");
safe_fprintf(stderr, "Generated %s.h\n", filename);
free(filename);
abuf_free(buf);
return 0;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment