Compiler support for tagged parametrized members.


git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@894 59561ff5-6e30-0410-9f3c-9617f08c8826
diff --git a/ChangeLog b/ChangeLog
index 27ee638..3103354 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,9 @@
 
-0.9.15: 2005-May-17
+0.9.15: 2005-June-01
 
 	* Compiler now checks 64-bit overflows in constraints range handling
 	  code. No effect on the code produced by the compiler.
+	* Compiler support for tagged parametrized members.
 	* Empty tags to element map avoided.
 
 0.9.14:	2005-Apr-29
diff --git a/libasn1fix/asn1fix_constr.c b/libasn1fix/asn1fix_constr.c
index e16c9e0..b71d874 100644
--- a/libasn1fix/asn1fix_constr.c
+++ b/libasn1fix/asn1fix_constr.c
@@ -419,6 +419,7 @@
 		|| ta.tag_value == -1	/* Spread IMAGINARY ANY tag... */
 		|| tb.tag_value == -1	/* ...it is an evil virus, fear it! */
 		) {
+			char tagbuf[2][TAG2STRING_BUFFER_SIZE];
 			char *p = (a->expr_type == A1TC_EXTENSIBLE)
 				?"potentially ":"";
 			FATAL("Processing %s at line %d: component \"%s\" at line %d %shas the same tag "
@@ -431,6 +432,12 @@
 				b->Identifier,
 				b->_lineno
 			);
+			DEBUG("Tags: %s %s  vs.  %s %s",
+				asn1p_tag2string(&ta, tagbuf[0]),
+				a->Identifier,
+				asn1p_tag2string(&tb, tagbuf[1]),
+				b->Identifier
+			);
 			if((arg->mod->module_flags & MSF_EXTENSIBILITY_IMPLIED)
 			&& (a->expr_type == A1TC_EXTENSIBLE)
 			&& (b->expr_type == A1TC_EXTENSIBLE)) {
diff --git a/libasn1fix/asn1fix_param.c b/libasn1fix/asn1fix_param.c
index 3fdaf30..8c9ce41 100644
--- a/libasn1fix/asn1fix_param.c
+++ b/libasn1fix/asn1fix_param.c
@@ -60,12 +60,22 @@
 
 #define	SUBSTITUTE(to, from)	do {				\
 		asn1p_expr_t tmp, *__v;				\
+		if((to)->tag.tag_class				\
+		&& (from)->tag.tag_class) {			\
+			FATAL("Layered tagging "		\
+			"in parametrization "			\
+			"is not yet supported, "		\
+			"contact asn1c author for");		\
+			return -1;				\
+		}						\
 		tmp = *(to);					\
 		*(to) = *(from);				\
 		TQ_MOVE(&(to)->members, &(from)->members);	\
 		*(from) = tmp;					\
 		(to)->next = tmp.next;				\
 		(to)->parent_expr = tmp.parent_expr;		\
+		if(tmp.tag.tag_class)				\
+			(to)->tag = tmp.tag;			\
 		memset(&((from)->next), 0,			\
 			sizeof((from)->next));			\
 		memset(&((from)->members), 0,			\
diff --git a/libasn1parser/asn1p_expr.c b/libasn1parser/asn1p_expr.c
index c3c31f2..5e2aa34 100644
--- a/libasn1parser/asn1p_expr.c
+++ b/libasn1parser/asn1p_expr.c
@@ -142,3 +142,41 @@
 	}
 }
 
+
+char *asn1p_tag2string(struct asn1p_type_tag_s *tag, char *buf) {
+	static buf_stat[TAG2STRING_BUFFER_SIZE];
+	char *start;
+	char *end;
+
+	if(!buf) buf = buf_stat;
+	start = buf;
+	end = buf + TAG2STRING_BUFFER_SIZE;
+
+	if(tag->tag_class == TC_NOCLASS) {
+		*buf = 0;
+		return buf;
+	}
+
+	strcpy(buf, "[");
+	switch(tag->tag_class) {
+	case TC_NOCLASS:
+		assert(tag->tag_class != TC_NOCLASS);
+		break;
+	case TC_UNIVERSAL:	strcat(buf, "UNIVERSAL ");	break;
+	case TC_PRIVATE:	strcat(buf, "PRIVATE ");	break;
+	case TC_APPLICATION:	strcat(buf, "APPLICATION ");	break;
+	case TC_CONTEXT_SPECIFIC:
+		break;
+	}
+	buf += snprintf(buf + strlen(buf), end - buf,
+		"%" PRIdASN "]", tag->tag_value);
+	assert((buf - end) > sizeof(" IMPLICIT "));
+
+	switch(tag->tag_mode) {
+	case TM_DEFAULT: break;
+	case TM_IMPLICIT: strcat(buf, " IMPLICIT"); break;
+	case TM_EXPLICIT: strcat(buf, " EXPLICIT"); break;
+	}
+
+	return start;
+}
diff --git a/libasn1parser/asn1p_expr.h b/libasn1parser/asn1p_expr.h
index 34a9e7a..18692c1 100644
--- a/libasn1parser/asn1p_expr.h
+++ b/libasn1parser/asn1p_expr.h
@@ -242,4 +242,7 @@
 void asn1p_expr_add(asn1p_expr_t *to, asn1p_expr_t *what);
 void asn1p_expr_free(asn1p_expr_t *expr);
 
+#define	TAG2STRING_BUFFER_SIZE	64	/* buf should be at least this big */
+char *asn1p_tag2string(struct asn1p_type_tag_s *tag, char *opt_buf);
+
 #endif	/* ASN1_PARSER_EXPR_H */
diff --git a/libasn1print/asn1print.c b/libasn1print/asn1print.c
index 1a44ef0..0a07378 100644
--- a/libasn1print/asn1print.c
+++ b/libasn1print/asn1print.c
@@ -168,27 +168,7 @@
 
 	(void)flags;	/* Unused argument */
 
-	if(tag->tag_class == TC_NOCLASS)
-		return 0;
-
-	printf("[");
-	switch(tag->tag_class) {
-	case TC_NOCLASS:
-		assert(tag->tag_class != TC_NOCLASS);
-		break;
-	case TC_UNIVERSAL:	printf("UNIVERSAL ");	break;
-	case TC_PRIVATE:	printf("PRIVATE ");	break;
-	case TC_APPLICATION:	printf("APPLICATION ");	break;
-	case TC_CONTEXT_SPECIFIC:
-		break;
-	}
-	printf("%" PRIdASN "]", tag->tag_value);
-
-	switch(tag->tag_mode) {
-	case TM_DEFAULT: break;
-	case TM_IMPLICIT: printf(" IMPLICIT"); break;
-	case TM_EXPLICIT: printf(" EXPLICIT"); break;
-	}
+	printf("%s", asn1p_tag2string(tag, 0));
 
 	return 0;
 }