diff --git a/asn1c/tests/check-132.-fnative-types.-gen-PER.c b/asn1c/tests/check-132.-fnative-types.-gen-PER.c new file mode 100644 index 0000000000000000000000000000000000000000..d4037a54b15b18e141e81ad208b5d128aee67165 --- /dev/null +++ b/asn1c/tests/check-132.-fnative-types.-gen-PER.c @@ -0,0 +1,63 @@ +#undef NDEBUG +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <assert.h> +#include <ctype.h> +#include <errno.h> + +#include <T.h> + +static void +verify(int testNo, T_t *ti) { + asn_enc_rval_t er; + asn_dec_rval_t rv; + unsigned char buf[2]; + T_t *to = 0; + + er = uper_encode_to_buffer(&asn_DEF_T, ti, buf, sizeof buf); + fprintf(stderr, "%d IN: %d => %d\n", testNo, + ti->present, (int)er.encoded); + assert(er.encoded >= 1 && er.encoded <= 8 * sizeof(buf)); + + rv = uper_decode(0, &asn_DEF_T, (void *)&to, buf, sizeof buf, 0, 0); + assert(rv.code == RC_OK); + + fprintf(stderr, "%d ENC: %2x%2x\n", testNo, + buf[0], buf[1]); + fprintf(stderr, "%d OUT: %d\n", testNo, ti->present); + assert(ti->present == to->present); + if(ti->present == T_PR_second) { + assert(ti->choice.second == to->choice.second); + } else { + assert(ti->choice.first.present == to->choice.first.present); + assert(ti->choice.first.choice.nothing == to->choice.first.choice.nothing); + } + + xer_fprint(stderr, &asn_DEF_T, ti); + xer_fprint(stderr, &asn_DEF_T, to); +} + +int main() { + T_t t; + + memset(&t, 0, sizeof(t)); + t.present = T_PR_first; + t.choice.first.present = first_PR_nothing; + t.choice.first.choice.nothing = 5; + verify(0, &t); + + memset(&t, 0, sizeof(t)); + t.present = T_PR_first; + t.choice.first.present = first_PR_nothing; + t.choice.first.choice.nothing = 6; + verify(1, &t); + + memset(&t, 0, sizeof(t)); + t.present = T_PR_second; + t.choice.second = 7; + verify(2, &t); + + return 0; +} diff --git a/skeletons/constr_CHOICE.c b/skeletons/constr_CHOICE.c index a9eb7194196ead287a748c2e70f6774030197671..2be69ab0eae7d90b32050f823f70097a5fdb338a 100644 --- a/skeletons/constr_CHOICE.c +++ b/skeletons/constr_CHOICE.c @@ -913,6 +913,7 @@ CHOICE_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraint_t *ct; void *memb_ptr; int present; + int present_enc; if(!sptr) _ASN_ENCODE_FAILED; @@ -934,15 +935,17 @@ CHOICE_encode_uper(asn_TYPE_descriptor_t *td, else present--; + ASN_DEBUG("Encoding %s CHOICE element %d", td->name, present); + /* Adjust if canonical order is different from natural order */ if(specs->canonical_order) - present = specs->canonical_order[present]; - - ASN_DEBUG("Encoding %s CHOICE element %d", td->name, present); + present_enc = specs->canonical_order[present]; + else + present_enc = present; if(ct && ct->range_bits >= 0) { - if(present < ct->lower_bound - || present > ct->upper_bound) { + if(present_enc < ct->lower_bound + || present_enc > ct->upper_bound) { if(ct->flags & APC_EXTENSIBLE) { if(per_put_few_bits(po, 1, 1)) _ASN_ENCODE_FAILED; @@ -966,7 +969,7 @@ CHOICE_encode_uper(asn_TYPE_descriptor_t *td, } if(ct && ct->range_bits >= 0) { - if(per_put_few_bits(po, present, ct->range_bits)) + if(per_put_few_bits(po, present_enc, ct->range_bits)) _ASN_ENCODE_FAILED; return elm->type->uper_encoder(elm->type, elm->per_constraints, @@ -975,7 +978,7 @@ CHOICE_encode_uper(asn_TYPE_descriptor_t *td, asn_enc_rval_t rval; if(specs->ext_start == -1) _ASN_ENCODE_FAILED; - if(uper_put_nsnnwn(po, present - specs->ext_start)) + if(uper_put_nsnnwn(po, present_enc - specs->ext_start)) _ASN_ENCODE_FAILED; if(uper_open_type_put(elm->type, elm->per_constraints, memb_ptr, po)) diff --git a/tests/132-per-choice-OK.asn1 b/tests/132-per-choice-OK.asn1 new file mode 100644 index 0000000000000000000000000000000000000000..8cbdb48c90fea2f7fae7f4244512d0905eec2701 --- /dev/null +++ b/tests/132-per-choice-OK.asn1 @@ -0,0 +1,21 @@ + +-- OK: Everything is fine + +-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1) +-- .spelio.software.asn1c.test (9363.1.5.1) +-- .132 + +ModulePERChoice + { iso org(3) dod(6) internet (1) private(4) enterprise(1) + spelio(9363) software(1) asn1c(5) test(1) 132 } + DEFINITIONS AUTOMATIC TAGS ::= +BEGIN + + T ::= CHOICE { + first [1] CHOICE { + nothing INTEGER (5..10) + }, + second [0] INTEGER (-10..10) + } + +END