1 #include "asn1fix_internal.h"
4 * Check the validity of an enumeration.
7 asn1f_fix_enum(arg_t *arg) {
8 asn1p_expr_t *expr = arg->expr;
10 asn1c_integer_t max_value = -1;
11 asn1c_integer_t max_value_ext = -1;
13 asn1p_expr_t *ext_marker = NULL; /* "..." position */
16 /* Keep track of value collisions */
17 asn1c_integer_t *used_vals;
18 int used_vals_sz = 50;
19 int used_vals_next = 0;
21 if(expr->expr_type != ASN_BASIC_ENUMERATED)
22 return 0; /* Just ignore it */
24 DEBUG("(%s)", expr->Identifier);
26 used_vals = (asn1c_integer_t *) malloc(sizeof(asn1c_integer_t) * used_vals_sz);
28 FATAL("Out of memory");
33 * 1. Scan the enumeration values in search for inconsistencies.
35 TQ_FOR(ev, &(expr->members), next) {
39 DEBUG("\tItem %s(%s)", ev->Identifier,
40 asn1f_printable_value(ev->value));
42 DEBUG("\tItem %s", ev->Identifier);
45 * 1.1 Found an extension mark "...", check correctness.
47 if(ev->expr_type == A1TC_EXTENSIBLE) {
49 FATAL("Enumeration %s at line %d: "
50 "Second extension marker is not allowed",
56 * Remember the marker's position.
61 } else if(ev->Identifier == NULL
62 || ev->expr_type != A1TC_UNIVERVAL) {
64 "Enumeration %s at line %d: "
65 "Unsupported enumeration element %s",
68 ev->Identifier?ev->Identifier:"<anonymous>");
74 * 1.2 Compute the value of the enumeration element.
77 switch(ev->value->type) {
79 eval = ev->value->value.v_integer;
82 FATAL("HERE HERE HERE", 1);
87 FATAL("ENUMERATED type %s at line %d "
88 "contain element %s(%s) at line %d",
89 expr->Identifier, expr->_lineno,
91 asn1f_printable_value(ev->value),
98 ev->value = asn1p_value_fromint(eval);
99 if(ev->value == NULL) {
106 * 1.3 Check the applicability of this value.
110 * Enumeration is allowed to be unordered
111 * before the first marker, but after the marker
112 * the values must be ordered.
115 if (eval > max_value_ext) {
116 max_value_ext = eval;
118 char max_value_buf[128];
119 asn1p_itoa_s(max_value_buf, sizeof(max_value_buf),
122 "Enumeration %s at line %d: "
123 "Explicit value \"%s(%s)\" "
125 "than previous values (max %s)",
135 if (eval > max_value) {
141 * 1.4 Check that all identifiers are unique
145 for (uv_idx = 0; uv_idx < used_vals_next; uv_idx++) {
146 if (used_vals[uv_idx] == eval) {
148 "Enumeration %s at line %d: "
149 "Explicit value \"%s(%s)\" "
150 "collides with previous values",
161 /* Grow the array if needed */
162 if (used_vals_next >= used_vals_sz) {
163 asn1c_integer_t *temp;
164 int new_sz = used_vals_sz + 50;
165 temp = (asn1c_integer_t *) realloc(used_vals,
166 sizeof(asn1c_integer_t) * new_sz);
167 if (!temp) return -1;
169 used_vals_sz = new_sz;
171 used_vals[used_vals_next++] = eval;
175 * 1.5 Check that all identifiers before the current one
178 ret = asn1f_check_unique_expr_child(arg, ev, 0, "identifier");
179 RET2RVAL(ret, rvalue);
185 * 2. Reorder the first half (before optional "...") of the
186 * identifiers alphabetically.