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.
diff --git a/libasn1compiler/asn1c_misc.c b/libasn1compiler/asn1c_misc.c
index 9fb2eff..498b120 100644
--- a/libasn1compiler/asn1c_misc.c
+++ b/libasn1compiler/asn1c_misc.c
@@ -50,6 +50,10 @@
 	char *second = 0;
 	ssize_t size;
 	char *p;
+	char *prefix = NULL;
+
+	if (flags & AMI_USE_PREFIX)
+		prefix = getenv("ASN1C_PREFIX");
 
 	if(expr) {
 		/*
@@ -74,6 +78,8 @@
 	va_end(ap);
 	if(size == -1) return NULL;
 
+	if(prefix)
+		size += 1 + strlen(prefix);
 	/*
 	 * Make sure we have this amount of storage.
 	 */
@@ -93,8 +99,12 @@
 	 */
 	va_start(ap, expr);
 	p = storage;
+	if(prefix) {
+		strcpy(storage, prefix);
+		p += strlen(prefix);
+	}
 	nextstr = "";
-	for(p = storage, str = 0; str || nextstr; str = nextstr) {
+	for(str = 0; str || nextstr; str = nextstr) {
 		int subst_made = 0;
 		nextstr = second ? second : va_arg(ap, char *);
 
@@ -262,23 +272,34 @@
 
 	switch(_format) {
 	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);
-	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(
 			AMI_MASK_ONLY_SPACES | AMI_NODELIMITER,
 			0, ((!stdname || (arg->flags & A1C_INCLUDES_QUOTED))
-				? "\"" : "<"),
+				? "\"" : "<"), stdname ? "" : prefix,
 			exprid ? exprid->Identifier : typename,
 			((!stdname || (arg->flags & A1C_INCLUDES_QUOTED))
 				? ".h\"" : ".h>"), 0);
+		}
 	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 */
-		return asn1c_make_identifier(0, exprid,
-				exprid?"t":typename, exprid?0:"t", 0);
+		return asn1c_make_identifier(stdname ? 0 : AMI_USE_PREFIX,
+				exprid, exprid?"t":typename, exprid?0:"t", 0);
 	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);
 	}
 
diff --git a/libasn1compiler/asn1c_misc.h b/libasn1compiler/asn1c_misc.h
index ee88cb1..4489ae1 100644
--- a/libasn1compiler/asn1c_misc.h
+++ b/libasn1compiler/asn1c_misc.h
@@ -10,6 +10,7 @@
   AMI_MASK_ONLY_SPACES	= 1,	/* Mask only spaces, everything else's safe */
   AMI_CHECK_RESERVED	= 2,	/* Check against reserved keywords */
   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, ...);
 
diff --git a/libasn1fix/asn1fix.c b/libasn1fix/asn1fix.c
index 8d2317f..6165873 100644
--- a/libasn1fix/asn1fix.c
+++ b/libasn1fix/asn1fix.c
@@ -245,10 +245,19 @@
 	asn1p_expr_t *expr;
 	int rvalue = 0;
 	int ret;
+	char *prefix = getenv("ASN1C_PREFIX");
 
 	TQ_FOR(expr, &(arg->mod->members), next) {
 		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.
 		 */