more PER support


git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@1245 59561ff5-6e30-0410-9f3c-9617f08c8826
diff --git a/tests/119-per-strings-OK.asn1 b/tests/119-per-strings-OK.asn1
new file mode 100644
index 0000000..856b51b
--- /dev/null
+++ b/tests/119-per-strings-OK.asn1
@@ -0,0 +1,38 @@
+
+-- OK: Everything is fine
+
+-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1)
+-- .spelio.software.asn1c.test (9363.1.5.1)
+-- .119
+
+ModulePERStrings
+	{ iso org(3) dod(6) internet (1) private(4) enterprise(1)
+		spelio(9363) software(1) asn1c(5) test(1) 119 }
+	DEFINITIONS AUTOMATIC TAGS ::=
+BEGIN
+
+	PDU ::= SEQUENCE {
+		many	SEQUENCE OF PDU			OPTIONAL,
+		ia5	IA5String			OPTIONAL,
+		ia5-c	IA5String (FROM("A".."Z"))	OPTIONAL,
+		ia5-ce	IA5String (FROM("A".."Z",...))	OPTIONAL,
+		ia5-ir	IA5String (FROM("A".."B"|"X".."Z")) OPTIONAL,
+		vs	VisibleString			OPTIONAL,
+		vs-c	VisibleString (FROM("A".."Z"))	OPTIONAL,
+		vs-ce	VisibleString (FROM("A".."Z",...)) OPTIONAL,
+		vs-ir	VisibleString (FROM("A".."B"|"X".."Z")) OPTIONAL,
+		pr	PrintableString			OPTIONAL,
+		pr-c	PrintableString (FROM("A".."Z")) OPTIONAL,
+		pr-ir	PrintableString (FROM("A".."B"|"X".."Z")) OPTIONAL,
+		ns	NumericString			OPTIONAL,
+		ns-c	NumericString (FROM("5".."9"))	OPTIONAL,
+		ns-ce	NumericString (FROM("5".."9",...)) OPTIONAL,
+		ns-ir	NumericString (FROM("1"|"9")) OPTIONAL,
+		ut-c	UTF8String (SIZE(6))		OPTIONAL,
+		ut-ce	UTF8String (SIZE(6,...))	OPTIONAL,
+		ut-ir	UTF8String (FROM("A"|"Z"))	OPTIONAL,
+		real	REAL				OPTIONAL,
+		oid	OBJECT IDENTIFIER		OPTIONAL
+	}
+
+END
diff --git a/tests/50-constraint-OK.asn1.-Pgen-PER b/tests/50-constraint-OK.asn1.-Pgen-PER
index 3e2911d..bb8d0e5 100644
--- a/tests/50-constraint-OK.asn1.-Pgen-PER
+++ b/tests/50-constraint-OK.asn1.-Pgen-PER
@@ -272,15 +272,19 @@
 }
 
 
+/*** <<< CTDEFS [Int2] >>> ***/
+
+static asn_per_constraints_t asn_PER_Int2_constr_1 = {
+	{ APC_SEMI_CONSTRAINED,	-1, -1,  0,  0 }	/* (0..MAX) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [Int2] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_Int2_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
-static asn_per_constraints_t asn_PER_Int2_constr_1 = {
-	{ APC_SEMI_CONSTRAINED,	-1, -1,  0,  0 }	/* (0..MAX) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_Int2 = {
 	"Int2",
 	"Int2",
@@ -441,15 +445,19 @@
 }
 
 
+/*** <<< CTDEFS [Int3] >>> ***/
+
+static asn_per_constraints_t asn_PER_Int3_constr_1 = {
+	{ APC_CONSTRAINED,	 4,  4,  0,  10 }	/* (0..10) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [Int3] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_Int3_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
-static asn_per_constraints_t asn_PER_Int3_constr_1 = {
-	{ APC_CONSTRAINED,	 4,  4,  0,  10 }	/* (0..10) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_Int3 = {
 	"Int3",
 	"Int3",
@@ -610,15 +618,19 @@
 }
 
 
+/*** <<< CTDEFS [Int4] >>> ***/
+
+static asn_per_constraints_t asn_PER_Int4_constr_1 = {
+	{ APC_CONSTRAINED | APC_EXTENSIBLE,  4,  4,  1,  10 }	/* (1..10,...) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [Int4] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_Int4_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
-static asn_per_constraints_t asn_PER_Int4_constr_1 = {
-	{ APC_CONSTRAINED | APC_EXTENSIBLE,  4,  4,  1,  10 }	/* (1..10,...) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_Int4 = {
 	"Int4",
 	"Int4",
@@ -779,15 +791,19 @@
 }
 
 
+/*** <<< CTDEFS [Int5] >>> ***/
+
+static asn_per_constraints_t asn_PER_Int5_constr_1 = {
+	{ APC_CONSTRAINED,	 0,  0,  5,  5 }	/* (5..5) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [Int5] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_Int5_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
-static asn_per_constraints_t asn_PER_Int5_constr_1 = {
-	{ APC_CONSTRAINED,	 0,  0,  5,  5 }	/* (5..5) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_Int5 = {
 	"Int5",
 	"Int5",
@@ -948,15 +964,19 @@
 }
 
 
+/*** <<< CTDEFS [ExtensibleExtensions] >>> ***/
+
+static asn_per_constraints_t asn_PER_ExtensibleExtensions_constr_1 = {
+	{ APC_CONSTRAINED | APC_EXTENSIBLE,  8,  8,  1,  256 }	/* (1..256,...) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [ExtensibleExtensions] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_ExtensibleExtensions_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
-static asn_per_constraints_t asn_PER_ExtensibleExtensions_constr_1 = {
-	{ APC_CONSTRAINED | APC_EXTENSIBLE,  8,  8,  1,  256 }	/* (1..256,...) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_ExtensibleExtensions = {
 	"ExtensibleExtensions",
 	"ExtensibleExtensions",
@@ -1271,15 +1291,19 @@
 }
 
 
+/*** <<< CTDEFS [Str2] >>> ***/
+
+static asn_per_constraints_t asn_PER_Str2_constr_1 = {
+	{ APC_CONSTRAINED,	 7,  7,  0,  127 }	/* (0..127) */,
+	{ APC_CONSTRAINED,	 5,  5,  0,  30 }	/* (SIZE(0..30)) */,
+	0, 0	/* No PER character map necessary */
+};
+
 /*** <<< STAT-DEFS [Str2] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_Str2_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
-static asn_per_constraints_t asn_PER_Str2_constr_1 = {
-	{ APC_CONSTRAINED,	 7,  7,  0,  127 }	/* (0..127) */,
-	{ APC_CONSTRAINED,	 5,  5,  0,  30 }	/* (SIZE(0..30)) */
-};
 asn_TYPE_descriptor_t asn_DEF_Str2 = {
 	"Str2",
 	"Str2",
@@ -1385,6 +1409,16 @@
 	}
 }
 
+static int asn_PER_MAP_Str3_1_v2c(unsigned int value) {
+	if(value >= sizeof(permitted_alphabet_table_1)/sizeof(permitted_alphabet_table_1[0]))
+		return -1;
+	return permitted_alphabet_table_1[value] - 1;
+}
+static int asn_PER_MAP_Str3_1_c2v(unsigned int code) {
+	if(code >= sizeof(permitted_alphabet_code2value_1)/sizeof(permitted_alphabet_code2value_1[0]))
+		return -1;
+	return permitted_alphabet_code2value_1[code];
+}
 /*
  * This type is implemented using Str2,
  * so here we adjust the DEF accordingly.
@@ -1466,15 +1500,20 @@
 }
 
 
+/*** <<< CTDEFS [Str3] >>> ***/
+
+static asn_per_constraints_t asn_PER_Str3_constr_1 = {
+	{ APC_CONSTRAINED,	 3,  3,  65,  102 }	/* (65..102) */,
+	{ APC_CONSTRAINED,	 5,  5,  10,  27 }	/* (SIZE(10..27)) */,
+	asn_PER_MAP_Str3_1_v2c,	/* Value to PER code map */
+	asn_PER_MAP_Str3_1_c2v	/* PER code to value map */
+};
+
 /*** <<< STAT-DEFS [Str3] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_Str3_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
-static asn_per_constraints_t asn_PER_Str3_constr_1 = {
-	{ APC_CONSTRAINED,	 6,  6,  65,  102 }	/* (65..102) */,
-	{ APC_CONSTRAINED,	 5,  5,  10,  27 }	/* (SIZE(10..27)) */
-};
 asn_TYPE_descriptor_t asn_DEF_Str3 = {
 	"Str3",
 	"Str3",
@@ -1644,15 +1683,19 @@
 }
 
 
+/*** <<< CTDEFS [Str4] >>> ***/
+
+static asn_per_constraints_t asn_PER_Str4_constr_1 = {
+	{ APC_CONSTRAINED,	 7,  7,  0,  127 }	/* (0..127) */,
+	{ APC_SEMI_CONSTRAINED,	-1, -1,  0,  0 }	/* (SIZE(0..MAX)) */,
+	0, 0	/* No PER character map necessary */
+};
+
 /*** <<< STAT-DEFS [Str4] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_Str4_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
-static asn_per_constraints_t asn_PER_Str4_constr_1 = {
-	{ APC_CONSTRAINED,	 7,  7,  0,  127 }	/* (0..127) */,
-	{ APC_SEMI_CONSTRAINED,	-1, -1,  0,  0 }	/* (SIZE(0..MAX)) */
-};
 asn_TYPE_descriptor_t asn_DEF_Str4 = {
 	"Str4",
 	"Str4",
@@ -1822,15 +1865,19 @@
 }
 
 
+/*** <<< CTDEFS [PER-Visible] >>> ***/
+
+static asn_per_constraints_t asn_PER_PER_Visible_constr_1 = {
+	{ APC_CONSTRAINED,	 3,  3,  65,  70 }	/* (65..70) */,
+	{ APC_SEMI_CONSTRAINED,	-1, -1,  0,  0 }	/* (SIZE(0..MAX)) */,
+	0, 0	/* No PER character map necessary */
+};
+
 /*** <<< STAT-DEFS [PER-Visible] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_PER_Visible_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
-static asn_per_constraints_t asn_PER_PER_Visible_constr_1 = {
-	{ APC_CONSTRAINED,	 3,  3,  65,  70 }	/* (65..70) */,
-	{ APC_SEMI_CONSTRAINED,	-1, -1,  0,  0 }	/* (SIZE(0..MAX)) */
-};
 asn_TYPE_descriptor_t asn_DEF_PER_Visible = {
 	"PER-Visible",
 	"PER-Visible",
@@ -2000,15 +2047,19 @@
 }
 
 
+/*** <<< CTDEFS [PER-Visible-2] >>> ***/
+
+static asn_per_constraints_t asn_PER_PER_Visible_2_constr_1 = {
+	{ APC_CONSTRAINED,	 1,  1,  69,  70 }	/* (69..70) */,
+	{ APC_SEMI_CONSTRAINED,	-1, -1,  0,  0 }	/* (SIZE(0..MAX)) */,
+	0, 0	/* No PER character map necessary */
+};
+
 /*** <<< STAT-DEFS [PER-Visible-2] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_PER_Visible_2_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
-static asn_per_constraints_t asn_PER_PER_Visible_2_constr_1 = {
-	{ APC_CONSTRAINED,	 1,  1,  69,  70 }	/* (69..70) */,
-	{ APC_SEMI_CONSTRAINED,	-1, -1,  0,  0 }	/* (SIZE(0..MAX)) */
-};
 asn_TYPE_descriptor_t asn_DEF_PER_Visible_2 = {
 	"PER-Visible-2",
 	"PER-Visible-2",
@@ -2178,15 +2229,19 @@
 }
 
 
+/*** <<< CTDEFS [Not-PER-Visible-1] >>> ***/
+
+static asn_per_constraints_t asn_PER_Not_PER_Visible_1_constr_1 = {
+	{ APC_CONSTRAINED,	 3,  3,  65,  70 }	/* (65..70) */,
+	{ APC_SEMI_CONSTRAINED,	-1, -1,  0,  0 }	/* (SIZE(0..MAX)) */,
+	0, 0	/* No PER character map necessary */
+};
+
 /*** <<< STAT-DEFS [Not-PER-Visible-1] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_Not_PER_Visible_1_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
-static asn_per_constraints_t asn_PER_Not_PER_Visible_1_constr_1 = {
-	{ APC_CONSTRAINED,	 3,  3,  65,  70 }	/* (65..70) */,
-	{ APC_SEMI_CONSTRAINED,	-1, -1,  0,  0 }	/* (SIZE(0..MAX)) */
-};
 asn_TYPE_descriptor_t asn_DEF_Not_PER_Visible_1 = {
 	"Not-PER-Visible-1",
 	"Not-PER-Visible-1",
@@ -2356,15 +2411,19 @@
 }
 
 
+/*** <<< CTDEFS [Not-PER-Visible-2] >>> ***/
+
+static asn_per_constraints_t asn_PER_Not_PER_Visible_2_constr_1 = {
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	{ APC_SEMI_CONSTRAINED,	-1, -1,  0,  0 }	/* (SIZE(0..MAX)) */,
+	0, 0	/* No PER character map necessary */
+};
+
 /*** <<< STAT-DEFS [Not-PER-Visible-2] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_Not_PER_Visible_2_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
-static asn_per_constraints_t asn_PER_Not_PER_Visible_2_constr_1 = {
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
-	{ APC_SEMI_CONSTRAINED,	-1, -1,  0,  0 }	/* (SIZE(0..MAX)) */
-};
 asn_TYPE_descriptor_t asn_DEF_Not_PER_Visible_2 = {
 	"Not-PER-Visible-2",
 	"Not-PER-Visible-2",
@@ -2534,15 +2593,19 @@
 }
 
 
+/*** <<< CTDEFS [Not-PER-Visible-3] >>> ***/
+
+static asn_per_constraints_t asn_PER_Not_PER_Visible_3_constr_1 = {
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	{ APC_SEMI_CONSTRAINED,	-1, -1,  0,  0 }	/* (SIZE(0..MAX)) */,
+	0, 0	/* No PER character map necessary */
+};
+
 /*** <<< STAT-DEFS [Not-PER-Visible-3] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_Not_PER_Visible_3_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
-static asn_per_constraints_t asn_PER_Not_PER_Visible_3_constr_1 = {
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
-	{ APC_SEMI_CONSTRAINED,	-1, -1,  0,  0 }	/* (SIZE(0..MAX)) */
-};
 asn_TYPE_descriptor_t asn_DEF_Not_PER_Visible_3 = {
 	"Not-PER-Visible-3",
 	"Not-PER-Visible-3",
@@ -2715,15 +2778,19 @@
 }
 
 
+/*** <<< CTDEFS [SIZE-but-not-FROM] >>> ***/
+
+static asn_per_constraints_t asn_PER_SIZE_but_not_FROM_constr_1 = {
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	{ APC_CONSTRAINED,	 2,  2,  1,  4 }	/* (SIZE(1..4)) */,
+	0, 0	/* No PER character map necessary */
+};
+
 /*** <<< STAT-DEFS [SIZE-but-not-FROM] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_SIZE_but_not_FROM_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
-static asn_per_constraints_t asn_PER_SIZE_but_not_FROM_constr_1 = {
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
-	{ APC_CONSTRAINED,	 2,  2,  1,  4 }	/* (SIZE(1..4)) */
-};
 asn_TYPE_descriptor_t asn_DEF_SIZE_but_not_FROM = {
 	"SIZE-but-not-FROM",
 	"SIZE-but-not-FROM",
@@ -2896,15 +2963,19 @@
 }
 
 
+/*** <<< CTDEFS [SIZE-and-FROM] >>> ***/
+
+static asn_per_constraints_t asn_PER_SIZE_and_FROM_constr_1 = {
+	{ APC_CONSTRAINED,	 2,  2,  65,  68 }	/* (65..68) */,
+	{ APC_CONSTRAINED,	 2,  2,  1,  4 }	/* (SIZE(1..4)) */,
+	0, 0	/* No PER character map necessary */
+};
+
 /*** <<< STAT-DEFS [SIZE-and-FROM] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_SIZE_and_FROM_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
-static asn_per_constraints_t asn_PER_SIZE_and_FROM_constr_1 = {
-	{ APC_CONSTRAINED,	 2,  2,  65,  68 }	/* (65..68) */,
-	{ APC_CONSTRAINED,	 2,  2,  1,  4 }	/* (SIZE(1..4)) */
-};
 asn_TYPE_descriptor_t asn_DEF_SIZE_and_FROM = {
 	"SIZE-and-FROM",
 	"SIZE-and-FROM",
@@ -3074,15 +3145,19 @@
 }
 
 
+/*** <<< CTDEFS [Neither-SIZE-nor-FROM] >>> ***/
+
+static asn_per_constraints_t asn_PER_Neither_SIZE_nor_FROM_constr_1 = {
+	{ APC_CONSTRAINED,	 3,  3,  65,  70 }	/* (65..70) */,
+	{ APC_SEMI_CONSTRAINED,	-1, -1,  0,  0 }	/* (SIZE(0..MAX)) */,
+	0, 0	/* No PER character map necessary */
+};
+
 /*** <<< STAT-DEFS [Neither-SIZE-nor-FROM] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_Neither_SIZE_nor_FROM_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
-static asn_per_constraints_t asn_PER_Neither_SIZE_nor_FROM_constr_1 = {
-	{ APC_CONSTRAINED,	 3,  3,  65,  70 }	/* (65..70) */,
-	{ APC_SEMI_CONSTRAINED,	-1, -1,  0,  0 }	/* (SIZE(0..MAX)) */
-};
 asn_TYPE_descriptor_t asn_DEF_Neither_SIZE_nor_FROM = {
 	"Neither-SIZE-nor-FROM",
 	"Neither-SIZE-nor-FROM",
@@ -3246,15 +3321,19 @@
 }
 
 
+/*** <<< CTDEFS [Utf8-4] >>> ***/
+
+static asn_per_constraints_t asn_PER_Utf8_4_constr_1 = {
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [Utf8-4] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_Utf8_4_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (12 << 2))
 };
-static asn_per_constraints_t asn_PER_Utf8_4_constr_1 = {
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_Utf8_4 = {
 	"Utf8-4",
 	"Utf8-4",
@@ -3313,12 +3392,6 @@
  0,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,	/*  abcdefghijklmno */
 42,43,44,45,46,47,48,49,50,51,52, 0, 0, 0, 0, 0,	/* pqrstuvwxyz      */
 };
-static int permitted_alphabet_code2value_1[52] = {
-65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,
-81,82,83,84,85,86,87,88,89,90,97,98,99,100,101,102,
-103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,
-119,120,121,122,};
-
 
 static int check_permitted_alphabet_1(const void *sptr) {
 	int *table = permitted_alphabet_table_1;
@@ -3452,15 +3525,19 @@
 }
 
 
+/*** <<< CTDEFS [Utf8-3] >>> ***/
+
+static asn_per_constraints_t asn_PER_Utf8_3_constr_1 = {
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [Utf8-3] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_Utf8_3_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (12 << 2))
 };
-static asn_per_constraints_t asn_PER_Utf8_3_constr_1 = {
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_Utf8_3 = {
 	"Utf8-3",
 	"Utf8-3",
@@ -3622,15 +3699,19 @@
 }
 
 
+/*** <<< CTDEFS [Utf8-2] >>> ***/
+
+static asn_per_constraints_t asn_PER_Utf8_2_constr_1 = {
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [Utf8-2] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_Utf8_2_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (12 << 2))
 };
-static asn_per_constraints_t asn_PER_Utf8_2_constr_1 = {
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_Utf8_2 = {
 	"Utf8-2",
 	"Utf8-2",
@@ -4223,6 +4304,29 @@
 }
 
 
+/*** <<< CTDEFS [Sequence] >>> ***/
+
+static asn_per_constraints_t asn_PER_enum_c_constr_6 = {
+	{ APC_CONSTRAINED | APC_EXTENSIBLE,  1,  1,  0,  1 }	/* (0..1,...) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+static asn_per_constraints_t asn_PER_int1_c_constr_2 = {
+	{ APC_SEMI_CONSTRAINED,	-1, -1, -2,  0 }	/* (-2..MAX) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+static asn_per_constraints_t asn_PER_int4_c_constr_4 = {
+	{ APC_CONSTRAINED,	 2,  2,  5,  7 }	/* (5..7) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+static asn_per_constraints_t asn_PER_int5_c_constr_13 = {
+	{ APC_CONSTRAINED,	 0,  0,  5,  5 }	/* (5..5) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [Sequence] >>> ***/
 
 static int asn_DFL_2_set_3(int set_value, void **sptr) {
@@ -4285,10 +4389,6 @@
 static ber_tlv_tag_t asn_DEF_enum_c_tags_6[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
 };
-static asn_per_constraints_t asn_PER_enum_c_constr_6 = {
-	{ APC_CONSTRAINED | APC_EXTENSIBLE,  1,  1,  0,  1 }	/* (0..1,...) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 static /* Use -fall-defs-global to expose */
 asn_TYPE_descriptor_t asn_DEF_enum_c_6 = {
 	"enum-c",
@@ -4314,29 +4414,13 @@
 	&asn_SPC_enum_c_specs_6	/* Additional specs */
 };
 
-static asn_per_constraints_t asn_PER_memb_int1_c_constr_2 = {
-	{ APC_SEMI_CONSTRAINED,	-1, -1, -2,  0 }	/* (-2..MAX) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
-static asn_per_constraints_t asn_PER_memb_int4_c_constr_4 = {
-	{ APC_CONSTRAINED,	 2,  2,  5,  7 }	/* (5..7) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
-static asn_per_constraints_t asn_PER_memb_enum_c_constr_6 = {
-	{ APC_CONSTRAINED | APC_EXTENSIBLE,  1,  1,  0,  1 }	/* (0..1,...) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
-static asn_per_constraints_t asn_PER_memb_int5_c_constr_13 = {
-	{ APC_CONSTRAINED,	 0,  0,  5,  5 }	/* (5..5) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 static asn_TYPE_member_t asn_MBR_Sequence_1[] = {
 	{ ATF_POINTER, 1, offsetof(struct Sequence, int1_c),
 		.tag = (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
 		.tag_mode = 0,
 		.type = &asn_DEF_Int1,
 		.memb_constraints = memb_int1_c_constraint_1,
-		.per_constraints = &asn_PER_memb_int1_c_constr_2,
+		.per_constraints = &asn_PER_int1_c_constr_2,
 		.default_value = asn_DFL_2_set_3,	/* DEFAULT 3 */
 		.name = "int1-c"
 		},
@@ -4354,7 +4438,7 @@
 		.tag_mode = 0,
 		.type = &asn_DEF_Int4,
 		.memb_constraints = memb_int4_c_constraint_1,
-		.per_constraints = &asn_PER_memb_int4_c_constr_4,
+		.per_constraints = &asn_PER_int4_c_constr_4,
 		.default_value = 0,
 		.name = "int4-c"
 		},
@@ -4372,7 +4456,7 @@
 		.tag_mode = 0,
 		.type = &asn_DEF_enum_c_6,
 		.memb_constraints = 0,	/* Defer constraints checking to the member type */
-		.per_constraints = &asn_PER_memb_enum_c_constr_6,
+		.per_constraints = &asn_PER_enum_c_constr_6,
 		.default_value = 0,
 		.name = "enum-c"
 		},
@@ -4390,7 +4474,7 @@
 		.tag_mode = 0,
 		.type = &asn_DEF_Int5,
 		.memb_constraints = memb_int5_c_constraint_1,
-		.per_constraints = &asn_PER_memb_int5_c_constr_13,
+		.per_constraints = &asn_PER_int5_c_constr_13,
 		.default_value = 0,
 		.name = "int5-c"
 		},
@@ -4470,6 +4554,14 @@
 
 #include "Sequence.h"
 
+/*** <<< CTDEFS [SequenceOf] >>> ***/
+
+static asn_per_constraints_t asn_PER_SequenceOf_constr_1 = {
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	{ APC_CONSTRAINED,	 1,  1,  1,  2 }	/* (SIZE(1..2)) */,
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [SequenceOf] >>> ***/
 
 static asn_TYPE_member_t asn_MBR_SequenceOf_1[] = {
@@ -4491,10 +4583,6 @@
 	offsetof(struct SequenceOf, _asn_ctx),
 	0,	/* XER encoding is XMLDelimitedItemList */
 };
-static asn_per_constraints_t asn_PER_SequenceOf_constr_1 = {
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
-	{ APC_CONSTRAINED,	 1,  1,  1,  2 }	/* (SIZE(1..2)) */
-};
 asn_TYPE_descriptor_t asn_DEF_SequenceOf = {
 	"SequenceOf",
 	"SequenceOf",
@@ -4640,6 +4728,14 @@
 }
 
 
+/*** <<< CTDEFS [Enum0] >>> ***/
+
+static asn_per_constraints_t asn_PER_Enum0_constr_1 = {
+	{ APC_CONSTRAINED,	 1,  1,  0,  1 }	/* (0..1) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [Enum0] >>> ***/
 
 static asn_INTEGER_enum_map_t asn_MAP_Enum0_value2enum_1[] = {
@@ -4660,10 +4756,6 @@
 static ber_tlv_tag_t asn_DEF_Enum0_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
 };
-static asn_per_constraints_t asn_PER_Enum0_constr_1 = {
-	{ APC_CONSTRAINED,	 1,  1,  0,  1 }	/* (0..1) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_Enum0 = {
 	"Enum0",
 	"Enum0",
@@ -4825,6 +4917,14 @@
 }
 
 
+/*** <<< CTDEFS [Enum1] >>> ***/
+
+static asn_per_constraints_t asn_PER_Enum1_constr_1 = {
+	{ APC_CONSTRAINED,	 1,  1,  0,  1 }	/* (0..1) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [Enum1] >>> ***/
 
 static asn_INTEGER_enum_map_t asn_MAP_Enum1_value2enum_1[] = {
@@ -4845,10 +4945,6 @@
 static ber_tlv_tag_t asn_DEF_Enum1_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
 };
-static asn_per_constraints_t asn_PER_Enum1_constr_1 = {
-	{ APC_CONSTRAINED,	 1,  1,  0,  1 }	/* (0..1) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_Enum1 = {
 	"Enum1",
 	"Enum1",
@@ -4959,6 +5055,16 @@
 	}
 }
 
+static int asn_PER_MAP_Identifier_1_v2c(unsigned int value) {
+	if(value >= sizeof(permitted_alphabet_table_1)/sizeof(permitted_alphabet_table_1[0]))
+		return -1;
+	return permitted_alphabet_table_1[value] - 1;
+}
+static int asn_PER_MAP_Identifier_1_c2v(unsigned int code) {
+	if(code >= sizeof(permitted_alphabet_code2value_1)/sizeof(permitted_alphabet_code2value_1[0]))
+		return -1;
+	return permitted_alphabet_code2value_1[code];
+}
 /*
  * This type is implemented using VisibleString,
  * so here we adjust the DEF accordingly.
@@ -5040,15 +5146,20 @@
 }
 
 
+/*** <<< CTDEFS [Identifier] >>> ***/
+
+static asn_per_constraints_t asn_PER_Identifier_constr_1 = {
+	{ APC_CONSTRAINED,	 6,  6,  36,  122 }	/* (36..122) */,
+	{ APC_CONSTRAINED,	 5,  5,  1,  32 }	/* (SIZE(1..32)) */,
+	asn_PER_MAP_Identifier_1_v2c,	/* Value to PER code map */
+	asn_PER_MAP_Identifier_1_c2v	/* PER code to value map */
+};
+
 /*** <<< STAT-DEFS [Identifier] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_Identifier_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (26 << 2))
 };
-static asn_per_constraints_t asn_PER_Identifier_constr_1 = {
-	{ APC_CONSTRAINED,	 7,  7,  36,  122 }	/* (36..122) */,
-	{ APC_CONSTRAINED,	 5,  5,  1,  32 }	/* (SIZE(1..32)) */
-};
 asn_TYPE_descriptor_t asn_DEF_Identifier = {
 	"Identifier",
 	"Identifier",
diff --git a/tests/90-cond-int-type-OK.asn1.-Pgen-PER b/tests/90-cond-int-type-OK.asn1.-Pgen-PER
index bd2f6e9..6fac764 100644
--- a/tests/90-cond-int-type-OK.asn1.-Pgen-PER
+++ b/tests/90-cond-int-type-OK.asn1.-Pgen-PER
@@ -267,15 +267,19 @@
 }
 
 
+/*** <<< CTDEFS [CN-IntegerMinMax] >>> ***/
+
+static asn_per_constraints_t asn_PER_CN_IntegerMinMax_constr_1 = {
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [CN-IntegerMinMax] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_CN_IntegerMinMax_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
-static asn_per_constraints_t asn_PER_CN_IntegerMinMax_constr_1 = {
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_CN_IntegerMinMax = {
 	"CN-IntegerMinMax",
 	"CN-IntegerMinMax",
@@ -436,15 +440,19 @@
 }
 
 
+/*** <<< CTDEFS [CN-IntegerMinLow] >>> ***/
+
+static asn_per_constraints_t asn_PER_CN_IntegerMinLow_constr_1 = {
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }	/* (MIN..1) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [CN-IntegerMinLow] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_CN_IntegerMinLow_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
-static asn_per_constraints_t asn_PER_CN_IntegerMinLow_constr_1 = {
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }	/* (MIN..1) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_CN_IntegerMinLow = {
 	"CN-IntegerMinLow",
 	"CN-IntegerMinLow",
@@ -605,15 +613,19 @@
 }
 
 
+/*** <<< CTDEFS [NO-IntegerMinHigh] >>> ***/
+
+static asn_per_constraints_t asn_PER_NO_IntegerMinHigh_constr_1 = {
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }	/* (MIN..3000000000) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [NO-IntegerMinHigh] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_NO_IntegerMinHigh_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
-static asn_per_constraints_t asn_PER_NO_IntegerMinHigh_constr_1 = {
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }	/* (MIN..3000000000) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_NO_IntegerMinHigh = {
 	"NO-IntegerMinHigh",
 	"NO-IntegerMinHigh",
@@ -774,15 +786,19 @@
 }
 
 
+/*** <<< CTDEFS [NO-IntegerLowHigh] >>> ***/
+
+static asn_per_constraints_t asn_PER_NO_IntegerLowHigh_constr_1 = {
+	{ APC_CONSTRAINED,	 32, -1,  1,  3000000000 }	/* (1..3000000000) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [NO-IntegerLowHigh] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_NO_IntegerLowHigh_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
-static asn_per_constraints_t asn_PER_NO_IntegerLowHigh_constr_1 = {
-	{ APC_CONSTRAINED,	 32, -1,  1,  3000000000 }	/* (1..3000000000) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_NO_IntegerLowHigh = {
 	"NO-IntegerLowHigh",
 	"NO-IntegerLowHigh",
@@ -943,15 +959,19 @@
 }
 
 
+/*** <<< CTDEFS [CN-IntegerLowMax] >>> ***/
+
+static asn_per_constraints_t asn_PER_CN_IntegerLowMax_constr_1 = {
+	{ APC_SEMI_CONSTRAINED,	-1, -1,  1,  0 }	/* (1..MAX) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [CN-IntegerLowMax] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_CN_IntegerLowMax_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
-static asn_per_constraints_t asn_PER_CN_IntegerLowMax_constr_1 = {
-	{ APC_SEMI_CONSTRAINED,	-1, -1,  1,  0 }	/* (1..MAX) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_CN_IntegerLowMax = {
 	"CN-IntegerLowMax",
 	"CN-IntegerLowMax",
@@ -1112,15 +1132,19 @@
 }
 
 
+/*** <<< CTDEFS [NO-IntegerHighMax] >>> ***/
+
+static asn_per_constraints_t asn_PER_NO_IntegerHighMax_constr_1 = {
+	{ APC_SEMI_CONSTRAINED,	-1, -1,  3000000000,  0 }	/* (3000000000..MAX) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [NO-IntegerHighMax] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_NO_IntegerHighMax_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
-static asn_per_constraints_t asn_PER_NO_IntegerHighMax_constr_1 = {
-	{ APC_SEMI_CONSTRAINED,	-1, -1,  3000000000,  0 }	/* (3000000000..MAX) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_NO_IntegerHighMax = {
 	"NO-IntegerHighMax",
 	"NO-IntegerHighMax",
@@ -1281,15 +1305,19 @@
 }
 
 
+/*** <<< CTDEFS [NO-IntegerLowestMax] >>> ***/
+
+static asn_per_constraints_t asn_PER_NO_IntegerLowestMax_constr_1 = {
+	{ APC_SEMI_CONSTRAINED,	-1, -1, -3000000000,  0 }	/* (-3000000000..MAX) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [NO-IntegerLowestMax] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_NO_IntegerLowestMax_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
-static asn_per_constraints_t asn_PER_NO_IntegerLowestMax_constr_1 = {
-	{ APC_SEMI_CONSTRAINED,	-1, -1, -3000000000,  0 }	/* (-3000000000..MAX) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_NO_IntegerLowestMax = {
 	"NO-IntegerLowestMax",
 	"NO-IntegerLowestMax",
@@ -1450,15 +1478,19 @@
 }
 
 
+/*** <<< CTDEFS [NO-IntegerOutRange] >>> ***/
+
+static asn_per_constraints_t asn_PER_NO_IntegerOutRange_constr_1 = {
+	{ APC_CONSTRAINED,	 1, -1,  3000000000,  3000000001 }	/* (3000000000..3000000001) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [NO-IntegerOutRange] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_NO_IntegerOutRange_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
-static asn_per_constraints_t asn_PER_NO_IntegerOutRange_constr_1 = {
-	{ APC_CONSTRAINED,	 1, -1,  3000000000,  3000000001 }	/* (3000000000..3000000001) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_NO_IntegerOutRange = {
 	"NO-IntegerOutRange",
 	"NO-IntegerOutRange",
@@ -1619,15 +1651,19 @@
 }
 
 
+/*** <<< CTDEFS [NO-IntegerOutValue] >>> ***/
+
+static asn_per_constraints_t asn_PER_NO_IntegerOutValue_constr_1 = {
+	{ APC_CONSTRAINED,	 0, -1,  3000000000,  3000000000 }	/* (3000000000..3000000000) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [NO-IntegerOutValue] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_NO_IntegerOutValue_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
-static asn_per_constraints_t asn_PER_NO_IntegerOutValue_constr_1 = {
-	{ APC_CONSTRAINED,	 0, -1,  3000000000,  3000000000 }	/* (3000000000..3000000000) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_NO_IntegerOutValue = {
 	"NO-IntegerOutValue",
 	"NO-IntegerOutValue",
@@ -1782,15 +1818,19 @@
 }
 
 
+/*** <<< CTDEFS [OK-IntegerInRange1] >>> ***/
+
+static asn_per_constraints_t asn_PER_OK_IntegerInRange1_constr_1 = {
+	{ APC_CONSTRAINED,	 8,  8, -100,  100 }	/* (-100..100) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [OK-IntegerInRange1] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_OK_IntegerInRange1_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
-static asn_per_constraints_t asn_PER_OK_IntegerInRange1_constr_1 = {
-	{ APC_CONSTRAINED,	 8,  8, -100,  100 }	/* (-100..100) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_OK_IntegerInRange1 = {
 	"OK-IntegerInRange1",
 	"OK-IntegerInRange1",
@@ -1945,15 +1985,19 @@
 }
 
 
+/*** <<< CTDEFS [OK-IntegerInRange2] >>> ***/
+
+static asn_per_constraints_t asn_PER_OK_IntegerInRange2_constr_1 = {
+	{ APC_CONSTRAINED,	 8,  8, -100,  100 }	/* (-100..100) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [OK-IntegerInRange2] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_OK_IntegerInRange2_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
-static asn_per_constraints_t asn_PER_OK_IntegerInRange2_constr_1 = {
-	{ APC_CONSTRAINED,	 8,  8, -100,  100 }	/* (-100..100) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_OK_IntegerInRange2 = {
 	"OK-IntegerInRange2",
 	"OK-IntegerInRange2",
@@ -2108,15 +2152,19 @@
 }
 
 
+/*** <<< CTDEFS [OK-IntegerInRange3] >>> ***/
+
+static asn_per_constraints_t asn_PER_OK_IntegerInRange3_constr_1 = {
+	{ APC_CONSTRAINED,	 32, -1, -2147483648,  2147483647 }	/* (-2147483648..2147483647) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [OK-IntegerInRange3] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_OK_IntegerInRange3_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
-static asn_per_constraints_t asn_PER_OK_IntegerInRange3_constr_1 = {
-	{ APC_CONSTRAINED,	 32, -1, -2147483648,  2147483647 }	/* (-2147483648..2147483647) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_OK_IntegerInRange3 = {
 	"OK-IntegerInRange3",
 	"OK-IntegerInRange3",
@@ -2271,15 +2319,19 @@
 }
 
 
+/*** <<< CTDEFS [OK-IntegerInRange4] >>> ***/
+
+static asn_per_constraints_t asn_PER_OK_IntegerInRange4_constr_1 = {
+	{ APC_CONSTRAINED,	 32, -1, -2147483648,  2147483647 }	/* (-2147483648..2147483647) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [OK-IntegerInRange4] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_OK_IntegerInRange4_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
-static asn_per_constraints_t asn_PER_OK_IntegerInRange4_constr_1 = {
-	{ APC_CONSTRAINED,	 32, -1, -2147483648,  2147483647 }	/* (-2147483648..2147483647) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_OK_IntegerInRange4 = {
 	"OK-IntegerInRange4",
 	"OK-IntegerInRange4",
@@ -2440,15 +2492,19 @@
 }
 
 
+/*** <<< CTDEFS [OK-IntegerInRange5] >>> ***/
+
+static asn_per_constraints_t asn_PER_OK_IntegerInRange5_constr_1 = {
+	{ APC_CONSTRAINED | APC_EXTENSIBLE,  32, -1, -2147483648,  2147483647 }	/* (-2147483648..2147483647,...) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [OK-IntegerInRange5] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_OK_IntegerInRange5_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
-static asn_per_constraints_t asn_PER_OK_IntegerInRange5_constr_1 = {
-	{ APC_CONSTRAINED | APC_EXTENSIBLE,  32, -1, -2147483648,  2147483647 }	/* (-2147483648..2147483647,...) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_OK_IntegerInRange5 = {
 	"OK-IntegerInRange5",
 	"OK-IntegerInRange5",
@@ -2609,15 +2665,19 @@
 }
 
 
+/*** <<< CTDEFS [NO-IntegerInRange6] >>> ***/
+
+static asn_per_constraints_t asn_PER_NO_IntegerInRange6_constr_1 = {
+	{ APC_CONSTRAINED,	 32, -1,  0,  4294967295 }	/* (0..4294967295) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [NO-IntegerInRange6] >>> ***/
 
 static ber_tlv_tag_t asn_DEF_NO_IntegerInRange6_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
-static asn_per_constraints_t asn_PER_NO_IntegerInRange6_constr_1 = {
-	{ APC_CONSTRAINED,	 32, -1,  0,  4294967295 }	/* (0..4294967295) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_NO_IntegerInRange6 = {
 	"NO-IntegerInRange6",
 	"NO-IntegerInRange6",
diff --git a/tests/95-choice-per-order-OK.asn1.-Pgen-PER b/tests/95-choice-per-order-OK.asn1.-Pgen-PER
index 2256b5b..b542976 100644
--- a/tests/95-choice-per-order-OK.asn1.-Pgen-PER
+++ b/tests/95-choice-per-order-OK.asn1.-Pgen-PER
@@ -56,6 +56,19 @@
 
 extern asn_TYPE_descriptor_t asn_DEF_Choice;
 
+/*** <<< CTDEFS [Choice] >>> ***/
+
+static asn_per_constraints_t asn_PER_ch_constr_4 = {
+	{ APC_CONSTRAINED,	 1,  1,  0,  1 }	/* (0..1) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+static asn_per_constraints_t asn_PER_Choice_constr_1 = {
+	{ APC_CONSTRAINED | APC_EXTENSIBLE,  2,  2,  0,  2 }	/* (0..2,...) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [Choice] >>> ***/
 
 static asn_TYPE_member_t asn_MBR_ch_4[] = {
@@ -93,10 +106,6 @@
 	.canonical_order = asn_MAP_ch_cmap_4,	/* Canonically sorted */
 	.ext_start = -1	/* Extensions start */
 };
-static asn_per_constraints_t asn_PER_ch_constr_4 = {
-	{ APC_CONSTRAINED,	 1,  1,  0,  1 }	/* (0..1) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 static /* Use -fall-defs-global to expose */
 asn_TYPE_descriptor_t asn_DEF_ch_4 = {
 	"ch",
@@ -121,10 +130,6 @@
 	&asn_SPC_ch_specs_4	/* Additional specs */
 };
 
-static asn_per_constraints_t asn_PER_memb_ch_constr_4 = {
-	{ APC_CONSTRAINED,	 1,  1,  0,  1 }	/* (0..1) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 static asn_TYPE_member_t asn_MBR_Choice_1[] = {
 	{ ATF_NOFLAGS, 0, offsetof(struct Choice, choice.roid),
 		.tag = (ASN_TAG_CLASS_UNIVERSAL | (13 << 2)),
@@ -149,7 +154,7 @@
 		.tag_mode = 0,
 		.type = &asn_DEF_ch_4,
 		.memb_constraints = 0,	/* Defer constraints checking to the member type */
-		.per_constraints = &asn_PER_memb_ch_constr_4,
+		.per_constraints = &asn_PER_ch_constr_4,
 		.default_value = 0,
 		.name = "ch"
 		},
@@ -181,10 +186,6 @@
 	.canonical_order = asn_MAP_Choice_cmap_1,	/* Canonically sorted */
 	.ext_start = 3	/* Extensions start */
 };
-static asn_per_constraints_t asn_PER_Choice_constr_1 = {
-	{ APC_CONSTRAINED | APC_EXTENSIBLE,  2,  2,  0,  2 }	/* (0..2,...) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_Choice = {
 	"Choice",
 	"Choice",
@@ -240,6 +241,14 @@
 
 extern asn_TYPE_descriptor_t asn_DEF_Choice2;
 
+/*** <<< CTDEFS [Choice2] >>> ***/
+
+static asn_per_constraints_t asn_PER_Choice2_constr_1 = {
+	{ APC_CONSTRAINED,	 1,  1,  0,  1 }	/* (0..1) */,
+	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 },
+	0, 0	/* No PER value map */
+};
+
 /*** <<< STAT-DEFS [Choice2] >>> ***/
 
 static asn_TYPE_member_t asn_MBR_Choice2_1[] = {
@@ -276,10 +285,6 @@
 	.canonical_order = 0,
 	.ext_start = -1	/* Extensions start */
 };
-static asn_per_constraints_t asn_PER_Choice2_constr_1 = {
-	{ APC_CONSTRAINED,	 1,  1,  0,  1 }	/* (0..1) */,
-	{ APC_UNCONSTRAINED,	-1, -1,  0,  0 }
-};
 asn_TYPE_descriptor_t asn_DEF_Choice2 = {
 	"Choice2",
 	"Choice2",