blob: 3f30009eeaf408ab838c1a4d45969f0dcf227c1c [file] [log] [blame]
vlmb5be8c32004-08-18 05:42:05 +00001#include <asn1fix_internal.h>
2#include <asn1fix_constraint.h>
3#include <asn1fix_crange.h>
4
5static void _remove_exceptions(arg_t *arg, asn1p_constraint_t *ct);
vlm2e0c1942004-08-22 03:10:23 +00006static int _constraint_value_resolve(arg_t *arg, asn1p_module_t *mod, asn1p_value_t **value);
vlmb5be8c32004-08-18 05:42:05 +00007
8int
9asn1constraint_pullup(arg_t *arg) {
10 asn1p_expr_t *expr = arg->expr;
11 asn1p_constraint_t *ct_parent;
12 asn1p_constraint_t *ct_expr;
13 int ret;
14
15 if(expr->combined_constraints)
16 return 0; /* Operation already performed earlier */
17
18 switch(expr->meta_type) {
19 case AMT_TYPE:
20 case AMT_TYPEREF:
21 break;
22 default:
23 return 0; /* Nothing to do */
24 }
25
26 if(expr->expr_type == A1TC_REFERENCE) {
27 asn1p_ref_t *ref = expr->reference;
vlmb5be8c32004-08-18 05:42:05 +000028 asn1p_expr_t *parent_expr;
29
30 assert(ref);
vlm2e0c1942004-08-22 03:10:23 +000031 parent_expr = asn1f_lookup_symbol(arg, expr->module, ref);
vlmb5be8c32004-08-18 05:42:05 +000032 if(!parent_expr) {
33 if(errno != EEXIST) {
34 DEBUG("\tWhile fetching parent constraints: "
35 "type \"%s\" not found: %s",
36 asn1f_printable_reference(ref),
37 strerror(errno));
38 return -1;
39 } else {
40 /*
41 * -fknown-extern-type is given.
42 * Assume there are no constraints there.
43 */
44 WARNING("External type \"%s\": "
45 "assuming no constraints",
46 asn1f_printable_reference(ref));
47 ct_parent = 0;
48 }
49 } else {
50 arg->expr = parent_expr;
51 ret = asn1constraint_pullup(arg);
52 arg->expr = expr;
53 if(ret) return ret;
54
55 ct_parent = parent_expr->combined_constraints;
56 }
57 } else {
58 ct_parent = 0;
59 }
60
61 ct_expr = expr->constraints;
62
63 if(!ct_parent && !ct_expr)
64 return 0; /* No constraints to consider */
65
66 if(ct_parent) {
67 ct_parent = asn1p_constraint_clone(ct_parent);
68 assert(ct_parent);
69 }
70
71 /*
72 * If the current type does not have constraints, it inherits
73 * the constraints of a parent.
74 */
75 if(ct_parent && !ct_expr) {
76 expr->combined_constraints = ct_parent;
77 return 0;
78 }
79
80 ct_expr = asn1p_constraint_clone(ct_expr);
81 assert(ct_expr);
82
83 /*
84 * Now we have a set of current expression's constraints,
85 * and an optional set of the parent expression's constraints.
86 */
87
88 if(ct_parent) {
89 /*
90 * If we have a parent, remove all the extensions (46.4).
91 */
92 _remove_exceptions(arg, ct_parent);
93
94 expr->combined_constraints = ct_parent;
95 if(ct_expr->type == ACT_CA_SET) {
vlm76142452004-09-05 10:36:22 +000096 unsigned int i;
vlmb5be8c32004-08-18 05:42:05 +000097 for(i = 0; i < ct_expr->el_count; i++) {
98 if(asn1p_constraint_insert(
99 expr->combined_constraints,
100 ct_expr->elements[i])) {
101 expr->combined_constraints = 0;
102 asn1p_constraint_free(ct_expr);
103 asn1p_constraint_free(ct_parent);
104 return -1;
105 } else {
106 ct_expr->elements[i] = 0;
107 }
108 }
109 asn1p_constraint_free(ct_expr);
110 } else {
111 asn1p_constraint_insert(expr->combined_constraints,
112 ct_expr);
113 }
114 } else {
115 expr->combined_constraints = ct_expr;
116 }
117
118 return 0;
119}
120
121int
vlm2e0c1942004-08-22 03:10:23 +0000122asn1constraint_resolve(arg_t *arg, asn1p_module_t *mod, asn1p_constraint_t *ct, asn1p_expr_type_e etype, enum asn1p_constraint_type_e effective_type) {
vlm76142452004-09-05 10:36:22 +0000123 unsigned int el;
vlmb5be8c32004-08-18 05:42:05 +0000124 int rvalue = 0;
125 int ret;
vlmb5be8c32004-08-18 05:42:05 +0000126
127 if(!ct) return 0;
128
129 /* Don't touch information object classes */
130 switch(ct->type) {
vlmd8d90352004-08-20 13:25:56 +0000131 case ACT_CT_SIZE:
132 case ACT_CT_FROM:
133 if(effective_type && effective_type != ct->type) {
134 FATAL("%s at line %d: "
135 "Incompatible nested %s within %s",
136 arg->expr->Identifier, ct->_lineno,
137 asn1p_constraint_type2str(ct->type),
138 asn1p_constraint_type2str(effective_type)
139 );
140 }
141 effective_type = ct->type;
142 break;
vlmb5be8c32004-08-18 05:42:05 +0000143 case ACT_CT_WCOMP:
144 case ACT_CT_WCOMPS:
145 case ACT_CA_CRC:
146 return 0;
147 default:
148 break;
149 }
150
vlmd8d90352004-08-20 13:25:56 +0000151 if(etype != A1TC_INVALID) {
152 enum asn1p_constraint_type_e check_type;
153
154 check_type = effective_type ? effective_type : ct->type;
155
156 ret = asn1constraint_compatible(etype, check_type);
vlmb5be8c32004-08-18 05:42:05 +0000157 switch(ret) {
158 case -1: /* If unknown, assume OK. */
159 case 1:
160 break;
161 case 0:
vlmd8d90352004-08-20 13:25:56 +0000162 if(effective_type == ACT_CT_SIZE
163 && (arg->flags & A1F_EXTENDED_SizeConstraint))
164 break;
vlmb5be8c32004-08-18 05:42:05 +0000165 default:
166 FATAL("%s at line %d: "
167 "Constraint type %s is not applicable to %s",
168 arg->expr->Identifier, ct->_lineno,
vlmd8d90352004-08-20 13:25:56 +0000169 asn1p_constraint_type2str(check_type),
170 ASN_EXPR_TYPE2STR(etype)
vlmb5be8c32004-08-18 05:42:05 +0000171 );
172 rvalue = -1;
173 break;
174 }
175 } else {
176 WARNING("%s at line %d: "
177 "Constraints ignored: Unresolved parent type",
178 arg->expr->Identifier, arg->expr->_lineno);
179 }
180
vlmd8d90352004-08-20 13:25:56 +0000181 /*
182 * Resolve all possible references, wherever they occur.
183 */
vlmb5be8c32004-08-18 05:42:05 +0000184 if(ct->value && ct->value->type == ATV_REFERENCED) {
vlm2e0c1942004-08-22 03:10:23 +0000185 ret = _constraint_value_resolve(arg, mod, &ct->value);
vlmb5be8c32004-08-18 05:42:05 +0000186 RET2RVAL(ret, rvalue);
187 }
188 if(ct->range_start && ct->range_start->type == ATV_REFERENCED) {
vlm2e0c1942004-08-22 03:10:23 +0000189 ret = _constraint_value_resolve(arg, mod, &ct->range_start);
vlmb5be8c32004-08-18 05:42:05 +0000190 RET2RVAL(ret, rvalue);
191 }
192 if(ct->range_stop && ct->range_stop->type == ATV_REFERENCED) {
vlm2e0c1942004-08-22 03:10:23 +0000193 ret = _constraint_value_resolve(arg, mod, &ct->range_stop);
vlmb5be8c32004-08-18 05:42:05 +0000194 RET2RVAL(ret, rvalue);
195 }
196
vlmd8d90352004-08-20 13:25:56 +0000197 /*
198 * Proceed recursively.
199 */
vlmb5be8c32004-08-18 05:42:05 +0000200 for(el = 0; el < ct->el_count; el++) {
vlm2e0c1942004-08-22 03:10:23 +0000201 ret = asn1constraint_resolve(arg, mod, ct->elements[el],
vlmd8d90352004-08-20 13:25:56 +0000202 etype, effective_type);
vlmb5be8c32004-08-18 05:42:05 +0000203 RET2RVAL(ret, rvalue);
204 }
205
206 return rvalue;
207}
208
209static void
210_remove_exceptions(arg_t *arg, asn1p_constraint_t *ct) {
vlm76142452004-09-05 10:36:22 +0000211 unsigned int i;
vlmb5be8c32004-08-18 05:42:05 +0000212
213 for(i = 0; i < ct->el_count; i++) {
214 if(ct->elements[i]->type == ACT_EL_EXT)
215 break;
216 _remove_exceptions(arg, ct->elements[i]);
217 }
218
219 /* Remove the elements at and after the extensibility mark */
220 for(; i < ct->el_count; ct->el_count--) {
221 asn1p_constraint_t *rm;
222 rm = ct->elements[ct->el_count-1];
223 asn1p_constraint_free(rm);
224 }
225
226 if(i < ct->el_size)
227 ct->elements[i] = 0;
228}
229
230
231static int
vlm2e0c1942004-08-22 03:10:23 +0000232_constraint_value_resolve(arg_t *arg, asn1p_module_t *mod, asn1p_value_t **value) {
vlmb5be8c32004-08-18 05:42:05 +0000233 asn1p_expr_t static_expr;
234 asn1p_expr_t *tmp_expr;
vlmb5be8c32004-08-18 05:42:05 +0000235 arg_t tmp_arg;
236 int rvalue = 0;
237 int ret;
238
vlm2e0c1942004-08-22 03:10:23 +0000239 tmp_expr = asn1f_lookup_symbol(arg, mod, (*value)->value.reference);
vlmb5be8c32004-08-18 05:42:05 +0000240 if(tmp_expr == NULL) {
241 FATAL("Cannot find symbol %s "
242 "used in %s subtype constraint at line %d",
243 asn1f_printable_reference((*value)->value.reference),
244 arg->expr->Identifier, arg->expr->_lineno);
245 assert((*value)->type == ATV_REFERENCED);
246 return -1;
247 }
248
249 static_expr = *tmp_expr;
250 static_expr.value = *value;
251 tmp_arg = *arg;
vlm2e0c1942004-08-22 03:10:23 +0000252 tmp_arg.mod = tmp_expr->module;
vlmb5be8c32004-08-18 05:42:05 +0000253 tmp_arg.expr = &static_expr;
254 ret = asn1f_fix_dereference_values(&tmp_arg);
255 RET2RVAL(ret, rvalue);
256 assert(static_expr.value);
257 *value = static_expr.value;
258
259 return rvalue;
260}