blob: ce2fc2fc646a4cb347392dc94bed7dac915f07f5 [file] [log] [blame]
vlmfa67ddc2004-06-03 03:38:44 +00001#include "asn1fix_internal.h"
2
3/*
4 * Check the validity of an enumeration.
5 */
6int
7asn1f_fix_enum(arg_t *arg) {
8 asn1p_expr_t *expr = arg->expr;
9 asn1p_expr_t *ev;
vlmd5b3bf32004-09-29 13:17:17 +000010 asn1c_integer_t max_value = -1;
vlmfa67ddc2004-06-03 03:38:44 +000011 int rvalue = 0;
12 asn1p_expr_t *ext_marker = NULL; /* "..." position */
13 int ret;
14
15 if(expr->expr_type != ASN_BASIC_ENUMERATED)
16 return 0; /* Just ignore it */
17
vlmfd245932005-03-10 10:02:50 +000018 DEBUG("(%s)", expr->Identifier);
vlmfa67ddc2004-06-03 03:38:44 +000019
20 /*
21 * 1. Scan the enumeration values in search for inconsistencies.
22 */
23 TQ_FOR(ev, &(expr->members), next) {
vlmd5b3bf32004-09-29 13:17:17 +000024 asn1c_integer_t eval;
vlmfa67ddc2004-06-03 03:38:44 +000025
26 if(ev->value)
27 DEBUG("\tItem %s(%s)", ev->Identifier,
28 asn1f_printable_value(ev->value));
29 else
30 DEBUG("\tItem %s", ev->Identifier);
31
32 /*
33 * 1.1 Found an extension mark "...", check correctness.
34 */
35 if(ev->expr_type == A1TC_EXTENSIBLE) {
36 if(ext_marker) {
37 arg->eh(1,
38 "Enumeration %s at line %d: "
39 "Second extension marker is not allowed",
40 expr->Identifier,
41 ev->_lineno);
42 rvalue = -1;
43 } else {
44 /*
45 * Remember the marker's position.
46 */
47 ext_marker = ev;
48 }
49 continue;
50 } else if(ev->Identifier == NULL
51 || ev->expr_type != A1TC_UNIVERVAL) {
52 FATAL(
53 "Enumeration %s at line %d: "
54 "Unsupported enumeration element %s",
55 expr->Identifier,
56 ev->_lineno,
57 ev->Identifier?ev->Identifier:"<anonymous>");
58 rvalue = -1;
59 continue;
60 }
61
62 /*
63 * 1.2 Compute the value of the enumeration element.
64 */
65 if(ev->value) {
66 switch(ev->value->type) {
67 case ATV_INTEGER:
68 eval = ev->value->value.v_integer;
69 break;
70 case ATV_REFERENCED:
71 FATAL("HERE HERE HERE", 1);
72 rvalue = -1;
73 continue;
74 break;
75 default:
76 FATAL("ENUMERATED type %s at line %d "
77 "contain element %s(%s) at line %d",
78 expr->Identifier, expr->_lineno,
79 ev->Identifier,
80 asn1f_printable_value(ev->value),
81 ev->_lineno);
82 rvalue = -1;
83 continue;
84 }
85 } else {
86 eval = max_value + 1;
87 ev->value = asn1p_value_fromint(eval);
88 if(ev->value == NULL) {
89 rvalue = -1;
90 continue;
91 }
92 }
93
94 /*
95 * 1.3 Check the applicability of this value.
96 */
97 if(eval <= max_value) {
98 if(ext_marker) {
99 /*
100 * Enumeration is allowed to be unordered
101 * before the first marker.
102 */
103 FATAL(
104 "Enumeration %s at line %d: "
vlm47ae1582004-09-24 21:01:43 +0000105 "Explicit value \"%s(%" PRIdASN ")\" "
vlmfa67ddc2004-06-03 03:38:44 +0000106 "is not greater "
vlm47ae1582004-09-24 21:01:43 +0000107 "than previous values (max %" PRIdASN ")",
vlmfa67ddc2004-06-03 03:38:44 +0000108 expr->Identifier,
109 ev->_lineno,
110 ev->Identifier,
111 eval,
112 max_value);
113 rvalue = -1;
114 }
115 } else if(eval > max_value) {
116 max_value = eval;
117 }
118
119 /*
120 * 1.4 Check that all identifiers before the current one
121 * differs from it.
122 */
123 ret = asn1f_check_unique_expr_child(arg, ev, NULL);
124 RET2RVAL(ret, rvalue);
125 }
126
127
128 /*
129 * 2. Reorder the first half (before optional "...") of the
130 * identifiers alphabetically.
131 */
132 // TODO
133
134 return rvalue;
135}
136