NativeEnumerated.c vars NULL init and check
[com/asn1c.git] / libasn1fix / asn1fix_integer.c
1 #include "asn1fix_internal.h"
2
3 static int _compare_value(asn1p_expr_t *expr1, asn1p_expr_t *expr2) {
4         if(expr2->value->type == ATV_INTEGER
5         && expr1->value->type == ATV_INTEGER) {
6                 return expr2->value->value.v_integer
7                         - expr1->value->value.v_integer;
8         } else {
9                 return -1;
10         }
11 }
12
13 /*
14  * Check the validity of an INTEGER type.
15  */
16 int
17 asn1f_fix_integer(arg_t *arg) {
18         asn1p_expr_t *expr = arg->expr;
19         asn1p_expr_t *iv;
20         int rvalue = 0;
21         int ret;
22
23         if(expr->expr_type != ASN_BASIC_INTEGER)
24                 return 0;       /* Just ignore it */
25
26         DEBUG("(\"%s\", %x) for line %d",
27                 expr->Identifier, expr->expr_type, expr->_lineno);
28
29         /*
30          * Scan the integer values in search for inconsistencies.
31          */
32         TQ_FOR(iv, &(expr->members), next) {
33
34                 DEBUG("\tItem %s(%s)", iv->Identifier,
35                         asn1f_printable_value(iv->value));
36
37                 /*
38                  * Found "...", check correctness.
39                  */
40                 if(iv->expr_type == A1TC_EXTENSIBLE) {
41                         FATAL("INTEGER %s at line %d: "
42                                 "Extension marker is not allowed",
43                                 expr->Identifier,
44                                 iv->_lineno);
45                         rvalue = -1;
46                         continue;
47                 }
48
49                 if(iv->Identifier == NULL
50                 || iv->expr_type != A1TC_UNIVERVAL) {
51                         FATAL("INTEGER %s at line %d: "
52                                 "Unsupported enumeration element %s",
53                                 expr->Identifier,
54                                 iv->_lineno,
55                                 iv->Identifier?iv->Identifier:"<Anonymous>"
56                         );
57                         rvalue = -1;
58                         continue;
59                 }
60
61                 if(iv->value == NULL) {
62                         FATAL("INTEGER %s at line %d: "
63                                 "Value for the identifier %s "
64                                 "must be set explicitly",
65                                 expr->Identifier,
66                                 iv->_lineno,
67                                 iv->Identifier
68                         );
69                         rvalue = -1;
70                         continue;
71                 } else if(iv->value->type == ATV_REFERENCED) {
72                         /*
73                          * Resolve the value, once and for all.
74                          */
75                         if(asn1f_value_resolve(arg, iv, 0)) {
76                                 /* This function will emit messages */
77                                 rvalue = -1;
78                                 continue;
79                         }
80                 }
81
82                 if(iv->value->type != ATV_INTEGER) {
83                         FATAL("INTEGER %s at line %d: "
84                                 "Value for the identifier %s "
85                                 "is not compatible with INTEGER type",
86                                 expr->Identifier,
87                                 iv->_lineno);
88                         rvalue = -1;
89                         continue;
90                 }
91
92                 /*
93                  * Check that all identifiers are distinct.
94                  */
95                 ret = asn1f_check_unique_expr_child(arg, iv, 0, "identifier");
96                 RET2RVAL(ret, rvalue);
97                 /*
98                  * Check that all values are distinct.
99                  */
100                 ret = asn1f_check_unique_expr_child(arg, iv,
101                                 _compare_value, "value");
102                 RET2RVAL(ret, rvalue);
103         }
104
105
106         return rvalue;
107 }
108
109 #if 0
110 static int
111 _asn1f_make_sure_type_is(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_type_e type) {
112         asn1p_expr_t *next_expr;
113         asn1p_expr_type_e expr_type;
114         int ret;
115
116         expr_type = expr->expr_type;
117
118         /*
119          * Here we're trying to make sure that the type of the given
120          * expression is really what is expected.
121          * This is ensured in two ways.
122          * First, if the immediate type matches the provided one,
123          * this is a clear hit.
124          */
125         if(expr_type == type)
126                 return 0;
127
128         /*
129          * Otherwise, it must be either a reference or a different type.
130          */
131         if(expr_type != A1TC_REFERENCE) {
132                 errno = EPERM;
133                 return -1;
134         }
135
136         assert(expr_type == A1TC_REFERENCE);
137         assert(expr->reference);
138
139         /*
140          * Then, it is a reference. For a reference, try to resolve type
141          * and try again.
142          */
143         next_expr = asn1f_lookup_symbol(arg, expr->module,
144                         expr->rhs_pspecs, expr->reference);
145         if(next_expr == NULL) {
146                 errno = ESRCH;
147                 return -1;
148         }
149
150         /*
151          * If symbol is here, recursively check that it conforms to the type.
152          */
153         WITH_MODULE(next_expr->module,
154                 ret = _asn1f_make_sure_type_is(arg, next_expr, type));
155
156         return ret;
157 }
158 #endif
159
160