blob: 60259421d1f3afdc75be93528fc45a983e368645 [file] [log] [blame]
vlmfa67ddc2004-06-03 03:38:44 +00001#include "asn1fix_internal.h"
2
3static int _asn1f_copy_value(arg_t *arg, asn1p_expr_t *to,asn1p_expr_t *from);
4
5int
vlm5ba49f52005-03-10 16:15:57 +00006asn1f_value_resolve(arg_t *arg, asn1p_expr_t *expr, const enum asn1p_constraint_type_e *opt_constr_type) {
vlmfa67ddc2004-06-03 03:38:44 +00007 asn1p_expr_t *val_type_expr;
8 asn1p_expr_t *value_expr;
9 asn1p_expr_t *type_expr;
10 int ret;
11
12 /* Make sure this IS a value assignment */
13 assert(expr->meta_type == AMT_VALUE);
14 assert(expr->value);
15
vlm71ad4962004-09-15 11:47:02 +000016 if(expr->value->type != ATV_REFERENCED)
17 return 0;
18
vlm8fba2572005-03-10 11:27:13 +000019 DEBUG("(=\"%s\", %x%s%s)",
20 asn1f_printable_value(expr->value), expr->expr_type,
21 opt_constr_type ? ", " : "",
22 opt_constr_type
23 ? asn1p_constraint_type2str(*opt_constr_type) : ""
24 );
vlmfa67ddc2004-06-03 03:38:44 +000025
26 /*
27 * 1. Find the terminal type for this assignment.
28 */
vlm2e0c1942004-08-22 03:10:23 +000029 type_expr = asn1f_find_terminal_type(arg, expr);
vlmfd245932005-03-10 10:02:50 +000030 DEBUG("terminal type %p", type_expr);
vlmfa67ddc2004-06-03 03:38:44 +000031 if(type_expr == 0) {
vlm20e60cc2005-03-24 16:35:24 +000032 FATAL("Terminal type for %s at line %d not found",
33 expr->Identifier, expr->_lineno);
vlmfa67ddc2004-06-03 03:38:44 +000034 return -1;
35 }
36
vlm71ad4962004-09-15 11:47:02 +000037 if(asn1f_look_value_in_type(arg, type_expr, expr) == -1) {
vlm20e60cc2005-03-24 16:35:24 +000038 FATAL("Value not found in type for %s at line %d",
39 expr->Identifier, expr->_lineno);
vlmfa67ddc2004-06-03 03:38:44 +000040 return -1;
vlm71ad4962004-09-15 11:47:02 +000041 }
vlmfa67ddc2004-06-03 03:38:44 +000042
43 /*
44 * 2. Find the terminal value also.
45 */
vlm2e0c1942004-08-22 03:10:23 +000046 value_expr = asn1f_find_terminal_value(arg, expr);
vlmfa67ddc2004-06-03 03:38:44 +000047 if(value_expr) {
vlm8fba2572005-03-10 11:27:13 +000048 DEBUG("Terminal value for %s->%s is %s at line %d",
vlmfa67ddc2004-06-03 03:38:44 +000049 expr->Identifier, asn1f_printable_value(expr->value),
50 value_expr->Identifier, value_expr->_lineno);
51 } else {
vlm71ad4962004-09-15 11:47:02 +000052 FATAL("Terminal value for %s->%s not found",
vlmfa67ddc2004-06-03 03:38:44 +000053 expr->Identifier, asn1f_printable_value(expr->value));
54 return -1;
55 }
56
57 /*
58 * 3. Find the _type_ of a _terminal value_.
59 */
vlm2e0c1942004-08-22 03:10:23 +000060 WITH_MODULE(value_expr->module,
61 val_type_expr = asn1f_find_terminal_type(arg, value_expr));
vlmfa67ddc2004-06-03 03:38:44 +000062 if(val_type_expr) {
vlm8fba2572005-03-10 11:27:13 +000063 DEBUG("Terminal type of value %s->%s is %s at line %d",
vlmfa67ddc2004-06-03 03:38:44 +000064 expr->Identifier, asn1f_printable_value(expr->value),
65 val_type_expr->Identifier, val_type_expr->_lineno);
66 } else {
vlm8fba2572005-03-10 11:27:13 +000067 FATAL("Terminal type of value %s->%s not found",
vlmfa67ddc2004-06-03 03:38:44 +000068 expr->Identifier, asn1f_printable_value(expr->value));
69 return -1;
70 }
71
72 /*
73 * 4. Check compatibility between the type of the current expression
74 * and the type of the discovered value.
75 */
vlm8fba2572005-03-10 11:27:13 +000076 if(opt_constr_type)
77 ret = asn1constraint_compatible(val_type_expr->expr_type,
78 *opt_constr_type);
79 else
80 ret = asn1f_check_type_compatibility(arg,
81 type_expr, val_type_expr);
vlmfa67ddc2004-06-03 03:38:44 +000082 if(ret == -1) {
vlm59f89da2004-09-06 08:06:37 +000083 switch(type_expr->expr_type) {
vlmc8bb2b12005-03-20 11:07:34 +000084 default:
85 if(!(type_expr->expr_type & ASN_STRING_MASK))
86 break;
87 /* Compatibility rules are not defined */
88 /* Fall through */
vlm59f89da2004-09-06 08:06:37 +000089 case ASN_BASIC_INTEGER:
90 case ASN_BASIC_ENUMERATED:
vlm8fba2572005-03-10 11:27:13 +000091 FATAL("Incompatible type of \"%s\" (%s) at line %d "
92 "with \"%s\" (%s) at line %d",
93 type_expr->Identifier,
94 ASN_EXPR_TYPE2STR(type_expr->expr_type),
95 type_expr->_lineno,
96 val_type_expr->Identifier,
97 ASN_EXPR_TYPE2STR(val_type_expr->expr_type),
98 val_type_expr->_lineno);
vlm59f89da2004-09-06 08:06:37 +000099 return -1;
100 case ASN_BASIC_OBJECT_IDENTIFIER:
101 /*
102 * Ignore this for now.
103 * We can't deal with OIDs inheritance properly yet.
104 */
105 return 0;
vlm59f89da2004-09-06 08:06:37 +0000106 }
vlmc8bb2b12005-03-20 11:07:34 +0000107 WARNING("Possibly incompatible type of \"%s\" (%s) at line %d "
vlm8fba2572005-03-10 11:27:13 +0000108 "with \"%s\" (%s) at line %d",
109 type_expr->Identifier,
110 ASN_EXPR_TYPE2STR(type_expr->expr_type),
111 type_expr->_lineno,
112 val_type_expr->Identifier,
113 ASN_EXPR_TYPE2STR(val_type_expr->expr_type),
114 val_type_expr->_lineno);
vlm59f89da2004-09-06 08:06:37 +0000115 return 1;
vlmfa67ddc2004-06-03 03:38:44 +0000116 }
117
118 if(asn1f_look_value_in_type(arg, val_type_expr, expr) == -1)
119 return -1;
120
121 /*
122 * 5. Copy value from the terminal value into the current expression.
123 */
124 ret = _asn1f_copy_value(arg, expr, value_expr);
125 if(ret == -1) {
vlm71ad4962004-09-15 11:47:02 +0000126 FATAL("Value %s cannot be copied from line %d to line %d",
vlmfa67ddc2004-06-03 03:38:44 +0000127 asn1f_printable_value(value_expr->value),
128 value_expr->_lineno, expr->_lineno);
129 return -1;
130 }
131
vlm8fba2572005-03-10 11:27:13 +0000132 DEBUG("Final value for \"%s\" at line %d is %s",
vlmfa67ddc2004-06-03 03:38:44 +0000133 expr->Identifier, expr->_lineno,
134 asn1f_printable_value(expr->value));
135
136 return 0;
137}
138
139static int
140_asn1f_copy_value(arg_t *arg, asn1p_expr_t *to, asn1p_expr_t *from) {
141 asn1p_value_t *v;
142
143 v = asn1p_value_clone(from->value);
144 if(v) {
145 asn1p_value_free(to->value);
146 to->value = v;
147 DEBUG("Copied value %s from \"%s\" on line %d "
148 "to \"%s\" on line %d",
149 asn1f_printable_value(v),
150 from->Identifier,
151 from->_lineno,
152 to->Identifier,
153 to->_lineno
154 );
155 return 0;
156 } else {
157 return -1;
158 }
159}
160
161int
162asn1f_look_value_in_type(arg_t *arg,
163 asn1p_expr_t *type_expr,
164 asn1p_expr_t *value_expr) {
165 asn1p_expr_t *child_expr;
166 char *identifier;
167
168 if(value_expr->value->type != ATV_REFERENCED
169 || value_expr->value->value.reference->comp_count != 1)
170 return 0;
171 if(type_expr->expr_type != ASN_BASIC_INTEGER
172 && type_expr->expr_type != ASN_BASIC_ENUMERATED)
173 return 0;
174
vlmfd245932005-03-10 10:02:50 +0000175 DEBUG("(for %s in %s %x) for line %d",
vlmfa67ddc2004-06-03 03:38:44 +0000176 asn1f_printable_value(value_expr->value),
177 type_expr->Identifier,
178 type_expr->expr_type,
179 value_expr->_lineno);
180
181 /*
182 * Look into the definitions of the type itself:
183 * Type1 ::= INTEGER { a(1), b(2) }
184 * value Type1 = b -- will assign 2
185 */
186 identifier = value_expr->value->value.reference->components[0].name;
187
188 child_expr = asn1f_lookup_child(type_expr, identifier);
vlm8fba2572005-03-10 11:27:13 +0000189 DEBUG("Looking into a type %s at line %d for %s at line %d: %s",
vlmfa67ddc2004-06-03 03:38:44 +0000190 type_expr->Identifier, type_expr->_lineno,
191 identifier, value_expr->_lineno,
192 child_expr
193 ? asn1f_printable_value(child_expr->value)
194 : "<not found>"
195 );
196
197 if(child_expr && child_expr->value) {
198 if(_asn1f_copy_value(arg, value_expr, child_expr))
199 return -1;
200 /* Fall through */
201 }
202
203 return 0;
204}