1 #include "asn1fix_internal.h"
3 static int _asn1f_copy_value(arg_t *arg, asn1p_expr_t *to,asn1p_expr_t *from);
6 asn1f_value_resolve(arg_t *arg, asn1p_expr_t *expr, const enum asn1p_constraint_type_e *opt_constr_type) {
7 asn1p_expr_t *val_type_expr;
8 asn1p_expr_t *value_expr;
9 asn1p_expr_t *type_expr;
12 /* Make sure this IS a value assignment */
13 assert(expr->meta_type == AMT_VALUE);
16 if(expr->value->type != ATV_REFERENCED)
19 DEBUG("(=\"%s\", %x%s%s)",
20 asn1f_printable_value(expr->value), expr->expr_type,
21 opt_constr_type ? ", " : "",
23 ? asn1p_constraint_type2str(*opt_constr_type) : ""
27 * 1. Find the terminal type for this assignment.
29 type_expr = asn1f_find_terminal_type(arg, expr);
32 DEBUG("External type for %s at line %d",
33 expr->Identifier, expr->_lineno);
36 FATAL("Terminal type for %s at line %d not found",
37 expr->Identifier, expr->_lineno);
42 if(asn1f_look_value_in_type(arg, type_expr, expr) == -1) {
43 FATAL("Value not found in type for %s at line %d",
44 expr->Identifier, expr->_lineno);
49 * 2. Find the terminal value also.
51 value_expr = asn1f_find_terminal_value(arg, expr);
53 DEBUG("Terminal value for %s->%s is %s at line %d",
54 expr->Identifier, asn1f_printable_value(expr->value),
55 value_expr->Identifier, value_expr->_lineno);
57 FATAL("Terminal value for %s->%s not found",
58 expr->Identifier, asn1f_printable_value(expr->value));
63 * 3. Find the _type_ of a _terminal value_.
65 WITH_MODULE(value_expr->module,
66 val_type_expr = asn1f_find_terminal_type(arg, value_expr));
68 DEBUG("Terminal type of value %s->%s is %s at line %d",
69 expr->Identifier, asn1f_printable_value(expr->value),
70 val_type_expr->Identifier, val_type_expr->_lineno);
72 FATAL("Terminal type of value %s->%s not found",
73 expr->Identifier, asn1f_printable_value(expr->value));
78 * 4. Check compatibility between the type of the current expression
79 * and the type of the discovered value.
82 ret = asn1constraint_compatible(val_type_expr->expr_type,
83 *opt_constr_type, 0 /* must not matter here */);
85 ret = asn1f_check_type_compatibility(arg,
86 type_expr, val_type_expr);
88 switch(type_expr->expr_type) {
90 if(!(type_expr->expr_type & ASN_STRING_MASK))
92 /* Compatibility rules are not defined */
94 case ASN_BASIC_INTEGER:
95 case ASN_BASIC_ENUMERATED:
96 FATAL("Incompatible type of \"%s\" (%s) at line %d "
97 "with \"%s\" (%s) at line %d",
98 type_expr->Identifier,
99 ASN_EXPR_TYPE2STR(type_expr->expr_type),
101 val_type_expr->Identifier,
102 ASN_EXPR_TYPE2STR(val_type_expr->expr_type),
103 val_type_expr->_lineno);
105 case ASN_BASIC_OBJECT_IDENTIFIER:
107 * Ignore this for now.
108 * We can't deal with OIDs inheritance properly yet.
112 WARNING("Possibly incompatible type of \"%s\" (%s) at line %d "
113 "with \"%s\" (%s) at line %d",
114 type_expr->Identifier,
115 ASN_EXPR_TYPE2STR(type_expr->expr_type),
117 val_type_expr->Identifier,
118 ASN_EXPR_TYPE2STR(val_type_expr->expr_type),
119 val_type_expr->_lineno);
123 if(asn1f_look_value_in_type(arg, val_type_expr, expr) == -1)
127 * 5. Copy value from the terminal value into the current expression.
129 ret = _asn1f_copy_value(arg, expr, value_expr);
131 FATAL("Value %s cannot be copied from line %d to line %d",
132 asn1f_printable_value(value_expr->value),
133 value_expr->_lineno, expr->_lineno);
137 DEBUG("Final value for \"%s\" at line %d is %s",
138 expr->Identifier, expr->_lineno,
139 asn1f_printable_value(expr->value));
145 _asn1f_copy_value(arg_t *arg, asn1p_expr_t *to, asn1p_expr_t *from) {
148 v = asn1p_value_clone(from->value);
150 asn1p_value_free(to->value);
152 DEBUG("Copied value %s from \"%s\" on line %d "
153 "to \"%s\" on line %d",
154 asn1f_printable_value(v),
167 asn1f_look_value_in_type(arg_t *arg,
168 asn1p_expr_t *type_expr,
169 asn1p_expr_t *value_expr) {
170 asn1p_expr_t *child_expr;
173 if(value_expr->value->type != ATV_REFERENCED
174 || value_expr->value->value.reference->comp_count != 1)
176 if(type_expr->expr_type != ASN_BASIC_INTEGER
177 && type_expr->expr_type != ASN_BASIC_ENUMERATED)
180 DEBUG("(for %s in %s %x) for line %d",
181 asn1f_printable_value(value_expr->value),
182 type_expr->Identifier,
183 type_expr->expr_type,
184 value_expr->_lineno);
187 * Look into the definitions of the type itself:
188 * Type1 ::= INTEGER { a(1), b(2) }
189 * value Type1 = b -- will assign 2
191 identifier = value_expr->value->value.reference->components[0].name;
193 child_expr = asn1f_lookup_child(type_expr, identifier);
194 DEBUG("Looking into a type %s at line %d for %s at line %d: %s",
195 type_expr->Identifier, type_expr->_lineno,
196 identifier, value_expr->_lineno,
198 ? asn1f_printable_value(child_expr->value)
203 /* Maybe hasn't been fixed yet. */
204 if (!child_expr->value) {
205 asn1p_expr_t *saved_expr = arg->expr;
206 arg->expr = type_expr;
207 switch (type_expr->expr_type) {
208 case ASN_BASIC_INTEGER:
209 asn1f_fix_integer(arg);
211 case ASN_BASIC_ENUMERATED:
215 WARNING("Unexpected type %s for %s",
216 type_expr->expr_type,
217 type_expr->Identifier);
220 arg->expr = saved_expr;
222 if(child_expr->value && _asn1f_copy_value(arg,
223 value_expr, child_expr))