prefixing of 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 commit is contained in:
Harald Welte 2015-09-10 09:31:18 +02:00 committed by Neels Hofmeyr
parent 840ee6d2c7
commit 5e2364f614
3 changed files with 39 additions and 8 deletions

View File

@ -50,6 +50,10 @@ asn1c_make_identifier(enum ami_flags_e flags, asn1p_expr_t *expr, ...) {
char *second = 0; char *second = 0;
ssize_t size; ssize_t size;
char *p; char *p;
char *prefix = NULL;
if (flags & AMI_USE_PREFIX)
prefix = getenv("ASN1C_PREFIX");
if(expr) { if(expr) {
/* /*
@ -74,6 +78,8 @@ asn1c_make_identifier(enum ami_flags_e flags, asn1p_expr_t *expr, ...) {
va_end(ap); va_end(ap);
if(size == -1) return NULL; if(size == -1) return NULL;
if(prefix)
size += 1 + strlen(prefix);
/* /*
* Make sure we have this amount of storage. * Make sure we have this amount of storage.
*/ */
@ -93,8 +99,12 @@ asn1c_make_identifier(enum ami_flags_e flags, asn1p_expr_t *expr, ...) {
*/ */
va_start(ap, expr); va_start(ap, expr);
p = storage; p = storage;
if(prefix) {
strcpy(storage, prefix);
p += strlen(prefix);
}
nextstr = ""; nextstr = "";
for(p = storage, str = 0; str || nextstr; str = nextstr) { for(str = 0; str || nextstr; str = nextstr) {
int subst_made = 0; int subst_made = 0;
nextstr = second ? second : va_arg(ap, char *); nextstr = second ? second : va_arg(ap, char *);
@ -262,23 +272,34 @@ asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format) {
switch(_format) { switch(_format) {
case TNF_UNMODIFIED: case TNF_UNMODIFIED:
return asn1c_make_identifier(AMI_MASK_ONLY_SPACES, return asn1c_make_identifier(stdname ? AMI_MASK_ONLY_SPACES :
AMI_MASK_ONLY_SPACES | AMI_USE_PREFIX,
0, exprid ? exprid->Identifier : typename, 0); 0, exprid ? exprid->Identifier : typename, 0);
case TNF_INCLUDE: case TNF_INCLUDE: {
/* as we have the quote marks " or < preceding the type
* name, we cannot simply have asn1c_make_identifier
* generate the prefix. Then we would end up with
* strings like PREFIX_<foo.h>" */
char *prefix = getenv("ASN1C_PREFIX");
if (!prefix)
prefix = "";
return asn1c_make_identifier( return asn1c_make_identifier(
AMI_MASK_ONLY_SPACES | AMI_NODELIMITER, AMI_MASK_ONLY_SPACES | AMI_NODELIMITER,
0, ((!stdname || (arg->flags & A1C_INCLUDES_QUOTED)) 0, ((!stdname || (arg->flags & A1C_INCLUDES_QUOTED))
? "\"" : "<"), ? "\"" : "<"), stdname ? "" : prefix,
exprid ? exprid->Identifier : typename, exprid ? exprid->Identifier : typename,
((!stdname || (arg->flags & A1C_INCLUDES_QUOTED)) ((!stdname || (arg->flags & A1C_INCLUDES_QUOTED))
? ".h\"" : ".h>"), 0); ? ".h\"" : ".h>"), 0);
}
case TNF_SAFE: case TNF_SAFE:
return asn1c_make_identifier(0, exprid, typename, 0); return asn1c_make_identifier(stdname ? 0 : AMI_USE_PREFIX,
exprid, typename, 0);
case TNF_CTYPE: /* C type */ case TNF_CTYPE: /* C type */
return asn1c_make_identifier(0, exprid, return asn1c_make_identifier(stdname ? 0 : AMI_USE_PREFIX,
exprid?"t":typename, exprid?0:"t", 0); exprid, exprid?"t":typename, exprid?0:"t", 0);
case TNF_RSAFE: /* Recursion-safe type */ case TNF_RSAFE: /* Recursion-safe type */
return asn1c_make_identifier(AMI_CHECK_RESERVED, 0, return asn1c_make_identifier(stdname ? AMI_CHECK_RESERVED :
AMI_CHECK_RESERVED | AMI_USE_PREFIX, 0,
"struct", " ", typename, 0); "struct", " ", typename, 0);
} }

View File

@ -10,6 +10,7 @@ enum ami_flags_e {
AMI_MASK_ONLY_SPACES = 1, /* Mask only spaces, everything else's safe */ AMI_MASK_ONLY_SPACES = 1, /* Mask only spaces, everything else's safe */
AMI_CHECK_RESERVED = 2, /* Check against reserved keywords */ AMI_CHECK_RESERVED = 2, /* Check against reserved keywords */
AMI_NODELIMITER = 4, /* Do not put delimiter, just concatenate */ 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, ...); char *asn1c_make_identifier(enum ami_flags_e, asn1p_expr_t *expr, ...);

View File

@ -245,10 +245,19 @@ asn1f_fix_module__phase_2(arg_t *arg) {
asn1p_expr_t *expr; asn1p_expr_t *expr;
int rvalue = 0; int rvalue = 0;
int ret; int ret;
char *prefix = getenv("ASN1C_PREFIX");
TQ_FOR(expr, &(arg->mod->members), next) { TQ_FOR(expr, &(arg->mod->members), next) {
arg->expr = expr; arg->expr = expr;
if (prefix) {
char *tmp = malloc(strlen(prefix)+strlen(expr->Identifier)+1);
sprintf(tmp, "%s%s", prefix, expr->Identifier);
expr->Identifier = tmp;
/* FIXME: what about old memory ? */
#warning "Fix this memory leak"
}
/* /*
* Dereference DEFAULT values. * Dereference DEFAULT values.
*/ */