blob: 80223d605383919b3789f6e98b1a92205c6de15b [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
6asn1f_value_resolve(arg_t *arg, asn1p_expr_t *expr) {
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
16 DEBUG("%s(=\"%s\", %x)", __func__,
17 asn1f_printable_value(expr->value), expr->expr_type);
18
19 /*
20 * 1. Find the terminal type for this assignment.
21 */
vlm2e0c1942004-08-22 03:10:23 +000022 type_expr = asn1f_find_terminal_type(arg, expr);
vlmb5be8c32004-08-18 05:42:05 +000023 DEBUG("%s(): terminal type %p", __func__, type_expr);
vlmfa67ddc2004-06-03 03:38:44 +000024 if(type_expr == 0) {
vlm59f89da2004-09-06 08:06:37 +000025 FATAL("Terminal type for is %s not found", expr->Identifier);
vlmfa67ddc2004-06-03 03:38:44 +000026 return -1;
27 }
28
29 if(asn1f_look_value_in_type(arg, type_expr, expr) == -1)
30 return -1;
31
32 /*
33 * 2. Find the terminal value also.
34 */
vlm2e0c1942004-08-22 03:10:23 +000035 value_expr = asn1f_find_terminal_value(arg, expr);
vlmfa67ddc2004-06-03 03:38:44 +000036 if(value_expr) {
37 DEBUG("\tTerminal value for %s->%s is %s at line %d",
38 expr->Identifier, asn1f_printable_value(expr->value),
39 value_expr->Identifier, value_expr->_lineno);
40 } else {
41 DEBUG("\tTerminal value for %s->%s not found",
42 expr->Identifier, asn1f_printable_value(expr->value));
43 return -1;
44 }
45
46 /*
47 * 3. Find the _type_ of a _terminal value_.
48 */
vlm2e0c1942004-08-22 03:10:23 +000049 WITH_MODULE(value_expr->module,
50 val_type_expr = asn1f_find_terminal_type(arg, value_expr));
vlmfa67ddc2004-06-03 03:38:44 +000051 if(val_type_expr) {
52 DEBUG("\tTerminal type of value %s->%s is %s at line %d",
53 expr->Identifier, asn1f_printable_value(expr->value),
54 val_type_expr->Identifier, val_type_expr->_lineno);
55 } else {
56 DEBUG("\tTerminal type of value %s->%s not found",
57 expr->Identifier, asn1f_printable_value(expr->value));
58 return -1;
59 }
60
61 /*
62 * 4. Check compatibility between the type of the current expression
63 * and the type of the discovered value.
64 */
65 ret = asn1f_check_type_compatibility(arg, type_expr, val_type_expr);
66 if(ret == -1) {
vlm59f89da2004-09-06 08:06:37 +000067 switch(type_expr->expr_type) {
68 case ASN_BASIC_INTEGER:
69 case ASN_BASIC_ENUMERATED:
70 FATAL("Incompatible type of %s at %d with %s at %d",
vlmfa67ddc2004-06-03 03:38:44 +000071 type_expr->Identifier, type_expr->_lineno,
72 val_type_expr->Identifier, val_type_expr->_lineno);
vlm59f89da2004-09-06 08:06:37 +000073 return -1;
74 case ASN_BASIC_OBJECT_IDENTIFIER:
75 /*
76 * Ignore this for now.
77 * We can't deal with OIDs inheritance properly yet.
78 */
79 return 0;
80 default:
81 break;
82 }
83 WARNING("\tIncompatible type of %s at %d with %s at %d",
84 type_expr->Identifier, type_expr->_lineno,
85 val_type_expr->Identifier, val_type_expr->_lineno);
86 return 1;
vlmfa67ddc2004-06-03 03:38:44 +000087 }
88
89 if(asn1f_look_value_in_type(arg, val_type_expr, expr) == -1)
90 return -1;
91
92 /*
93 * 5. Copy value from the terminal value into the current expression.
94 */
95 ret = _asn1f_copy_value(arg, expr, value_expr);
96 if(ret == -1) {
97 DEBUG("\tValue %s cannot be copied from line %d to line %d",
98 asn1f_printable_value(value_expr->value),
99 value_expr->_lineno, expr->_lineno);
100 return -1;
101 }
102
103 DEBUG("\tFinal value for \"%s\" at line %d is %s",
104 expr->Identifier, expr->_lineno,
105 asn1f_printable_value(expr->value));
106
107 return 0;
108}
109
110static int
111_asn1f_copy_value(arg_t *arg, asn1p_expr_t *to, asn1p_expr_t *from) {
112 asn1p_value_t *v;
113
114 v = asn1p_value_clone(from->value);
115 if(v) {
116 asn1p_value_free(to->value);
117 to->value = v;
118 DEBUG("Copied value %s from \"%s\" on line %d "
119 "to \"%s\" on line %d",
120 asn1f_printable_value(v),
121 from->Identifier,
122 from->_lineno,
123 to->Identifier,
124 to->_lineno
125 );
126 return 0;
127 } else {
128 return -1;
129 }
130}
131
132int
133asn1f_look_value_in_type(arg_t *arg,
134 asn1p_expr_t *type_expr,
135 asn1p_expr_t *value_expr) {
136 asn1p_expr_t *child_expr;
137 char *identifier;
138
139 if(value_expr->value->type != ATV_REFERENCED
140 || value_expr->value->value.reference->comp_count != 1)
141 return 0;
142 if(type_expr->expr_type != ASN_BASIC_INTEGER
143 && type_expr->expr_type != ASN_BASIC_ENUMERATED)
144 return 0;
145
146 DEBUG("%s(for %s in %s %x) for line %d", __func__,
147 asn1f_printable_value(value_expr->value),
148 type_expr->Identifier,
149 type_expr->expr_type,
150 value_expr->_lineno);
151
152 /*
153 * Look into the definitions of the type itself:
154 * Type1 ::= INTEGER { a(1), b(2) }
155 * value Type1 = b -- will assign 2
156 */
157 identifier = value_expr->value->value.reference->components[0].name;
158
159 child_expr = asn1f_lookup_child(type_expr, identifier);
160 DEBUG("\tLooking into a type %s at line %d for %s at line %d: %s",
161 type_expr->Identifier, type_expr->_lineno,
162 identifier, value_expr->_lineno,
163 child_expr
164 ? asn1f_printable_value(child_expr->value)
165 : "<not found>"
166 );
167
168 if(child_expr && child_expr->value) {
169 if(_asn1f_copy_value(arg, value_expr, child_expr))
170 return -1;
171 /* Fall through */
172 }
173
174 return 0;
175}