blob: 570d23ae18d8d10de392014997340f53b6f19b89 [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) {
vlmadf419b2006-08-28 02:24:24 +000037 FATAL("Enumeration %s at line %d: "
vlmfa67ddc2004-06-03 03:38:44 +000038 "Second extension marker is not allowed",
39 expr->Identifier,
40 ev->_lineno);
41 rvalue = -1;
42 } else {
43 /*
44 * Remember the marker's position.
45 */
46 ext_marker = ev;
47 }
48 continue;
49 } else if(ev->Identifier == NULL
50 || ev->expr_type != A1TC_UNIVERVAL) {
51 FATAL(
52 "Enumeration %s at line %d: "
53 "Unsupported enumeration element %s",
54 expr->Identifier,
55 ev->_lineno,
56 ev->Identifier?ev->Identifier:"<anonymous>");
57 rvalue = -1;
58 continue;
59 }
60
61 /*
62 * 1.2 Compute the value of the enumeration element.
63 */
64 if(ev->value) {
65 switch(ev->value->type) {
66 case ATV_INTEGER:
67 eval = ev->value->value.v_integer;
68 break;
69 case ATV_REFERENCED:
70 FATAL("HERE HERE HERE", 1);
71 rvalue = -1;
72 continue;
73 break;
74 default:
75 FATAL("ENUMERATED type %s at line %d "
76 "contain element %s(%s) at line %d",
77 expr->Identifier, expr->_lineno,
78 ev->Identifier,
79 asn1f_printable_value(ev->value),
80 ev->_lineno);
81 rvalue = -1;
82 continue;
83 }
84 } else {
85 eval = max_value + 1;
86 ev->value = asn1p_value_fromint(eval);
87 if(ev->value == NULL) {
88 rvalue = -1;
89 continue;
90 }
91 }
92
93 /*
94 * 1.3 Check the applicability of this value.
95 */
96 if(eval <= max_value) {
97 if(ext_marker) {
98 /*
99 * Enumeration is allowed to be unordered
100 * before the first marker.
101 */
102 FATAL(
103 "Enumeration %s at line %d: "
vlm47ae1582004-09-24 21:01:43 +0000104 "Explicit value \"%s(%" PRIdASN ")\" "
vlmfa67ddc2004-06-03 03:38:44 +0000105 "is not greater "
vlm47ae1582004-09-24 21:01:43 +0000106 "than previous values (max %" PRIdASN ")",
vlmfa67ddc2004-06-03 03:38:44 +0000107 expr->Identifier,
108 ev->_lineno,
109 ev->Identifier,
110 eval,
111 max_value);
112 rvalue = -1;
113 }
114 } else if(eval > max_value) {
115 max_value = eval;
116 }
117
118 /*
119 * 1.4 Check that all identifiers before the current one
120 * differs from it.
121 */
vlm073a7c72006-08-28 02:45:44 +0000122 ret = asn1f_check_unique_expr_child(arg, ev, 0, "identifier");
vlmfa67ddc2004-06-03 03:38:44 +0000123 RET2RVAL(ret, rvalue);
124 }
125
126
127 /*
128 * 2. Reorder the first half (before optional "...") of the
129 * identifiers alphabetically.
130 */
131 // TODO
132
133 return rvalue;
134}
135