hints for run-time parser


git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@25 59561ff5-6e30-0410-9f3c-9617f08c8826
diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c
index 54bd847..4643ae2 100644
--- a/libasn1compiler/asn1c_C.c
+++ b/libasn1compiler/asn1c_C.c
@@ -9,6 +9,8 @@
 typedef struct tag2el_s {
 	struct asn1p_type_tag_s el_tag;
 	int el_no;
+	int toff_first;
+	int toff_last;
 	asn1p_expr_t *from_expr;
 } tag2el_t;
 
@@ -1236,10 +1238,34 @@
 	}
 
 	/*
-	 * Sort the map according to canonical order of their tags.
+	 * Sort the map according to canonical order of their tags
+	 * and element numbers.
 	 */
 	qsort(*tag2el, *count, sizeof(**tag2el), _tag2el_cmp);
 
+	/*
+	 * Initialize .toff_{first|last} members.
+	 */
+	if(*count) {
+		struct asn1p_type_tag_s *cur_tag = 0;
+		tag2el_t *cur = *tag2el;
+		tag2el_t *end = cur + *count;
+		int occur, i;
+		for(occur = 0; cur < end; cur++) {
+			if(cur_tag == 0
+			|| cur_tag->tag_value != cur->el_tag.tag_value
+			|| cur_tag->tag_class != cur->el_tag.tag_class) {
+				cur_tag = &cur->el_tag;
+				occur = 0;
+			} else {
+				occur++;
+			}
+			cur->toff_first = -occur;
+			for(i = 0; i >= -occur; i--)
+				cur[i].toff_last = -i;
+		}
+	}
+
 	return 0;
 }
 
@@ -1315,7 +1341,9 @@
 			OUT("    { ");
 			_print_tag(arg, expr, &tag2el[i].el_tag);
 			OUT(", ");
-			OUT("%d ", tag2el[i].el_no);
+			OUT("%d, ", tag2el[i].el_no);
+			OUT("%d, ", tag2el[i].toff_first);
+			OUT("%d ", tag2el[i].toff_last);
 			OUT("}, /* %s at %d */\n",
 				tag2el[i].from_expr->Identifier,
 				tag2el[i].from_expr->_lineno
diff --git a/skeletons/constr_TYPE.h b/skeletons/constr_TYPE.h
index 5c00104..da3a2db 100644
--- a/skeletons/constr_TYPE.h
+++ b/skeletons/constr_TYPE.h
@@ -89,10 +89,11 @@
 typedef struct asn1_TYPE_tag2member_s {
 	ber_tlv_tag_t el_tag;	/* Outmost tag of the member */
 	int el_no;		/* Index of the associated member, base 0 */
+	int toff_first;		/* First occurence of the el_tag, relative */
+	int toff_last;		/* Last occurence of the el_tag, relatvie */
 } asn1_TYPE_tag2member_t;
 
 
-
 /*
  * This function is a wrapper around (td)->print_struct, which prints out
  * the contents of the target language's structure (struct_ptr) into the
diff --git a/tests/39-sequence-of-OK.asn1.-P b/tests/39-sequence-of-OK.asn1.-P
index b427ae5..d073e49 100644
--- a/tests/39-sequence-of-OK.asn1.-P
+++ b/tests/39-sequence-of-OK.asn1.-P
@@ -79,8 +79,8 @@
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
 static asn1_TYPE_tag2member_t asn1_DEF_T_tag2el[] = {
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0 }, /* int at 15 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 1 }, /* collection at 17 */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* int at 15 */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 1, 0, 0 }, /* collection at 17 */
 };
 static asn1_SEQUENCE_specifics_t asn1_DEF_T_specs = {
 	sizeof(struct T),
@@ -152,8 +152,8 @@
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
 static asn1_TYPE_tag2member_t asn1_DEF_T2_tag2el[] = {
-    { (ASN_TAG_CLASS_UNIVERSAL | (1 << 2)), 0 }, /* flag at 20 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (12 << 2)), 1 }, /* str at 21 */
+    { (ASN_TAG_CLASS_UNIVERSAL | (1 << 2)), 0, 0, 0 }, /* flag at 20 */
+    { (ASN_TAG_CLASS_UNIVERSAL | (12 << 2)), 1, 0, 0 }, /* str at 21 */
 };
 static asn1_SEQUENCE_specifics_t asn1_DEF_T2_specs = {
 	sizeof(struct T2),
diff --git a/tests/42-real-life-OK.asn1.-PR b/tests/42-real-life-OK.asn1.-PR
index d7a6507..0cf1be9 100644
--- a/tests/42-real-life-OK.asn1.-PR
+++ b/tests/42-real-life-OK.asn1.-PR
@@ -83,8 +83,8 @@
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
 static asn1_TYPE_tag2member_t asn1_DEF_LogLine_tag2el[] = {
-    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 1 }, /* varsets at 25 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (22 << 2)), 0 }, /* line-digest at 23 */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 1, 0, 0 }, /* varsets at 25 */
+    { (ASN_TAG_CLASS_UNIVERSAL | (22 << 2)), 0, 0, 0 }, /* line-digest at 23 */
 };
 static asn1_SEQUENCE_specifics_t asn1_DEF_LogLine_specs = {
 	sizeof(struct LogLine),
@@ -197,8 +197,8 @@
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
 static asn1_TYPE_tag2member_t asn1_DEF_VariablePartSet_tag2el[] = {
-    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 0 }, /* vparts at 33 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 1 }, /* resolution at 35 */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 0, 0, 1 }, /* vparts at 33 */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 1, -1, 0 }, /* resolution at 35 */
 };
 static asn1_SEQUENCE_specifics_t asn1_DEF_VariablePartSet_specs = {
 	sizeof(struct VariablePartSet),
@@ -331,8 +331,8 @@
 			(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 		};
 		static asn1_TYPE_tag2member_t asn1_DEF_vrange_tag2el[] = {
-		    { (ASN_TAG_CLASS_UNIVERSAL | (26 << 2)), 0 }, /* from at 45 */
-		    { (ASN_TAG_CLASS_UNIVERSAL | (26 << 2)), 1 }, /* to at 46 */
+		    { (ASN_TAG_CLASS_UNIVERSAL | (26 << 2)), 0, 0, 1 }, /* from at 45 */
+		    { (ASN_TAG_CLASS_UNIVERSAL | (26 << 2)), 1, -1, 0 }, /* to at 46 */
 		};
 		static asn1_SEQUENCE_specifics_t asn1_DEF_vrange_specs = {
 			sizeof(struct vrange),
@@ -380,8 +380,8 @@
 	
 };
 static asn1_TYPE_tag2member_t asn1_DEF_VariablePart_tag2el[] = {
-    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 1 }, /* vrange at 45 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (17 << 2)), 0 }, /* vset at 42 */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 1, 0, 0 }, /* vrange at 45 */
+    { (ASN_TAG_CLASS_UNIVERSAL | (17 << 2)), 0, 0, 0 }, /* vset at 42 */
 };
 static asn1_CHOICE_specifics_t asn1_DEF_VariablePart_specs = {
 	sizeof(struct VariablePart),
@@ -519,8 +519,8 @@
 		(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 	};
 	static asn1_TYPE_tag2member_t asn1_DEF_notify_tag2el[] = {
-	    { (ASN_TAG_CLASS_UNIVERSAL | (1 << 2)), 0 }, /* critical at 61 */
-	    { (ASN_TAG_CLASS_UNIVERSAL | (17 << 2)), 1 }, /* email at 62 */
+	    { (ASN_TAG_CLASS_UNIVERSAL | (1 << 2)), 0, 0, 0 }, /* critical at 61 */
+	    { (ASN_TAG_CLASS_UNIVERSAL | (17 << 2)), 1, 0, 0 }, /* email at 62 */
 	};
 	static asn1_SEQUENCE_specifics_t asn1_DEF_notify_specs = {
 		sizeof(struct notify),
@@ -568,8 +568,8 @@
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
 static asn1_TYPE_tag2member_t asn1_DEF_ActionItem_tag2el[] = {
-    { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 0 }, /* accept-as at 55 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 1 }, /* notify at 61 */
+    { (ASN_TAG_CLASS_UNIVERSAL | (10 << 2)), 0, 0, 0 }, /* accept-as at 55 */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 1, 0, 0 }, /* notify at 61 */
 };
 static asn1_SEQUENCE_specifics_t asn1_DEF_ActionItem_specs = {
 	sizeof(struct ActionItem),