aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLev Walkin <vlm@lionet.info>2010-10-25 00:10:34 -0700
committerLev Walkin <vlm@lionet.info>2010-10-25 00:10:34 -0700
commitffe79f445099764490217e07622f535b887b2c84 (patch)
treef9bad460af8fc9ddd11ddf28b696dbeebe618dec
parenta6dd57a927459e7a517833d41ba3565057f9b859 (diff)
Enumeration constraints relaxed
-rw-r--r--ChangeLog1
-rw-r--r--asn1c/tests/check-03.c62
-rw-r--r--libasn1fix/asn1fix_enum.c72
-rw-r--r--tests/03-enum-OK.asn115
-rw-r--r--tests/03-enum-OK.asn1.-EF47
-rw-r--r--tests/03-enum-OK.asn1.-P798
-rw-r--r--tests/128-enum-SE.asn116
-rw-r--r--tests/129-enum-OK.asn116
-rw-r--r--tests/129-enum-OK.asn1.-EF12
-rw-r--r--tests/129-enum-SE.asn116
-rw-r--r--tests/130-enum-OK.asn116
-rw-r--r--tests/130-enum-OK.asn1.-EF13
12 files changed, 1075 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 3c964b35..312b6072 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,7 @@
* Added -fincludes-quoted to asn1c to generate #includes in "double"
instead of <angle> quotes.
* PER encoding correctness fix. Reported by Grzegorz Aksamit.
+ * ENUMERATED extension values check relaxed. Reported by Gabriel Burca.
0.9.22: 2008-Nov-19
diff --git a/asn1c/tests/check-03.c b/asn1c/tests/check-03.c
new file mode 100644
index 00000000..a821675e
--- /dev/null
+++ b/asn1c/tests/check-03.c
@@ -0,0 +1,62 @@
+#undef NDEBUG
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <string.h>
+#include <assert.h>
+
+#include "Enum2.h"
+#include "xer_decoder.h"
+
+static char buf[4096];
+static int buf_offset;
+
+static int
+buf_writer(const void *buffer, size_t size, void *app_key) {
+ char *b, *bend;
+ (void)app_key;
+ assert(buf_offset + size < sizeof(buf));
+ memcpy(buf + buf_offset, buffer, size);
+ b = buf + buf_offset;
+ bend = b + size;
+ buf_offset += size;
+ return 0;
+}
+
+static void
+check_xer(e_Enum2 eval, char *xer_string) {
+ asn_dec_rval_t rv;
+ char buf2[128];
+ Enum2_t *e = 0;
+ long val;
+
+ rv = xer_decode(0, &asn_DEF_Enum2, (void **)&e,
+ xer_string, strlen(xer_string));
+ assert(rv.code == RC_OK);
+ assert(rv.consumed == strlen(xer_string));
+
+ asn_INTEGER2long(e, &val);
+ printf("%s -> %ld == %d\n", xer_string, val, eval);
+ assert(val == eval);
+
+ buf_offset = 0;
+ xer_encode(&asn_DEF_Enum2, e, XER_F_CANONICAL, buf_writer, 0);
+ buf[buf_offset] = 0;
+ sprintf(buf2, "<Enum2>%s</Enum2>", xer_string);
+ printf("%ld -> %s == %s\n", eval, buf, buf2);
+ assert(0 == strcmp(buf, buf2));
+}
+
+int
+main() {
+
+ check_xer(Enum2_red, "<red/>");
+ check_xer(Enum2_green, "<green/>");
+ check_xer(Enum2_blue, "<blue/>");
+ check_xer(Enum2_orange, "<orange/>");
+ check_xer(Enum2_alpha, "<alpha/>");
+ check_xer(Enum2_beta, "<beta/>");
+ check_xer(Enum2_gamma, "<gamma/>");
+
+ return 0;
+}
diff --git a/libasn1fix/asn1fix_enum.c b/libasn1fix/asn1fix_enum.c
index 570d23ae..399cb625 100644
--- a/libasn1fix/asn1fix_enum.c
+++ b/libasn1fix/asn1fix_enum.c
@@ -8,15 +8,27 @@ asn1f_fix_enum(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *ev;
asn1c_integer_t max_value = -1;
+ asn1c_integer_t max_value_ext = -1;
int rvalue = 0;
asn1p_expr_t *ext_marker = NULL; /* "..." position */
int ret;
+ /* Keep track of value collisions */
+ asn1c_integer_t *used_vals;
+ int used_vals_sz = 50;
+ int used_vals_next = 0;
+
if(expr->expr_type != ASN_BASIC_ENUMERATED)
return 0; /* Just ignore it */
DEBUG("(%s)", expr->Identifier);
+ used_vals = (asn1c_integer_t *) malloc(sizeof(asn1c_integer_t) * used_vals_sz);
+ if (!used_vals) {
+ FATAL("Out of memory");
+ return -1;
+ }
+
/*
* 1. Scan the enumeration values in search for inconsistencies.
*/
@@ -93,12 +105,16 @@ asn1f_fix_enum(arg_t *arg) {
/*
* 1.3 Check the applicability of this value.
*/
- if(eval <= max_value) {
- if(ext_marker) {
- /*
- * Enumeration is allowed to be unordered
- * before the first marker.
- */
+
+ /*
+ * Enumeration is allowed to be unordered
+ * before the first marker, but after the marker
+ * the values must be ordered.
+ */
+ if (ext_marker) {
+ if (eval > max_value_ext) {
+ max_value_ext = eval;
+ } else {
FATAL(
"Enumeration %s at line %d: "
"Explicit value \"%s(%" PRIdASN ")\" "
@@ -108,21 +124,59 @@ asn1f_fix_enum(arg_t *arg) {
ev->_lineno,
ev->Identifier,
eval,
- max_value);
+ max_value_ext);
rvalue = -1;
}
- } else if(eval > max_value) {
+ }
+
+ if (eval > max_value) {
max_value = eval;
}
+
+ /*
+ * 1.4 Check that all identifiers are unique
+ */
+ int unique = 1;
+ int uv_idx;
+ for (uv_idx = 0; uv_idx < used_vals_next; uv_idx++) {
+ if (used_vals[uv_idx] == eval) {
+ FATAL(
+ "Enumeration %s at line %d: "
+ "Explicit value \"%s(%" PRIdASN ")\" "
+ "collides with previous values",
+ expr->Identifier,
+ ev->_lineno,
+ ev->Identifier,
+ eval);
+ rvalue = -1;
+ unique = 0;
+ }
+ }
+
+ if (unique) {
+ /* Grow the array if needed */
+ if (used_vals_next >= used_vals_sz) {
+ asn1c_integer_t *temp;
+ int new_sz = used_vals_sz + 50;
+ temp = (asn1c_integer_t *) realloc(used_vals,
+ sizeof(asn1c_integer_t) * new_sz);
+ if (!temp) return -1;
+ used_vals = temp;
+ used_vals_sz = new_sz;
+ }
+ used_vals[used_vals_next++] = eval;
+ }
+
/*
- * 1.4 Check that all identifiers before the current one
+ * 1.5 Check that all identifiers before the current one
* differs from it.
*/
ret = asn1f_check_unique_expr_child(arg, ev, 0, "identifier");
RET2RVAL(ret, rvalue);
}
+ free(used_vals);
/*
* 2. Reorder the first half (before optional "...") of the
diff --git a/tests/03-enum-OK.asn1 b/tests/03-enum-OK.asn1
index 567df26a..a8570a9d 100644
--- a/tests/03-enum-OK.asn1
+++ b/tests/03-enum-OK.asn1
@@ -19,4 +19,19 @@ BEGIN
... -- extensible --
}
+ Enum2 ::= ENUMERATED
+ { red, -- will be 0 --
+ green, -- will be 1 --
+ blue(45),
+ orange(23), -- Does not have to be ordered --
+ alpha,
+ ..., -- extensible --
+ beta(12), -- May be less than the max value in the root --
+ gamma(103) -- Must be ordered --
+ }
+
+ Enum3 ::= ENUMERATED { a, b(3), ..., c(1) }
+ Enum4 ::= ENUMERATED { a, b, ..., c(3), d }
+ Enum5 ::= ENUMERATED { a, z(25), ..., d }
+
END
diff --git a/tests/03-enum-OK.asn1.-EF b/tests/03-enum-OK.asn1.-EF
new file mode 100644
index 00000000..761736ff
--- /dev/null
+++ b/tests/03-enum-OK.asn1.-EF
@@ -0,0 +1,47 @@
+ModuleTestEnum1 { iso org(3) dod(6) internet(1) private(4) enterprise(1)
+ spelio(9363) software(1) asn1c(5) test(1) 3 }
+DEFINITIONS ::=
+BEGIN
+
+Enum1 ::= ENUMERATED {
+ red(0),
+ green(1),
+ blue(4),
+ alpha(5),
+ ...
+}
+
+Enum2 ::= ENUMERATED {
+ red(0),
+ green(1),
+ blue(45),
+ orange(23),
+ alpha(46),
+ ...,
+ beta(12),
+ gamma(103)
+}
+
+Enum3 ::= ENUMERATED {
+ a(0),
+ b(3),
+ ...,
+ c(1)
+}
+
+Enum4 ::= ENUMERATED {
+ a(0),
+ b(1),
+ ...,
+ c(3),
+ d(4)
+}
+
+Enum5 ::= ENUMERATED {
+ a(0),
+ z(25),
+ ...,
+ d(26)
+}
+
+END
diff --git a/tests/03-enum-OK.asn1.-P b/tests/03-enum-OK.asn1.-P
new file mode 100644
index 00000000..d2e8ad0f
--- /dev/null
+++ b/tests/03-enum-OK.asn1.-P
@@ -0,0 +1,798 @@
+
+/*** <<< INCLUDES [Enum1] >>> ***/
+
+#include <ENUMERATED.h>
+
+/*** <<< DEPS [Enum1] >>> ***/
+
+typedef enum Enum1 {
+ Enum1_red = 0,
+ Enum1_green = 1,
+ Enum1_blue = 4,
+ Enum1_alpha = 5
+ /*
+ * Enumeration is extensible
+ */
+} e_Enum1;
+
+/*** <<< TYPE-DECLS [Enum1] >>> ***/
+
+typedef ENUMERATED_t Enum1_t;
+
+/*** <<< FUNC-DECLS [Enum1] >>> ***/
+
+extern asn_TYPE_descriptor_t asn_DEF_Enum1;
+asn_struct_free_f Enum1_free;
+asn_struct_print_f Enum1_print;
+asn_constr_check_f Enum1_constraint;
+ber_type_decoder_f Enum1_decode_ber;
+der_type_encoder_f Enum1_encode_der;
+xer_type_decoder_f Enum1_decode_xer;
+xer_type_encoder_f Enum1_encode_xer;
+
+/*** <<< CODE [Enum1] >>> ***/
+
+int
+Enum1_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ /* Replace with underlying type checker */
+ td->check_constraints = asn_DEF_ENUMERATED.check_constraints;
+ return td->check_constraints(td, sptr, ctfailcb, app_key);
+}
+
+/*
+ * This type is implemented using ENUMERATED,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+Enum1_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+ td->free_struct = asn_DEF_ENUMERATED.free_struct;
+ td->print_struct = asn_DEF_ENUMERATED.print_struct;
+ td->ber_decoder = asn_DEF_ENUMERATED.ber_decoder;
+ td->der_encoder = asn_DEF_ENUMERATED.der_encoder;
+ td->xer_decoder = asn_DEF_ENUMERATED.xer_decoder;
+ td->xer_encoder = asn_DEF_ENUMERATED.xer_encoder;
+ td->uper_decoder = asn_DEF_ENUMERATED.uper_decoder;
+ td->uper_encoder = asn_DEF_ENUMERATED.uper_encoder;
+ if(!td->per_constraints)
+ td->per_constraints = asn_DEF_ENUMERATED.per_constraints;
+ td->elements = asn_DEF_ENUMERATED.elements;
+ td->elements_count = asn_DEF_ENUMERATED.elements_count;
+ /* td->specifics = asn_DEF_ENUMERATED.specifics; // Defined explicitly */
+}
+
+void
+Enum1_free(asn_TYPE_descriptor_t *td,
+ void *struct_ptr, int contents_only) {
+ Enum1_1_inherit_TYPE_descriptor(td);
+ td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+Enum1_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+ int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+ Enum1_1_inherit_TYPE_descriptor(td);
+ return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+Enum1_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const void *bufptr, size_t size, int tag_mode) {
+ Enum1_1_inherit_TYPE_descriptor(td);
+ return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+Enum1_encode_der(asn_TYPE_descriptor_t *td,
+ void *structure, int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ Enum1_1_inherit_TYPE_descriptor(td);
+ return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+Enum1_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+ Enum1_1_inherit_TYPE_descriptor(td);
+ return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+Enum1_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ Enum1_1_inherit_TYPE_descriptor(td);
+ return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+
+/*** <<< STAT-DEFS [Enum1] >>> ***/
+
+static asn_INTEGER_enum_map_t asn_MAP_Enum1_value2enum_1[] = {
+ { 0, 3, "red" },
+ { 1, 5, "green" },
+ { 4, 4, "blue" },
+ { 5, 5, "alpha" }
+ /* This list is extensible */
+};
+static unsigned int asn_MAP_Enum1_enum2value_1[] = {
+ 3, /* alpha(5) */
+ 2, /* blue(4) */
+ 1, /* green(1) */
+ 0 /* red(0) */
+ /* This list is extensible */
+};
+static asn_INTEGER_specifics_t asn_SPC_Enum1_specs_1 = {
+ asn_MAP_Enum1_value2enum_1, /* "tag" => N; sorted by tag */
+ asn_MAP_Enum1_enum2value_1, /* N => "tag"; sorted by N */
+ 4, /* Number of elements in the maps */
+ 5, /* Extensions before this member */
+ 1, /* Strict enumeration */
+ 0, /* Native long size */
+ 0
+};
+static ber_tlv_tag_t asn_DEF_Enum1_tags_1[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_Enum1 = {
+ "Enum1",
+ "Enum1",
+ Enum1_free,
+ Enum1_print,
+ Enum1_constraint,
+ Enum1_decode_ber,
+ Enum1_encode_der,
+ Enum1_decode_xer,
+ Enum1_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_Enum1_tags_1,
+ sizeof(asn_DEF_Enum1_tags_1)
+ /sizeof(asn_DEF_Enum1_tags_1[0]), /* 1 */
+ asn_DEF_Enum1_tags_1, /* Same as above */
+ sizeof(asn_DEF_Enum1_tags_1)
+ /sizeof(asn_DEF_Enum1_tags_1[0]), /* 1 */
+ 0, /* No PER visible constraints */
+ 0, 0, /* Defined elsewhere */
+ &asn_SPC_Enum1_specs_1 /* Additional specs */
+};
+
+
+/*** <<< INCLUDES [Enum2] >>> ***/
+
+#include <ENUMERATED.h>
+
+/*** <<< DEPS [Enum2] >>> ***/
+
+typedef enum Enum2 {
+ Enum2_red = 0,
+ Enum2_green = 1,
+ Enum2_blue = 45,
+ Enum2_orange = 23,
+ Enum2_alpha = 46,
+ /*
+ * Enumeration is extensible
+ */
+ Enum2_beta = 12,
+ Enum2_gamma = 103
+} e_Enum2;
+
+/*** <<< TYPE-DECLS [Enum2] >>> ***/
+
+typedef ENUMERATED_t Enum2_t;
+
+/*** <<< FUNC-DECLS [Enum2] >>> ***/
+
+extern asn_TYPE_descriptor_t asn_DEF_Enum2;
+asn_struct_free_f Enum2_free;
+asn_struct_print_f Enum2_print;
+asn_constr_check_f Enum2_constraint;
+ber_type_decoder_f Enum2_decode_ber;
+der_type_encoder_f Enum2_encode_der;
+xer_type_decoder_f Enum2_decode_xer;
+xer_type_encoder_f Enum2_encode_xer;
+
+/*** <<< CODE [Enum2] >>> ***/
+
+int
+Enum2_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ /* Replace with underlying type checker */
+ td->check_constraints = asn_DEF_ENUMERATED.check_constraints;
+ return td->check_constraints(td, sptr, ctfailcb, app_key);
+}
+
+/*
+ * This type is implemented using ENUMERATED,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+Enum2_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+ td->free_struct = asn_DEF_ENUMERATED.free_struct;
+ td->print_struct = asn_DEF_ENUMERATED.print_struct;
+ td->ber_decoder = asn_DEF_ENUMERATED.ber_decoder;
+ td->der_encoder = asn_DEF_ENUMERATED.der_encoder;
+ td->xer_decoder = asn_DEF_ENUMERATED.xer_decoder;
+ td->xer_encoder = asn_DEF_ENUMERATED.xer_encoder;
+ td->uper_decoder = asn_DEF_ENUMERATED.uper_decoder;
+ td->uper_encoder = asn_DEF_ENUMERATED.uper_encoder;
+ if(!td->per_constraints)
+ td->per_constraints = asn_DEF_ENUMERATED.per_constraints;
+ td->elements = asn_DEF_ENUMERATED.elements;
+ td->elements_count = asn_DEF_ENUMERATED.elements_count;
+ /* td->specifics = asn_DEF_ENUMERATED.specifics; // Defined explicitly */
+}
+
+void
+Enum2_free(asn_TYPE_descriptor_t *td,
+ void *struct_ptr, int contents_only) {
+ Enum2_1_inherit_TYPE_descriptor(td);
+ td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+Enum2_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+ int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+ Enum2_1_inherit_TYPE_descriptor(td);
+ return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+Enum2_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const void *bufptr, size_t size, int tag_mode) {
+ Enum2_1_inherit_TYPE_descriptor(td);
+ return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+Enum2_encode_der(asn_TYPE_descriptor_t *td,
+ void *structure, int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ Enum2_1_inherit_TYPE_descriptor(td);
+ return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+Enum2_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+ Enum2_1_inherit_TYPE_descriptor(td);
+ return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+Enum2_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ Enum2_1_inherit_TYPE_descriptor(td);
+ return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+
+/*** <<< STAT-DEFS [Enum2] >>> ***/
+
+static asn_INTEGER_enum_map_t asn_MAP_Enum2_value2enum_1[] = {
+ { 0, 3, "red" },
+ { 1, 5, "green" },
+ { 12, 4, "beta" },
+ { 23, 6, "orange" },
+ { 45, 4, "blue" },
+ { 46, 5, "alpha" },
+ { 103, 5, "gamma" }
+ /* This list is extensible */
+};
+static unsigned int asn_MAP_Enum2_enum2value_1[] = {
+ 5, /* alpha(46) */
+ 2, /* beta(12) */
+ 4, /* blue(45) */
+ 6, /* gamma(103) */
+ 1, /* green(1) */
+ 3, /* orange(23) */
+ 0 /* red(0) */
+ /* This list is extensible */
+};
+static asn_INTEGER_specifics_t asn_SPC_Enum2_specs_1 = {
+ asn_MAP_Enum2_value2enum_1, /* "tag" => N; sorted by tag */
+ asn_MAP_Enum2_enum2value_1, /* N => "tag"; sorted by N */
+ 7, /* Number of elements in the maps */
+ 6, /* Extensions before this member */
+ 1, /* Strict enumeration */
+ 0, /* Native long size */
+ 0
+};
+static ber_tlv_tag_t asn_DEF_Enum2_tags_1[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_Enum2 = {
+ "Enum2",
+ "Enum2",
+ Enum2_free,
+ Enum2_print,
+ Enum2_constraint,
+ Enum2_decode_ber,
+ Enum2_encode_der,
+ Enum2_decode_xer,
+ Enum2_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_Enum2_tags_1,
+ sizeof(asn_DEF_Enum2_tags_1)
+ /sizeof(asn_DEF_Enum2_tags_1[0]), /* 1 */
+ asn_DEF_Enum2_tags_1, /* Same as above */
+ sizeof(asn_DEF_Enum2_tags_1)
+ /sizeof(asn_DEF_Enum2_tags_1[0]), /* 1 */
+ 0, /* No PER visible constraints */
+ 0, 0, /* Defined elsewhere */
+ &asn_SPC_Enum2_specs_1 /* Additional specs */
+};
+
+
+/*** <<< INCLUDES [Enum3] >>> ***/
+
+#include <ENUMERATED.h>
+
+/*** <<< DEPS [Enum3] >>> ***/
+
+typedef enum Enum3 {
+ Enum3_a = 0,
+ Enum3_b = 3,
+ /*
+ * Enumeration is extensible
+ */
+ Enum3_c = 1
+} e_Enum3;
+
+/*** <<< TYPE-DECLS [Enum3] >>> ***/
+
+typedef ENUMERATED_t Enum3_t;
+
+/*** <<< FUNC-DECLS [Enum3] >>> ***/
+
+extern asn_TYPE_descriptor_t asn_DEF_Enum3;
+asn_struct_free_f Enum3_free;
+asn_struct_print_f Enum3_print;
+asn_constr_check_f Enum3_constraint;
+ber_type_decoder_f Enum3_decode_ber;
+der_type_encoder_f Enum3_encode_der;
+xer_type_decoder_f Enum3_decode_xer;
+xer_type_encoder_f Enum3_encode_xer;
+
+/*** <<< CODE [Enum3] >>> ***/
+
+int
+Enum3_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ /* Replace with underlying type checker */
+ td->check_constraints = asn_DEF_ENUMERATED.check_constraints;
+ return td->check_constraints(td, sptr, ctfailcb, app_key);
+}
+
+/*
+ * This type is implemented using ENUMERATED,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+Enum3_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+ td->free_struct = asn_DEF_ENUMERATED.free_struct;
+ td->print_struct = asn_DEF_ENUMERATED.print_struct;
+ td->ber_decoder = asn_DEF_ENUMERATED.ber_decoder;
+ td->der_encoder = asn_DEF_ENUMERATED.der_encoder;
+ td->xer_decoder = asn_DEF_ENUMERATED.xer_decoder;
+ td->xer_encoder = asn_DEF_ENUMERATED.xer_encoder;
+ td->uper_decoder = asn_DEF_ENUMERATED.uper_decoder;
+ td->uper_encoder = asn_DEF_ENUMERATED.uper_encoder;
+ if(!td->per_constraints)
+ td->per_constraints = asn_DEF_ENUMERATED.per_constraints;
+ td->elements = asn_DEF_ENUMERATED.elements;
+ td->elements_count = asn_DEF_ENUMERATED.elements_count;
+ /* td->specifics = asn_DEF_ENUMERATED.specifics; // Defined explicitly */
+}
+
+void
+Enum3_free(asn_TYPE_descriptor_t *td,
+ void *struct_ptr, int contents_only) {
+ Enum3_1_inherit_TYPE_descriptor(td);
+ td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+Enum3_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+ int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+ Enum3_1_inherit_TYPE_descriptor(td);
+ return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+Enum3_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const void *bufptr, size_t size, int tag_mode) {
+ Enum3_1_inherit_TYPE_descriptor(td);
+ return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+Enum3_encode_der(asn_TYPE_descriptor_t *td,
+ void *structure, int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ Enum3_1_inherit_TYPE_descriptor(td);
+ return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+Enum3_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+ Enum3_1_inherit_TYPE_descriptor(td);
+ return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+Enum3_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ Enum3_1_inherit_TYPE_descriptor(td);
+ return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+
+/*** <<< STAT-DEFS [Enum3] >>> ***/
+
+static asn_INTEGER_enum_map_t asn_MAP_Enum3_value2enum_1[] = {
+ { 0, 1, "a" },
+ { 1, 1, "c" },
+ { 3, 1, "b" }
+ /* This list is extensible */
+};
+static unsigned int asn_MAP_Enum3_enum2value_1[] = {
+ 0, /* a(0) */
+ 2, /* b(3) */
+ 1 /* c(1) */
+ /* This list is extensible */
+};
+static asn_INTEGER_specifics_t asn_SPC_Enum3_specs_1 = {
+ asn_MAP_Enum3_value2enum_1, /* "tag" => N; sorted by tag */
+ asn_MAP_Enum3_enum2value_1, /* N => "tag"; sorted by N */
+ 3, /* Number of elements in the maps */
+ 3, /* Extensions before this member */
+ 1, /* Strict enumeration */
+ 0, /* Native long size */
+ 0
+};
+static ber_tlv_tag_t asn_DEF_Enum3_tags_1[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_Enum3 = {
+ "Enum3",
+ "Enum3",
+ Enum3_free,
+ Enum3_print,
+ Enum3_constraint,
+ Enum3_decode_ber,
+ Enum3_encode_der,
+ Enum3_decode_xer,
+ Enum3_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_Enum3_tags_1,
+ sizeof(asn_DEF_Enum3_tags_1)
+ /sizeof(asn_DEF_Enum3_tags_1[0]), /* 1 */
+ asn_DEF_Enum3_tags_1, /* Same as above */
+ sizeof(asn_DEF_Enum3_tags_1)
+ /sizeof(asn_DEF_Enum3_tags_1[0]), /* 1 */
+ 0, /* No PER visible constraints */
+ 0, 0, /* Defined elsewhere */
+ &asn_SPC_Enum3_specs_1 /* Additional specs */
+};
+
+
+/*** <<< INCLUDES [Enum4] >>> ***/
+
+#include <ENUMERATED.h>
+
+/*** <<< DEPS [Enum4] >>> ***/
+
+typedef enum Enum4 {
+ Enum4_a = 0,
+ Enum4_b = 1,
+ /*
+ * Enumeration is extensible
+ */
+ Enum4_c = 3,
+ Enum4_d = 4
+} e_Enum4;
+
+/*** <<< TYPE-DECLS [Enum4] >>> ***/
+
+typedef ENUMERATED_t Enum4_t;
+
+/*** <<< FUNC-DECLS [Enum4] >>> ***/
+
+extern asn_TYPE_descriptor_t asn_DEF_Enum4;
+asn_struct_free_f Enum4_free;
+asn_struct_print_f Enum4_print;
+asn_constr_check_f Enum4_constraint;
+ber_type_decoder_f Enum4_decode_ber;
+der_type_encoder_f Enum4_encode_der;
+xer_type_decoder_f Enum4_decode_xer;
+xer_type_encoder_f Enum4_encode_xer;
+
+/*** <<< CODE [Enum4] >>> ***/
+
+int
+Enum4_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ /* Replace with underlying type checker */
+ td->check_constraints = asn_DEF_ENUMERATED.check_constraints;
+ return td->check_constraints(td, sptr, ctfailcb, app_key);
+}
+
+/*
+ * This type is implemented using ENUMERATED,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+Enum4_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+ td->free_struct = asn_DEF_ENUMERATED.free_struct;
+ td->print_struct = asn_DEF_ENUMERATED.print_struct;
+ td->ber_decoder = asn_DEF_ENUMERATED.ber_decoder;
+ td->der_encoder = asn_DEF_ENUMERATED.der_encoder;
+ td->xer_decoder = asn_DEF_ENUMERATED.xer_decoder;
+ td->xer_encoder = asn_DEF_ENUMERATED.xer_encoder;
+ td->uper_decoder = asn_DEF_ENUMERATED.uper_decoder;
+ td->uper_encoder = asn_DEF_ENUMERATED.uper_encoder;
+ if(!td->per_constraints)
+ td->per_constraints = asn_DEF_ENUMERATED.per_constraints;
+ td->elements = asn_DEF_ENUMERATED.elements;
+ td->elements_count = asn_DEF_ENUMERATED.elements_count;
+ /* td->specifics = asn_DEF_ENUMERATED.specifics; // Defined explicitly */
+}
+
+void
+Enum4_free(asn_TYPE_descriptor_t *td,
+ void *struct_ptr, int contents_only) {
+ Enum4_1_inherit_TYPE_descriptor(td);
+ td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+Enum4_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+ int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+ Enum4_1_inherit_TYPE_descriptor(td);
+ return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+Enum4_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const void *bufptr, size_t size, int tag_mode) {
+ Enum4_1_inherit_TYPE_descriptor(td);
+ return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+Enum4_encode_der(asn_TYPE_descriptor_t *td,
+ void *structure, int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ Enum4_1_inherit_TYPE_descriptor(td);
+ return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+Enum4_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+ Enum4_1_inherit_TYPE_descriptor(td);
+ return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+Enum4_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ Enum4_1_inherit_TYPE_descriptor(td);
+ return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+
+/*** <<< STAT-DEFS [Enum4] >>> ***/
+
+static asn_INTEGER_enum_map_t asn_MAP_Enum4_value2enum_1[] = {
+ { 0, 1, "a" },
+ { 1, 1, "b" },
+ { 3, 1, "c" },
+ { 4, 1, "d" }
+ /* This list is extensible */
+};
+static unsigned int asn_MAP_Enum4_enum2value_1[] = {
+ 0, /* a(0) */
+ 1, /* b(1) */
+ 2, /* c(3) */
+ 3 /* d(4) */
+ /* This list is extensible */
+};
+static asn_INTEGER_specifics_t asn_SPC_Enum4_specs_1 = {
+ asn_MAP_Enum4_value2enum_1, /* "tag" => N; sorted by tag */
+ asn_MAP_Enum4_enum2value_1, /* N => "tag"; sorted by N */
+ 4, /* Number of elements in the maps */
+ 3, /* Extensions before this member */
+ 1, /* Strict enumeration */
+ 0, /* Native long size */
+ 0
+};
+static ber_tlv_tag_t asn_DEF_Enum4_tags_1[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_Enum4 = {
+ "Enum4",
+ "Enum4",
+ Enum4_free,
+ Enum4_print,
+ Enum4_constraint,
+ Enum4_decode_ber,
+ Enum4_encode_der,
+ Enum4_decode_xer,
+ Enum4_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_Enum4_tags_1,
+ sizeof(asn_DEF_Enum4_tags_1)
+ /sizeof(asn_DEF_Enum4_tags_1[0]), /* 1 */
+ asn_DEF_Enum4_tags_1, /* Same as above */
+ sizeof(asn_DEF_Enum4_tags_1)
+ /sizeof(asn_DEF_Enum4_tags_1[0]), /* 1 */
+ 0, /* No PER visible constraints */
+ 0, 0, /* Defined elsewhere */
+ &asn_SPC_Enum4_specs_1 /* Additional specs */
+};
+
+
+/*** <<< INCLUDES [Enum5] >>> ***/
+
+#include <ENUMERATED.h>
+
+/*** <<< DEPS [Enum5] >>> ***/
+
+typedef enum Enum5 {
+ Enum5_a = 0,
+ Enum5_z = 25,
+ /*
+ * Enumeration is extensible
+ */
+ Enum5_d = 26
+} e_Enum5;
+
+/*** <<< TYPE-DECLS [Enum5] >>> ***/
+
+typedef ENUMERATED_t Enum5_t;
+
+/*** <<< FUNC-DECLS [Enum5] >>> ***/
+
+extern asn_TYPE_descriptor_t asn_DEF_Enum5;
+asn_struct_free_f Enum5_free;
+asn_struct_print_f Enum5_print;
+asn_constr_check_f Enum5_constraint;
+ber_type_decoder_f Enum5_decode_ber;
+der_type_encoder_f Enum5_encode_der;
+xer_type_decoder_f Enum5_decode_xer;
+xer_type_encoder_f Enum5_encode_xer;
+
+/*** <<< CODE [Enum5] >>> ***/
+
+int
+Enum5_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
+ asn_app_constraint_failed_f *ctfailcb, void *app_key) {
+ /* Replace with underlying type checker */
+ td->check_constraints = asn_DEF_ENUMERATED.check_constraints;
+ return td->check_constraints(td, sptr, ctfailcb, app_key);
+}
+
+/*
+ * This type is implemented using ENUMERATED,
+ * so here we adjust the DEF accordingly.
+ */
+static void
+Enum5_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
+ td->free_struct = asn_DEF_ENUMERATED.free_struct;
+ td->print_struct = asn_DEF_ENUMERATED.print_struct;
+ td->ber_decoder = asn_DEF_ENUMERATED.ber_decoder;
+ td->der_encoder = asn_DEF_ENUMERATED.der_encoder;
+ td->xer_decoder = asn_DEF_ENUMERATED.xer_decoder;
+ td->xer_encoder = asn_DEF_ENUMERATED.xer_encoder;
+ td->uper_decoder = asn_DEF_ENUMERATED.uper_decoder;
+ td->uper_encoder = asn_DEF_ENUMERATED.uper_encoder;
+ if(!td->per_constraints)
+ td->per_constraints = asn_DEF_ENUMERATED.per_constraints;
+ td->elements = asn_DEF_ENUMERATED.elements;
+ td->elements_count = asn_DEF_ENUMERATED.elements_count;
+ /* td->specifics = asn_DEF_ENUMERATED.specifics; // Defined explicitly */
+}
+
+void
+Enum5_free(asn_TYPE_descriptor_t *td,
+ void *struct_ptr, int contents_only) {
+ Enum5_1_inherit_TYPE_descriptor(td);
+ td->free_struct(td, struct_ptr, contents_only);
+}
+
+int
+Enum5_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
+ int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+ Enum5_1_inherit_TYPE_descriptor(td);
+ return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+asn_dec_rval_t
+Enum5_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const void *bufptr, size_t size, int tag_mode) {
+ Enum5_1_inherit_TYPE_descriptor(td);
+ return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);
+}
+
+asn_enc_rval_t
+Enum5_encode_der(asn_TYPE_descriptor_t *td,
+ void *structure, int tag_mode, ber_tlv_tag_t tag,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ Enum5_1_inherit_TYPE_descriptor(td);
+ return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+asn_dec_rval_t
+Enum5_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+ void **structure, const char *opt_mname, const void *bufptr, size_t size) {
+ Enum5_1_inherit_TYPE_descriptor(td);
+ return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);
+}
+
+asn_enc_rval_t
+Enum5_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
+ int ilevel, enum xer_encoder_flags_e flags,
+ asn_app_consume_bytes_f *cb, void *app_key) {
+ Enum5_1_inherit_TYPE_descriptor(td);
+ return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
+}
+
+
+/*** <<< STAT-DEFS [Enum5] >>> ***/
+
+static asn_INTEGER_enum_map_t asn_MAP_Enum5_value2enum_1[] = {
+ { 0, 1, "a" },
+ { 25, 1, "z" },
+ { 26, 1, "d" }
+ /* This list is extensible */
+};
+static unsigned int asn_MAP_Enum5_enum2value_1[] = {
+ 0, /* a(0) */
+ 2, /* d(26) */
+ 1 /* z(25) */
+ /* This list is extensible */
+};
+static asn_INTEGER_specifics_t asn_SPC_Enum5_specs_1 = {
+ asn_MAP_Enum5_value2enum_1, /* "tag" => N; sorted by tag */
+ asn_MAP_Enum5_enum2value_1, /* N => "tag"; sorted by N */
+ 3, /* Number of elements in the maps */
+ 3, /* Extensions before this member */
+ 1, /* Strict enumeration */
+ 0, /* Native long size */
+ 0
+};
+static ber_tlv_tag_t asn_DEF_Enum5_tags_1[] = {
+ (ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
+};
+asn_TYPE_descriptor_t asn_DEF_Enum5 = {
+ "Enum5",
+ "Enum5",
+ Enum5_free,
+ Enum5_print,
+ Enum5_constraint,
+ Enum5_decode_ber,
+ Enum5_encode_der,
+ Enum5_decode_xer,
+ Enum5_encode_xer,
+ 0, 0, /* No PER support, use "-gen-PER" to enable */
+ 0, /* Use generic outmost tag fetcher */
+ asn_DEF_Enum5_tags_1,
+ sizeof(asn_DEF_Enum5_tags_1)
+ /sizeof(asn_DEF_Enum5_tags_1[0]), /* 1 */
+ asn_DEF_Enum5_tags_1, /* Same as above */
+ sizeof(asn_DEF_Enum5_tags_1)
+ /sizeof(asn_DEF_Enum5_tags_1[0]), /* 1 */
+ 0, /* No PER visible constraints */
+ 0, 0, /* Defined elsewhere */
+ &asn_SPC_Enum5_specs_1 /* Additional specs */
+};
+
diff --git a/tests/128-enum-SE.asn1 b/tests/128-enum-SE.asn1
new file mode 100644
index 00000000..40b8caf2
--- /dev/null
+++ b/tests/128-enum-SE.asn1
@@ -0,0 +1,16 @@
+
+-- SE: Semantic error
+
+-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1)
+-- .spelio.software.asn1c.test (9363.1.5.1)
+-- .128
+
+ModuleTestEnum1
+ { iso org(3) dod(6) internet (1) private(4) enterprise(1)
+ spelio(9363) software(1) asn1c(5) test(1) 128 }
+ DEFINITIONS ::=
+BEGIN
+
+ A ::= ENUMERATED {a, b, ..., c, d(2)}
+
+END
diff --git a/tests/129-enum-OK.asn1 b/tests/129-enum-OK.asn1
new file mode 100644
index 00000000..06f5eed9
--- /dev/null
+++ b/tests/129-enum-OK.asn1
@@ -0,0 +1,16 @@
+
+-- OK: Everything is fine
+
+-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1)
+-- .spelio.software.asn1c.test (9363.1.5.1)
+-- .129
+
+ModuleTestEnum1
+ { iso org(3) dod(6) internet (1) private(4) enterprise(1)
+ spelio(9363) software(1) asn1c(5) test(1) 129 }
+ DEFINITIONS ::=
+BEGIN
+
+ A ::= ENUMERATED {a(-5), b(-4), c}
+
+END
diff --git a/tests/129-enum-OK.asn1.-EF b/tests/129-enum-OK.asn1.-EF
new file mode 100644
index 00000000..ebc3d30e
--- /dev/null
+++ b/tests/129-enum-OK.asn1.-EF
@@ -0,0 +1,12 @@
+ModuleTestEnum1 { iso org(3) dod(6) internet(1) private(4) enterprise(1)
+ spelio(9363) software(1) asn1c(5) test(1) 129 }
+DEFINITIONS ::=
+BEGIN
+
+A ::= ENUMERATED {
+ a(-5),
+ b(-4),
+ c(0)
+}
+
+END
diff --git a/tests/129-enum-SE.asn1 b/tests/129-enum-SE.asn1
new file mode 100644
index 00000000..cb85dc9d
--- /dev/null
+++ b/tests/129-enum-SE.asn1
@@ -0,0 +1,16 @@
+
+-- SE: Semantic error
+
+-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1)
+-- .spelio.software.asn1c.test (9363.1.5.1)
+-- .129
+
+ModuleTestEnum1
+ { iso org(3) dod(6) internet (1) private(4) enterprise(1)
+ spelio(9363) software(1) asn1c(5) test(1) 129 }
+ DEFINITIONS ::=
+BEGIN
+
+ A ::= ENUMERATED {a, b, ..., c, d(2)}
+
+END
diff --git a/tests/130-enum-OK.asn1 b/tests/130-enum-OK.asn1
new file mode 100644
index 00000000..d917e398
--- /dev/null
+++ b/tests/130-enum-OK.asn1
@@ -0,0 +1,16 @@
+
+-- OK: Everything is fine
+
+-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1)
+-- .spelio.software.asn1c.test (9363.1.5.1)
+-- .130
+
+ModuleTestEnum1
+ { iso org(3) dod(6) internet (1) private(4) enterprise(1)
+ spelio(9363) software(1) asn1c(5) test(1) 130 }
+ DEFINITIONS ::=
+BEGIN
+
+ A ::= ENUMERATED {a(-5), b(-4),..., c}
+
+END
diff --git a/tests/130-enum-OK.asn1.-EF b/tests/130-enum-OK.asn1.-EF
new file mode 100644
index 00000000..eaa5a51a
--- /dev/null
+++ b/tests/130-enum-OK.asn1.-EF
@@ -0,0 +1,13 @@
+ModuleTestEnum1 { iso org(3) dod(6) internet(1) private(4) enterprise(1)
+ spelio(9363) software(1) asn1c(5) test(1) 130 }
+DEFINITIONS ::=
+BEGIN
+
+A ::= ENUMERATED {
+ a(-5),
+ b(-4),
+ ...,
+ c(0)
+}
+
+END