blob: 36b27758650d76a126ac53eb4d47eaa8d8fd3e5f [file] [log] [blame]
vlm1d036692004-08-19 13:29:46 +00001#include "asn1c_internal.h"
2#include "asn1c_constraint.h"
vlmb2839012004-08-20 13:37:01 +00003#include "asn1c_misc.h"
4#include "asn1c_out.h"
vlm1d036692004-08-19 13:29:46 +00005
6#include <asn1fix_crange.h> /* constraint groker from libasn1fix */
7#include <asn1fix_export.h> /* other exportable stuff from libasn1fix */
8
vlmb2839012004-08-20 13:37:01 +00009static int asn1c_emit_constraint_tables(arg_t *arg, int got_size);
vlm1d036692004-08-19 13:29:46 +000010static int emit_alphabet_check_loop(arg_t *arg, asn1cnst_range_t *range);
11static int emit_value_determination_code(arg_t *arg, asn1p_expr_type_e etype);
12static int emit_size_determination_code(arg_t *arg, asn1p_expr_type_e etype);
13static asn1p_expr_type_e _find_terminal_type(arg_t *arg);
14static int emit_range_comparison_code(arg_t *arg, asn1cnst_range_t *range, const char *varname, asn1_integer_t natural_start, asn1_integer_t natural_stop);
15
16#define MKID(id) asn1c_make_identifier(0, (id), 0)
17
18static int global_compile_mark;
19
20int
21asn1c_emit_constraint_checking_code(arg_t *arg) {
22 asn1cnst_range_t *r_size;
23 asn1cnst_range_t *r_value;
24 asn1p_expr_t *expr = arg->expr;
25 asn1p_expr_type_e etype;
26 asn1p_constraint_t *ct;
27 int got_something = 0;
vlmb2839012004-08-20 13:37:01 +000028 int produce_st = 0;
vlm1d036692004-08-19 13:29:46 +000029
30 ct = expr->combined_constraints;
31 if(ct == NULL)
32 return 1; /* No additional constraints defined */
33
34 etype = _find_terminal_type(arg);
35
36 r_value=asn1constraint_compute_PER_range(etype, ct, ACT_EL_RANGE, 0, 0);
37 r_size = asn1constraint_compute_PER_range(etype, ct, ACT_CT_SIZE, 0, 0);
38 if(r_value) {
39 if(r_value->not_PER_visible
40 || r_value->extensible
41 || r_value->empty_constraint
42 || (r_value->left.type == ARE_MIN
43 && r_value->right.type == ARE_MAX)
44 || (etype == ASN_BASIC_BOOLEAN
45 && r_value->left.value == 0
46 && r_value->right.value == 1)
47 ) {
48 asn1constraint_range_free(r_value);
49 r_value = 0;
50 }
51 }
52 if(r_size) {
53 if(r_size->not_PER_visible
54 || r_size->extensible
55 || r_size->empty_constraint
56 || (r_size->left.value == 0 /* or .type == MIN */
57 && r_size->right.type == ARE_MAX)
58 ) {
59 asn1constraint_range_free(r_size);
60 r_size = 0;
61 }
62 }
63
vlmb2839012004-08-20 13:37:01 +000064 /*
65 * Do we really need an "*st = sptr" pointer?
66 */
67 switch(etype) {
68 case ASN_BASIC_INTEGER:
69 case ASN_BASIC_ENUMERATED:
70 if(!(arg->flags & A1C_USE_NATIVE_INTEGERS))
71 produce_st = 1;
72 break;
vlmffa21d22004-08-21 07:34:58 +000073 case ASN_BASIC_BIT_STRING:
vlmb2839012004-08-20 13:37:01 +000074 case ASN_BASIC_OCTET_STRING:
75 produce_st = 1;
76 break;
77 default:
78 if(etype & ASN_STRING_MASK)
79 produce_st = 1;
80 break;
81 }
82 if(produce_st)
vlmffa21d22004-08-21 07:34:58 +000083 OUT("const %s_t *st = sptr;\n",
84 asn1c_type_name(arg, arg->expr, TNF_SAFE));
vlm1d036692004-08-19 13:29:46 +000085
86 if(r_size || r_value) {
87 if(r_size) {
88 OUT("size_t size;\n");
89 }
90 if(r_value)
91 switch(etype) {
92 case ASN_BASIC_INTEGER:
93 case ASN_BASIC_ENUMERATED:
94 OUT("long value;\n");
95 break;
96 case ASN_BASIC_BOOLEAN:
97 OUT("int value;\n");
98 break;
99 default:
100 break;
101 }
102 }
103
104 OUT("\n");
105
106 /*
107 * Protection against null input.
108 */
109 OUT("if(!sptr) {\n");
110 INDENT(+1);
111 OUT("_ASN_ERRLOG(app_errlog, app_key,\n");
vlm758530a2004-08-22 13:47:59 +0000112 OUT("\t\"%%s: value not given (%%s:%%d)\",\n");
113 OUT("\ttd->name, __FILE__, __LINE__);\n");
vlm1d036692004-08-19 13:29:46 +0000114 OUT("return -1;\n");
115 INDENT(-1);
116 OUT("}\n");
117 OUT("\n");
118
119 if(r_value)
120 emit_value_determination_code(arg, etype);
121 if(r_size)
122 emit_size_determination_code(arg, etype);
123
vlmb2839012004-08-20 13:37:01 +0000124 INDENT(-1);
125 REDIR(OT_CTABLES);
126 /* Emit FROM() tables */
127 asn1c_emit_constraint_tables(arg, r_size?1:0);
128 REDIR(OT_CODE);
129 INDENT(+1);
130
vlm1d036692004-08-19 13:29:46 +0000131 /*
132 * Here is an if() {} else {} constaint checking code.
133 */
134 OUT("\n");
135 OUT("if(");
136 INDENT(+1);
137 if(r_size) {
138 if(got_something++) { OUT("\n"); OUT(" && "); }
139 OUT("(");
140 emit_range_comparison_code(arg, r_size, "size", 0, -1);
141 OUT(")");
142 }
143 if(r_value) {
144 if(got_something++) { OUT("\n"); OUT(" && "); }
145 OUT("(");
146 if(etype == ASN_BASIC_BOOLEAN)
147 emit_range_comparison_code(arg, r_value,
148 "value", 0, 1);
149 else
150 emit_range_comparison_code(arg, r_value,
151 "value", -1, -1);
152 OUT(")");
153 }
154 if(ct->_compile_mark) {
155 if(got_something++) { OUT("\n"); OUT(" && "); }
vlm7e20dfc2004-08-22 13:11:40 +0000156 OUT("!check_permitted_alphabet_%d(sptr)",
vlm1d036692004-08-19 13:29:46 +0000157 ct->_compile_mark);
158 }
159 if(!got_something) {
160 OUT("1 /* No applicable constraints whatsoever */");
vlmb2839012004-08-20 13:37:01 +0000161 OUT(") {\n");
162 INDENT(-1);
163 INDENTED(OUT("/* Nothing is here. See below */\n"));
164 OUT("}\n");
165 OUT("\n");
166 return 1;
vlm1d036692004-08-19 13:29:46 +0000167 }
168 INDENT(-1);
169 OUT(") {\n");
170 INDENT(+1);
171 OUT("/* Constraint check succeeded */\n");
vlm22b03112004-08-22 12:37:35 +0000172 OUT("return 0;\n");
vlm1d036692004-08-19 13:29:46 +0000173 INDENT(-1);
174 OUT("} else {\n");
175 INDENT(+1);
176 OUT("_ASN_ERRLOG(app_errlog, app_key,\n");
vlm758530a2004-08-22 13:47:59 +0000177 OUT("\t\"%%s: constraint failed (%%s:%%d)\",\n");
178 OUT("\ttd->name, __FILE__, __LINE__);\n");
vlm1d036692004-08-19 13:29:46 +0000179 OUT("return -1;\n");
180 INDENT(-1);
181 OUT("}\n");
182
183 return 0;
184}
185
vlmb2839012004-08-20 13:37:01 +0000186static int
187asn1c_emit_constraint_tables(arg_t *arg, int got_size) {
vlm1d036692004-08-19 13:29:46 +0000188 asn1_integer_t range_start;
189 asn1_integer_t range_stop;
190 asn1p_expr_type_e etype;
191 asn1cnst_range_t *range;
vlmb2839012004-08-20 13:37:01 +0000192 asn1p_constraint_t *ct;
193 int utf8_full_alphabet_check = 0;
194 int max_table_size = 256;
vlm1d036692004-08-19 13:29:46 +0000195 int table[256];
196 int use_table;
197
vlmb2839012004-08-20 13:37:01 +0000198 ct = arg->expr->combined_constraints;
vlm1d036692004-08-19 13:29:46 +0000199 if(!ct) return 0;
200
201 etype = _find_terminal_type(arg);
202
203 range = asn1constraint_compute_PER_range(etype, ct, ACT_CT_FROM, 0, 0);
204 if(!range) return 0;
205
206 if(range->not_PER_visible
207 || range->extensible
208 || range->empty_constraint) {
209 asn1constraint_range_free(range);
210 return 0;
211 }
212
213 range_start = range->left.value;
214 range_stop = range->right.value;
215 assert(range->left.type == ARE_VALUE);
216 assert(range->right.type == ARE_VALUE);
217 assert(range_start <= range_stop);
218
219 range_start = 0; /* Force old behavior */
220
221 /*
222 * Check if we need a test table to check the alphabet.
223 */
224 use_table = 1;
vlmb2839012004-08-20 13:37:01 +0000225 if(range->el_count == 0) {
226 /*
227 * It's better to have a short if() check
228 * than waste 4k of table space
229 */
230 use_table = 0;
231 }
vlm1d036692004-08-19 13:29:46 +0000232 if((range_stop - range_start) > 255)
233 use_table = 0;
vlmb2839012004-08-20 13:37:01 +0000234 if(etype == ASN_STRING_UTF8String) {
235 if(range_stop >= 0x80)
236 use_table = 0;
237 else
238 max_table_size = 128;
239 }
vlm1d036692004-08-19 13:29:46 +0000240
241 if(!ct->_compile_mark)
242 ct->_compile_mark = ++global_compile_mark;
243
244 if(use_table) {
245 int i, n = 0;
246 int untl;
247 memset(table, 0, sizeof(table));
248 for(i = -1; i < range->el_count; i++) {
249 asn1cnst_range_t *r;
250 asn1_integer_t v;
251 if(i == -1) {
252 if(range->el_count) continue;
253 r = range;
254 } else {
255 r = range->elements[i];
256 }
257 for(v = r->left.value; v <= r->right.value; v++) {
258 assert((v - range_start) >= 0);
vlmb2839012004-08-20 13:37:01 +0000259 assert((v - range_start) < max_table_size);
vlm1d036692004-08-19 13:29:46 +0000260 table[v - range_start] = ++n;
261 }
262 }
263
vlm1d036692004-08-19 13:29:46 +0000264 untl = (range_stop - range_start) + 1;
265 untl += (untl % 16)?16 - (untl % 16):0;
vlmb2839012004-08-20 13:37:01 +0000266 OUT("static int permitted_alphabet_table_%d[%d] = {\n",
267 ct->_compile_mark, max_table_size);
vlm1d036692004-08-19 13:29:46 +0000268 for(n = 0; n < untl; n++) {
269 OUT("%d,", table[n]?1:0);
270 if(!((n+1) % 16)) {
271 int c;
272 if(!n) {
273 OUT("\n");
274 continue;
275 }
276 OUT("\t/* ");
277 for(c = n - 15; c <= n; c++) {
278 if(table[c]) {
279 int a = c + range_start;
280 if(a > 0x20 && a < 0x80)
281 OUT("%c", a);
282 else
283 OUT(".");
284 } else {
285 OUT(" ");
286 }
287 }
288 OUT(" */");
289 OUT("\n");
290 }
291 }
292 OUT("};\n");
293 OUT("\n");
vlmb2839012004-08-20 13:37:01 +0000294 } else if(etype == ASN_STRING_UTF8String) {
295 /*
296 * UTF8String type is a special case in many respects.
297 */
298 assert(range_stop > 255); /* This one's unobvious */
299 if(got_size) {
300 /*
301 * Size has been already determined.
302 * The UTF8String length checker also checks
303 * for the syntax validity, so we don't have
304 * to repeat this process twice.
305 */
306 ct->_compile_mark = 0; /* Don't generate code */
307 asn1constraint_range_free(range);
308 return 0;
309 } else {
310 utf8_full_alphabet_check = 1;
311 }
312 } else {
313 /*
314 * This permitted alphabet check will be
315 * expressed using conditional statements
316 * instead of table lookups. Table would be
317 * to large or otherwise inappropriate (too sparse?).
318 */
vlm1d036692004-08-19 13:29:46 +0000319 }
320
321 OUT("static int check_permitted_alphabet_%d(const void *sptr) {\n",
322 ct->_compile_mark);
vlmb2839012004-08-20 13:37:01 +0000323 INDENT(+1);
324 if(utf8_full_alphabet_check) {
325 OUT("if(UTF8String_length((UTF8String_t *)sptr, td->name, \n");
326 OUT("\tapp_errlog, app_key) == -1)\n");
vlmcdf661b2004-08-22 12:47:03 +0000327 OUT("\t\treturn -1; /* Alphabet (sic!) test failed. */\n");
vlmb2839012004-08-20 13:37:01 +0000328 OUT("\n");
329 } else {
vlm1d036692004-08-19 13:29:46 +0000330 if(use_table) {
331 OUT("int *table = permitted_alphabet_table_%d;\n",
332 ct->_compile_mark);
333 emit_alphabet_check_loop(arg, 0);
334 } else {
335 emit_alphabet_check_loop(arg, range);
336 }
vlmb2839012004-08-20 13:37:01 +0000337 }
vlmcdf661b2004-08-22 12:47:03 +0000338 OUT("return 0;\n");
vlmb2839012004-08-20 13:37:01 +0000339 INDENT(-1);
vlm1d036692004-08-19 13:29:46 +0000340 OUT("}\n");
341 OUT("\n");
342
343 asn1constraint_range_free(range);
344
345 return 0;
346}
347
348static int
349emit_alphabet_check_loop(arg_t *arg, asn1cnst_range_t *range) {
vlm1d036692004-08-19 13:29:46 +0000350 asn1_integer_t natural_stop;
vlmb08de152004-08-22 03:30:05 +0000351 asn1p_expr_t *terminal;
vlm1d036692004-08-19 13:29:46 +0000352
vlmb08de152004-08-22 03:30:05 +0000353 terminal = asn1f_find_terminal_type_ex(arg->asn, arg->mod, arg->expr);
354 if(terminal) {
355 OUT("/* The underlying type is %s */\n",
356 ASN_EXPR_TYPE2STR(terminal->expr_type));
357 } else {
358 terminal = arg->expr;
359 }
vlmffa21d22004-08-21 07:34:58 +0000360 OUT("const %s_t *st = sptr;\n",
vlmb08de152004-08-22 03:30:05 +0000361 asn1c_type_name(arg, terminal, TNF_SAFE));
vlm1d036692004-08-19 13:29:46 +0000362
vlmb08de152004-08-22 03:30:05 +0000363 switch(terminal->expr_type) {
vlm1d036692004-08-19 13:29:46 +0000364 case ASN_STRING_UTF8String:
vlmffa21d22004-08-21 07:34:58 +0000365 OUT("const uint8_t *ch = st->buf;\n");
366 OUT("const uint8_t *end = ch + st->size;\n");
vlm1d036692004-08-19 13:29:46 +0000367 OUT("\n");
368 OUT("for(; ch < end; ch++) {\n");
369 INDENT(+1);
370 OUT("uint8_t cv = *ch;\n");
vlmcdf661b2004-08-22 12:47:03 +0000371 if(!range) OUT("if(cv >= 0x80) return -1;\n");
vlm1d036692004-08-19 13:29:46 +0000372 natural_stop = 0xffffffffUL;
373 break;
374 case ASN_STRING_UniversalString:
vlmffa21d22004-08-21 07:34:58 +0000375 OUT("const uint32_t *ch = st->buf;\n");
376 OUT("const uint32_t *end = ch + st->size;\n");
vlm1d036692004-08-19 13:29:46 +0000377 OUT("\n");
vlmcdf661b2004-08-22 12:47:03 +0000378 OUT("if(st->size % 4) return -1; /* (size%4)! */\n");
vlm1d036692004-08-19 13:29:46 +0000379 OUT("for(; ch < end; ch++) {\n");
380 INDENT(+1);
vlmffa21d22004-08-21 07:34:58 +0000381 OUT("uint32_t cv = (((const uint8_t *)ch)[0] << 24)\n");
382 OUT("\t\t| (((const uint8_t *)ch)[1] << 16)\n");
383 OUT("\t\t| (((const uint8_t *)ch)[2] << 8)\n");
384 OUT("\t\t| ((const uint8_t *)ch)[3];\n");
vlmcdf661b2004-08-22 12:47:03 +0000385 if(!range) OUT("if(cv > 255) return -1;\n");
vlm1d036692004-08-19 13:29:46 +0000386 natural_stop = 0xffffffffUL;
387 break;
388 case ASN_STRING_BMPString:
vlmffa21d22004-08-21 07:34:58 +0000389 OUT("const uint16_t *ch = st->buf;\n");
390 OUT("const uint16_t *end = ch + st->size;\n");
vlm1d036692004-08-19 13:29:46 +0000391 OUT("\n");
vlmcdf661b2004-08-22 12:47:03 +0000392 OUT("if(st->size % 2) return -1; /* (size%2)! */\n");
vlm1d036692004-08-19 13:29:46 +0000393 OUT("for(; ch < end; ch++) {\n");
394 INDENT(+1);
vlmffa21d22004-08-21 07:34:58 +0000395 OUT("uint16_t cv = (((const uint8_t *)ch)[0] << 8)\n");
396 OUT("\t\t| ((const uint8_t *)ch)[1];\n");
vlmcdf661b2004-08-22 12:47:03 +0000397 if(!range) OUT("if(cv > 255) return -1;\n");
vlm1d036692004-08-19 13:29:46 +0000398 natural_stop = 0xffff;
399 break;
400 case ASN_BASIC_OCTET_STRING:
401 default:
vlmffa21d22004-08-21 07:34:58 +0000402 OUT("const uint8_t *ch = st->buf;\n");
403 OUT("const uint8_t *end = ch + st->size;\n");
vlm1d036692004-08-19 13:29:46 +0000404 OUT("\n");
405 OUT("for(; ch < end; ch++) {\n");
406 INDENT(+1);
407 OUT("uint8_t cv = *ch;\n");
408 natural_stop = 0xff;
409 break;
410 }
411
412 if(range) {
413 OUT("if(!(");
414 emit_range_comparison_code(arg, range, "cv", 0, natural_stop);
vlmcdf661b2004-08-22 12:47:03 +0000415 OUT(")) return -1;\n");
vlm1d036692004-08-19 13:29:46 +0000416 } else {
vlmcdf661b2004-08-22 12:47:03 +0000417 OUT("if(!table[cv]) return -1;\n");
vlm1d036692004-08-19 13:29:46 +0000418 }
419
420 INDENT(-1);
421 OUT("}\n");
422
423 return 0;
424}
425
426static int
427emit_range_comparison_code(arg_t *arg, asn1cnst_range_t *range, const char *varname, asn1_integer_t natural_start, asn1_integer_t natural_stop) {
428 int ignore_left;
429 int ignore_right;
vlmb2839012004-08-20 13:37:01 +0000430 int generated_something = 0;
vlm1d036692004-08-19 13:29:46 +0000431 int i;
432
433 for(i = -1; i < range->el_count; i++) {
434 asn1cnst_range_t *r;
435 if(i == -1) {
436 if(range->el_count) continue;
437 r = range;
438 } else {
439 if(i) OUT(" || ");
440 r = range->elements[i];
441 }
442
443 if(r != range) OUT("(");
444
445 ignore_left = (r->left.type == ARE_MIN)
446 || (natural_start != -1
447 && r->left.value <= natural_start);
448 ignore_right = (r->right.type == ARE_MAX)
449 || (natural_stop != -1
450 && r->right.value >= natural_stop);
451 if(ignore_left && ignore_right) {
452 OUT("1 /* Constraint matches natural range of %s */",
453 varname);
454 continue;
455 }
456
457 if(ignore_left) {
458 OUT("%s <= %lld", varname,
459 (long long)r->right.value);
460 } else if(ignore_right) {
461 OUT("%s >= %lld", varname,
462 (long long)r->left.value);
463 } else if(r->left.value == r->right.value) {
464 OUT("%s == %lld", varname,
465 (long long)r->right.value);
466 } else {
467 OUT("%s >= %lld && %s <= %lld",
468 varname,
469 (long long)r->left.value,
470 varname,
471 (long long)r->right.value);
472 }
473 if(r != range) OUT(")");
vlmb2839012004-08-20 13:37:01 +0000474 generated_something = 1;
vlm1d036692004-08-19 13:29:46 +0000475 }
476
vlmb2839012004-08-20 13:37:01 +0000477 return generated_something;
vlm1d036692004-08-19 13:29:46 +0000478}
479
480static int
481emit_size_determination_code(arg_t *arg, asn1p_expr_type_e etype) {
482
483 switch(etype) {
484 case ASN_BASIC_BIT_STRING:
485 OUT("if(st->size > 0) {\n");
486 OUT("\t/* Size in bits */\n");
487 OUT("\tsize = (st->size - 1) - (st->buf[0] & 0x7);\n");
488 OUT("} else {\n");
489 OUT("\tsize = 0;\n");
490 OUT("}\n");
491 break;
492 case ASN_STRING_UniversalString:
493 OUT("size = st->size >> 2;\t/* 4 byte per character */\n");
494 break;
495 case ASN_STRING_BMPString:
496 OUT("size = st->size >> 1;\t/* 2 byte per character */\n");
497 break;
498 case ASN_STRING_UTF8String:
499 OUT("size = UTF8String_length(st, td->name, app_errlog, app_key);\n");
500 OUT("if(size == (size_t)-1) return -1;\n");
501 break;
502 case ASN_CONSTR_SET_OF:
503 case ASN_CONSTR_SEQUENCE_OF:
504 OUT("{ /* Determine the number of elements */\n");
505 INDENT(+1);
vlmb2839012004-08-20 13:37:01 +0000506 OUT("const A_%s_OF(void) *list;\n",
vlm1d036692004-08-19 13:29:46 +0000507 etype==ASN_CONSTR_SET_OF?"SET":"SEQUENCE");
vlmb2839012004-08-20 13:37:01 +0000508 OUT("(const void *)list = sptr;\n");
vlm1d036692004-08-19 13:29:46 +0000509 OUT("size = list->count;\n");
510 INDENT(-1);
511 OUT("}\n");
512 break;
vlmb2839012004-08-20 13:37:01 +0000513 case ASN_BASIC_OCTET_STRING:
514 OUT("size = st->size;\n");
515 break;
vlm1d036692004-08-19 13:29:46 +0000516 default:
vlmb2839012004-08-20 13:37:01 +0000517 if(etype & ASN_STRING_MASK) {
vlm1d036692004-08-19 13:29:46 +0000518 OUT("size = st->size;\n");
519 break;
520 } else {
521 const char *type_name = ASN_EXPR_TYPE2STR(etype);
522 if(!type_name) type_name = arg->expr->Identifier;
523 WARNING("SizeConstraint is not defined for %s",
524 type_name);
525 OUT_NOINDENT("#warning SizeConstraint "
526 "is not defined for %s!\n", type_name);
527 OUT("size = st->size;\n");
528 }
529 return -1;
530 }
531
532 return 0;
533}
534
535static int
536emit_value_determination_code(arg_t *arg, asn1p_expr_type_e etype) {
537
538 switch(etype) {
539 case ASN_BASIC_INTEGER:
540 case ASN_BASIC_ENUMERATED:
541 if(arg->flags & A1C_USE_NATIVE_INTEGERS) {
vlmffa21d22004-08-21 07:34:58 +0000542 OUT("value = *(const int *)sptr;\n");
vlm1d036692004-08-19 13:29:46 +0000543 } else {
544 OUT("if(asn1_INTEGER2long(st, &value)) {\n");
545 INDENT(+1);
546 OUT("_ASN_ERRLOG(app_errlog, app_key,\n");
vlm758530a2004-08-22 13:47:59 +0000547 OUT("\t\"%%s: value too large (%%s:%%d)\",\n");
548 OUT("\ttd->name, __FILE__, __LINE__);\n");
vlm1d036692004-08-19 13:29:46 +0000549 OUT("return -1;\n");
550 INDENT(-1);
551 OUT("}\n");
552 }
553 break;
554 case ASN_BASIC_BOOLEAN:
vlmffa21d22004-08-21 07:34:58 +0000555 OUT("value = (*(const int *)sptr) ? 1 : 0;\n");
vlm1d036692004-08-19 13:29:46 +0000556 break;
557 default:
vlmffa21d22004-08-21 07:34:58 +0000558 WARNING("%s:%d: Value cannot be determined "
559 "for constraint check for %s",
560 arg->mod->source_file_name,
561 arg->expr->_lineno,
562 arg->expr->Identifier
563 );
564 OUT_NOINDENT(
565 "#error %s:%d: Value of %s cannot be determined\n",
566 arg->mod->source_file_name,
567 arg->expr->_lineno,
568 arg->expr->Identifier
569 );
vlm1d036692004-08-19 13:29:46 +0000570 break;
571 }
572
573 return 0;
574}
575
576static asn1p_expr_type_e
577_find_terminal_type(arg_t *arg) {
578 asn1p_expr_t *expr;
vlme8423bc2004-08-22 03:10:52 +0000579 expr = asn1f_find_terminal_type_ex(arg->asn, arg->mod, arg->expr);
vlm1d036692004-08-19 13:29:46 +0000580 if(expr) return expr->expr_type;
581 return A1TC_INVALID;
582}
583