mirror of https://gerrit.osmocom.org/asn1c
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:
parent
840ee6d2c7
commit
5e2364f614
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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, ...);
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue