diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c index 54bd847e..4643ae2d 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 @@ _fill_tag2el_map(arg_t *arg, tag2el_t **tag2el, int *count, int el_no) { } /* - * 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 @@ emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count) { 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 5c001049..da3a2db7 100644 --- a/skeletons/constr_TYPE.h +++ b/skeletons/constr_TYPE.h @@ -89,10 +89,11 @@ typedef struct asn1_TYPE_descriptor_s { 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 b427ae5a..d073e49f 100644 --- a/tests/39-sequence-of-OK.asn1.-P +++ b/tests/39-sequence-of-OK.asn1.-P @@ -79,8 +79,8 @@ static ber_tlv_tag_t asn1_DEF_T_tags[] = { (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 @@ static ber_tlv_tag_t asn1_DEF_T2_tags[] = { (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 d7a65078..0cf1be94 100644 --- a/tests/42-real-life-OK.asn1.-PR +++ b/tests/42-real-life-OK.asn1.-PR @@ -83,8 +83,8 @@ static ber_tlv_tag_t asn1_DEF_LogLine_tags[] = { (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 @@ static ber_tlv_tag_t asn1_DEF_VariablePartSet_tags[] = { (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 @@ typedef struct VariablePart { (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 ber_tlv_tag_t asn1_DEF_VariablePart_tags[] = { }; 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 @@ typedef struct ActionItem { (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 @@ static ber_tlv_tag_t asn1_DEF_ActionItem_tags[] = { (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),