blob: 0dd0a70f4ff43c2c755b5a035382ab38f0b78fa1 [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001/*
2 * Don't look into this file. First, because it's a mess, and second, because
3 * it's a brain of the compiler, and you don't wanna mess with brains do you? ;)
4 */
5#include "asn1c_internal.h"
6#include "asn1c_C.h"
7#include <asn1fix_export.h> /* exportable stuff from libasn1fix */
8
9static int asn1c_lang_C_type_SEQUENCE_def(arg_t *arg);
10static int asn1c_lang_C_type_SET_def(arg_t *arg);
11static int asn1c_lang_C_type_CHOICE_def(arg_t *arg);
12static int asn1c_lang_C_type_SEx_OF_def(arg_t *arg, int seq_of);
13static int _print_tag(arg_t *arg, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag_p);
14static int emit_constraint_checking_code(arg_t *arg);
15static int emit_single_constraint_check(arg_t *arg, asn1p_constraint_t *ct, int mode);
16static int emit_alphabet_tables(arg_t *arg, asn1p_constraint_t *ct, int *table);
17static int emit_alphabet_check_cycle(arg_t *arg);
18static int check_constraint_type_presence(asn1p_constraint_t *ct, enum asn1p_constraint_type_e type);
19static asn1p_expr_type_e _find_terminal_type(arg_t *arg);
20static int emit_value_determination_code(arg_t *arg);
21static int emit_size_determination_code(arg_t *arg);
22static long compute_min_size(arg_t *arg);
23static long compute_max_size(arg_t *arg);
24static long compute_xxx_size(arg_t *arg, int _max);
25
26typedef struct tag2el_s {
27 struct asn1p_type_tag_s el_tag;
28 int el_no;
29 asn1p_expr_t *from_expr;
30} tag2el_t;
31
32static int _fill_tag2el_map(arg_t *arg, tag2el_t **tag2el, int *count, int el_no);
33static int _add_tag2el_member(arg_t *arg, tag2el_t **tag2el, int *count, int el_no);
34
35#define C99_MODE (arg->flags & A1C_NO_C99)
36#define UNNAMED_UNIONS (arg->flags & A1C_UNNAMED_UNIONS)
37
38#define PCTX_DEF INDENTED( \
39 OUT("\n"); \
40 OUT("/* Context for parsing across buffer boundaries */\n"); \
41 OUT("ber_dec_ctx_t _ber_dec_ctx;\n"));
42
43#define DEPENDENCIES do { \
44 int saved_target = arg->target->target; \
45 int saved_indent = arg->indent_level; \
46 int comment_printed = 0; \
47 REDIR(OT_DEPS); \
48 arg->indent_level = 0; \
49 TQ_FOR(v, &(expr->members), next) { \
50 if((!(v->expr_type & ASN_CONSTR_MASK) \
51 && v->expr_type > ASN_CONSTR_MASK) \
52 || v->meta_type == AMT_TYPEREF) { \
53 if(!comment_printed++) \
54 OUT("/* Dependencies for %s */\n", \
55 asn1c_type_name(arg, expr, TNF_UNMODIFIED)); \
56 OUT("#include <%s.h>\n", \
57 asn1c_type_name(arg, v, TNF_INCLUDE)); \
58 } \
59 } \
60 if(expr->expr_type == ASN_CONSTR_SET_OF) \
61 OUT("#include <asn_SET_OF.h>\n"); \
62 if(expr->expr_type == ASN_CONSTR_SEQUENCE_OF) \
63 OUT("#include <asn_SEQUENCE_OF.h>\n"); \
64 OUT("\n"); \
65 REDIR(saved_target); \
66 INDENT(saved_indent); \
67 } while(0)
68
69#define MKID(id) asn1c_make_identifier(0, (id), 0)
70
71int
72asn1c_lang_C_type_ENUMERATED(arg_t *arg) {
73 asn1p_expr_t *expr = arg->expr;
74 asn1p_expr_t *v;
75
76 REDIR(OT_DEPS);
77
78 OUT("typedef enum %s {\n", MKID(expr->Identifier));
79 TQ_FOR(v, &(expr->members), next) {
80 switch(v->expr_type) {
81 case A1TC_UNIVERVAL:
82 OUT("\t%s\t= %lld,\n",
83 asn1c_make_identifier(0,
84 expr->Identifier,
85 v->Identifier, 0),
86 v->value->value.v_integer);
87 break;
88 case A1TC_EXTENSIBLE:
89 OUT("\t/*\n");
90 OUT("\t * Enumeration is extensible\n");
91 OUT("\t */\n");
92 break;
93 default:
94 return -1;
95 }
96 }
97 OUT("} %s_e;\n", MKID(expr->Identifier));
98
99 return asn1c_lang_C_type_SIMPLE_TYPE(arg);
100}
101
102
103int
104asn1c_lang_C_type_INTEGER(arg_t *arg) {
105 asn1p_expr_t *expr = arg->expr;
106 asn1p_expr_t *v;
107
108 REDIR(OT_DEPS);
109
110 if(TQ_FIRST(&(expr->members))) {
111 OUT("typedef enum %s {\n", MKID(expr->Identifier));
112 TQ_FOR(v, &(expr->members), next) {
113 switch(v->expr_type) {
114 case A1TC_UNIVERVAL:
115 OUT("\t%s\t= %lld,\n",
116 asn1c_make_identifier(0,
117 expr->Identifier,
118 v->Identifier, 0),
119 v->value->value.v_integer);
120 break;
121 default:
122 return -1;
123 }
124 }
125 OUT("} %s_e;\n", MKID(expr->Identifier));
126 }
127
128 return asn1c_lang_C_type_SIMPLE_TYPE(arg);
129}
130
131int
132asn1c_lang_C_type_SEQUENCE(arg_t *arg) {
133 asn1p_expr_t *expr = arg->expr;
134 asn1p_expr_t *v;
135 int comp_mode = 0; /* {root,ext=1,root,root,...} */
136
137 DEPENDENCIES;
138
139 if(arg->embed) {
140 OUT("struct %s {\n",
141 MKID(expr->Identifier));
142 } else {
143 OUT("typedef struct %s {\n",
144 MKID(expr->Identifier));
145 }
146
147 TQ_FOR(v, &(expr->members), next) {
148 if(v->expr_type == A1TC_EXTENSIBLE) {
149 if(comp_mode < 3) comp_mode++;
150 }
151 if(comp_mode == 1 && !v->marker)
152 v->marker = EM_OPTIONAL;
153 EMBED(v);
154 }
155
156 PCTX_DEF;
157 OUT("} %s%s", expr->marker?"*":"",
158 MKID(expr->Identifier));
159 if(arg->embed) OUT(";\n"); else OUT("_t;\n");
160
161 return asn1c_lang_C_type_SEQUENCE_def(arg);
162}
163
164static int
165asn1c_lang_C_type_SEQUENCE_def(arg_t *arg) {
166 asn1p_expr_t *expr = arg->expr;
167 asn1p_expr_t *v;
168 int elements; /* Number of elements */
169 int tags_impl_skip = 0;
170 int comp_mode = 0; /* {root,ext=1,root,root,...} */
171 int ext_start = -1;
172 int ext_stop = -1;
173 char *p;
174
175 REDIR(OT_STAT_DEFS);
176
177 OUT("#include <constr_SEQUENCE.h>\n");
178 OUT("\n");
179
180 /*
181 * Print out the table according to which the parsing is performed.
182 */
183 p = MKID(expr->Identifier);
184 OUT("static asn1_SEQUENCE_element_t asn1_DEF_%s_elements[] = {\n", p);
185
186 elements = 0;
187 INDENTED(TQ_FOR(v, &(expr->members), next) {
188 if(v->expr_type == A1TC_EXTENSIBLE) {
189 if((++comp_mode) == 1)
190 ext_start = elements - 1;
191 else
192 ext_stop = elements - 1;
193 continue;
194 }
195 OUT("{ ");
196 elements++;
197 OUT("offsetof(struct %s, ", MKID(expr->Identifier));
198 OUT("%s), ", MKID(v->Identifier));
199 if(v->marker) {
200 asn1p_expr_t *tv;
201 int opts = 0;
202 for(tv = v; tv && tv->marker;
203 tv = TQ_NEXT(tv, next), opts++) {
204 if(tv->expr_type == A1TC_EXTENSIBLE)
205 opts--;
206 }
207 OUT("%d,", opts);
208 } else {
209 OUT("0,");
210 }
211 OUT("\n");
212 INDENT(+1);
213 if(C99_MODE) OUT(".tag = ");
214 _print_tag(arg, v, NULL);
215 OUT(",\n");
216 if(C99_MODE) OUT(".tag_mode = ");
217 if(v->tag.tag_class) {
218 if(v->tag.tag_mode == TM_IMPLICIT)
219 OUT("-1,\t/* IMPLICIT tag at current level */\n");
220 else
221 OUT("+1,\t/* EXPLICIT tag at current level */\n");
222 } else {
223 OUT("0,\n");
224 }
225 if(C99_MODE) OUT(".type = ");
226 OUT("(void *)&asn1_DEF_%s,\n",
227 asn1c_type_name(arg, v, TNF_SAFE));
228 if(C99_MODE) OUT(".name = ");
229 OUT("\"%s\"\n", v->Identifier);
230 OUT("},\n");
231 INDENT(-1);
232 });
233 OUT("};\n");
234
235 p = MKID(expr->Identifier);
236 OUT("static ber_tlv_tag_t asn1_DEF_%s_tags[] = {\n", p);
237 INDENTED(
238 if(expr->tag.tag_class) {
239 _print_tag(arg, expr, &expr->tag);
240 if(expr->tag.tag_mode != TM_EXPLICIT)
241 tags_impl_skip++;
242 }
243 if(!expr->tag.tag_class
244 || (expr->meta_type == AMT_TYPE
245 && expr->tag.tag_mode == TM_EXPLICIT)) {
246 struct asn1p_type_tag_s tag;
247 if(expr->tag.tag_class)
248 OUT(",\n");
249 tag.tag_class = TC_UNIVERSAL;
250 tag.tag_mode = TM_IMPLICIT;
251 tag.tag_value = expr_type2uclass_value[expr->expr_type];
252 _print_tag(arg, expr, &tag);
253 }
254 OUT("\n");
255 );
256 OUT("};\n");
257
258 OUT("static asn1_SEQUENCE_specifics_t asn1_DEF_%s_specs = {\n", p);
259 INDENTED(
260 OUT("sizeof(struct %s),\n", p);
261 OUT("offsetof(struct %s, _ber_dec_ctx),\n", p);
262 OUT("asn1_DEF_%s_elements,\n", p);
263 OUT("%d,\t/* Elements count */\n", elements);
264 OUT("%d,\t/* Start extensions */\n",
265 ext_start);
266 OUT("%d\t/* Stop extensions */\n",
267 (ext_stop<ext_start)?elements+1:ext_stop, ext_stop);
268 );
269 OUT("};\n");
270 OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
271 INDENTED(
272 OUT("\"%s\",\n", expr->Identifier);
273 OUT("SEQUENCE_constraint,\n");
274 OUT("SEQUENCE_decode_ber,\n");
275 OUT("SEQUENCE_encode_der,\n");
276 OUT("SEQUENCE_print,\n");
277 OUT("SEQUENCE_free,\n");
278 OUT("0,\t/* Use generic outmost tag fetcher */\n");
279 OUT("asn1_DEF_%s_tags,\n", p);
280 OUT("sizeof(asn1_DEF_%s_tags)\n", p);
281 OUT("\t/sizeof(asn1_DEF_%s_tags[0]),\n", p);
282 OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
283 OUT("%d,\t/* Whether CONSTRUCTED */\n", 1);
284 OUT("&asn1_DEF_%s_specs\t/* Additional specs */\n", p);
285 );
286 OUT("};\n");
287 OUT("\n");
288
289 REDIR(OT_DEPS);
290 OUT("#include <constr_SEQUENCE.h>\n");
291 OUT("\n");
292 if(!arg->embed)
293 OUT("extern asn1_TYPE_descriptor_t asn1_DEF_%s;\n", p);
294 REDIR(OT_TYPE_DECLS);
295
296 return 0;
297}
298
299int
300asn1c_lang_C_type_SEQUENCE_OF(arg_t *arg) {
301 asn1p_expr_t *expr = arg->expr;
302 asn1p_expr_t *v;
303
304 DEPENDENCIES;
305
306 if(arg->embed) {
307 OUT("struct %s {\n", MKID(expr->Identifier));
308 } else {
309 OUT("typedef struct %s {\n", MKID(expr->Identifier));
310 }
311
312 TQ_FOR(v, &(expr->members), next) {
313 INDENTED(OUT("A_SEQUENCE_OF(%s) list;\n",
314 asn1c_type_name(arg, v, TNF_RSAFE)));
315 }
316
317 PCTX_DEF;
318 OUT("} %s%s", expr->marker?"*":"", MKID(expr->Identifier));
319 if(arg->embed) OUT(";\n"); else OUT("_t;\n");
320
321 /*
322 * SET OF/SEQUENCE OF definition, SEQUENCE OF mode.
323 */
324 return asn1c_lang_C_type_SEx_OF_def(arg, 1);
325}
326
327int
328asn1c_lang_C_type_SET(arg_t *arg) {
329 asn1p_expr_t *expr = arg->expr;
330 asn1p_expr_t *v;
331 long mcount;
332 char *id;
333 int comp_mode = 0; /* {root,ext=1,root,root,...} */
334
335 DEPENDENCIES;
336
337 REDIR(OT_DEPS);
338
339 OUT("\n");
340 OUT("/*\n");
341 OUT(" * Method of determining the components presence\n");
342 OUT(" */\n");
343 mcount = 0;
344 OUT("enum %s_PR_e {\n", MKID(expr->Identifier));
345 TQ_FOR(v, &(expr->members), next) {
346 if(v->expr_type == A1TC_EXTENSIBLE) continue;
347 INDENTED(
348 id = MKID(expr->Identifier);
349 OUT("%s_PR_", id);
350 id = MKID(v->Identifier);
351 OUT("%s,\t/* Member %s is present */\n",
352 id, id)
353 );
354 mcount++;
355 }
356 OUT("};\n");
357
358 REDIR(OT_TYPE_DECLS);
359
360 if(arg->embed) {
361 OUT("struct %s {\n", MKID(expr->Identifier));
362 } else {
363 OUT("typedef struct %s {\n", MKID(expr->Identifier));
364 }
365
366 TQ_FOR(v, &(expr->members), next) {
367 if(v->expr_type == A1TC_EXTENSIBLE) {
368 if(comp_mode < 3) comp_mode++;
369 }
370 if(comp_mode == 1 && !v->marker)
371 v->marker = EM_OPTIONAL;
372 EMBED(v);
373 }
374
375 INDENTED(
376 id = MKID(expr->Identifier);
377 OUT("\n");
378 OUT("/* Presence bitmask: ASN_SET_ISPRESENT(p%s, %s_PR_x) */\n",
379 id, id);
380 OUT("unsigned int _presence_map\n");
381 OUT("\t[((%ld+(8*sizeof(unsigned int))-1)/(8*sizeof(unsigned int)))];\n", mcount);
382 );
383
384 PCTX_DEF;
385 OUT("} %s%s", expr->marker?"*":"", MKID(expr->Identifier));
386 if(arg->embed) OUT(";\n"); else OUT("_t;\n");
387
388 return asn1c_lang_C_type_SET_def(arg);
389}
390
391/*
392 * Compare tags according to their canonical order.
393 * Canonical order: [UNIVERSAL] [APPLICATION] [] [PRIVATE]
394 * As you see, the class is encoded using the two lowest bits.
395 */
396static arg_t *_ctc_arg;
397static int _canonical_tags_cmp(const void *ap, const void *bp)
398 __attribute__ ((unused));
399static int
400_canonical_tags_cmp(const void *ap, const void *bp) {
401 asn1p_expr_t *a, *b;
402 struct asn1p_type_tag_s ta, tb;
403
404 (const asn1p_expr_t *)a = *(const asn1p_expr_t * const *)ap;
405 (const asn1p_expr_t *)b = *(const asn1p_expr_t * const *)bp;
406
407 if(asn1f_fetch_tag(_ctc_arg->asn, _ctc_arg->mod, a, &ta)
408 || asn1f_fetch_tag(_ctc_arg->asn, _ctc_arg->mod, b, &tb))
409 return 0;
410
411 if(ta.tag_class == tb.tag_class) {
412 if(ta.tag_value == tb.tag_value)
413 return 0;
414 else if(ta.tag_value < tb.tag_value)
415 return -1;
416 else
417 return 1;
418 } else if(ta.tag_class < tb.tag_class) {
419 return -1;
420 } else {
421 return 1;
422 }
423}
424
425static int
426_tag2el_cmp(const void *ap, const void *bp) {
427 const tag2el_t *a = ap;
428 const tag2el_t *b = bp;
429 const struct asn1p_type_tag_s *ta = &a->el_tag;
430 const struct asn1p_type_tag_s *tb = &b->el_tag;
431
432 if(ta->tag_class == tb->tag_class) {
433 if(ta->tag_value == tb->tag_value)
434 return 0;
435 else if(ta->tag_value < tb->tag_value)
436 return -1;
437 else
438 return 1;
439 } else if(ta->tag_class < tb->tag_class) {
440 return -1;
441 } else {
442 return 1;
443 }
444}
445
446static int
447asn1c_lang_C_type_SET_def(arg_t *arg) {
448 asn1p_expr_t *expr = arg->expr;
449 asn1p_expr_t *v;
450 int elements;
451 int tags_impl_skip = 0;
452 int comp_mode = 0; /* {root,ext=1,root,root,...} */
453 int extensible = 0;
454 tag2el_t *tag2el = NULL;
455 int tag2el_count = 0;
456 char *p;
457
458 /*
459 * Fetch every inner tag from the tag to elements map.
460 */
461 if(_fill_tag2el_map(arg, &tag2el, &tag2el_count, -1)) {
462 if(tag2el) free(tag2el);
463 return -1;
464 } else {
465 /*
466 * Sort the map according to canonical order of their tags.
467 */
468 _ctc_arg = arg;
469 qsort(tag2el, tag2el_count, sizeof(*tag2el), _tag2el_cmp);
470 }
471
472
473 REDIR(OT_STAT_DEFS);
474
475 OUT("#include <constr_SET.h>\n");
476 OUT("\n");
477
478 /*
479 * Print out the table according to which the parsing is performed.
480 */
481 p = MKID(expr->Identifier);
482 OUT("static asn1_SET_element_t asn1_DEF_%s_elements[] = {\n", p);
483
484 elements = 0;
485 INDENTED(TQ_FOR(v, &(expr->members), next) {
486 if(v->expr_type != A1TC_EXTENSIBLE) {
487 if(comp_mode == 1)
488 v->marker = EM_OPTIONAL;
489 elements++;
490 } else {
491 if(comp_mode < 3) comp_mode++;
492 continue;
493 }
494 OUT("{ ");
495 p = MKID(expr->Identifier);
496 OUT("offsetof(struct %s, ", p);
497 p = MKID(v->Identifier);
498 OUT("%s), ", p);
499 if(v->marker) {
500 OUT("1, /* Optional element */\n");
501 } else {
502 OUT("0,\n");
503 }
504 INDENT(+1);
505 if(C99_MODE) OUT(".tag = ");
506 _print_tag(arg, v, NULL);
507 OUT(",\n");
508 if(C99_MODE) OUT(".tag_mode = ");
509 if(v->tag.tag_class) {
510 if(v->tag.tag_mode == TM_IMPLICIT)
511 OUT("-1,\t/* IMPLICIT tag at current level */\n");
512 else
513 OUT("+1,\t/* EXPLICIT tag at current level */\n");
514 } else {
515 OUT("0,\n");
516 }
517 if(C99_MODE) OUT(".type = ");
518 OUT("(void *)&asn1_DEF_%s,\n",
519 asn1c_type_name(arg, v, TNF_SAFE));
520 if(C99_MODE) OUT(".name = ");
521 OUT("\"%s\"\n", v->Identifier);
522 OUT("},\n");
523 INDENT(-1);
524 });
525 OUT("};\n");
526
527 p = MKID(expr->Identifier);
528 OUT("static ber_tlv_tag_t asn1_DEF_%s_tags[] = {\n", p);
529 INDENTED(
530 if(expr->tag.tag_class) {
531 _print_tag(arg, expr, &expr->tag);
532 if(expr->tag.tag_mode != TM_EXPLICIT)
533 tags_impl_skip++;
534 }
535 if(!expr->tag.tag_class
536 || (expr->meta_type == AMT_TYPE
537 && expr->tag.tag_mode == TM_EXPLICIT)) {
538 struct asn1p_type_tag_s tag;
539 if(expr->tag.tag_class)
540 OUT(",\n");
541 tag.tag_class = TC_UNIVERSAL;
542 tag.tag_mode = TM_IMPLICIT;
543 tag.tag_value = expr_type2uclass_value[expr->expr_type];
544 _print_tag(arg, expr, &tag);
545 }
546 OUT("\n");
547 );
548 OUT("};\n");
549
550 /*
551 * Tags to elements map.
552 */
553 p = MKID(expr->Identifier);
554 OUT("static asn1_SET_tag2member_t asn1_DEF_%s_tag2el[] = {\n", p);
555 if(tag2el_count) {
556 int i;
557 for(i = 0; i < tag2el_count; i++) {
558 OUT(" { ");
559 _print_tag(arg, expr, &tag2el[i].el_tag);
560 OUT(", ");
561 OUT("%d ", tag2el[i].el_no);
562 OUT("}, /* %s at %d */\n",
563 tag2el[i].from_expr->Identifier,
564 tag2el[i].from_expr->_lineno
565 );
566 }
567 }
568 OUT("};\n");
569
570 /*
571 * Emit a map of mandatory elements.
572 */
573 OUT("static uint8_t asn1_DEF_%s_mmap", p);
574 OUT("[(%d + (8 * sizeof(unsigned int)) - 1) / 8]", elements);
575 OUT(" = {\n", p);
576 INDENTED(
577 if(elements) {
578 int delimit = 0;
579 int el = 0;
580 TQ_FOR(v, &(expr->members), next) {
581 if(v->expr_type == A1TC_EXTENSIBLE) continue;
582 if(delimit) {
583 OUT(",\n");
584 delimit = 0;
585 } else if(el) {
586 OUT(" | ");
587 }
588 OUT("(%d << %d)", v->marker?0:1, 7 - (el % 8));
589 if(el && (el % 8) == 0)
590 delimit = 1;
591 el++;
592 }
593 } else {
594 OUT("0");
595 }
596 );
597 OUT("\n");
598 OUT("};\n");
599
600 OUT("static asn1_SET_specifics_t asn1_DEF_%s_specs = {\n", p);
601 INDENTED(
602 OUT("sizeof(struct %s),\n", p);
603 OUT("offsetof(struct %s, _ber_dec_ctx),\n", p);
604 OUT("offsetof(struct %s, _presence_map),\n", p);
605 OUT("asn1_DEF_%s_elements,\n", p);
606 OUT("%d,\t/* Elements count */\n", elements);
607 OUT("asn1_DEF_%s_tag2el,\n", p);
608 OUT("%d,\t/* Count of tags in the map */\n", tag2el_count);
609 OUT("%d,\t/* Whether extensible */\n", extensible);
610 OUT("(unsigned int *)asn1_DEF_%s_mmap\t/* Mandatory elements map */\n", p);
611 );
612 OUT("};\n");
613 OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
614 INDENTED(
615 OUT("\"%s\",\n", expr->Identifier);
616 OUT("SET_constraint,\n");
617 OUT("SET_decode_ber,\n");
618 OUT("SET_encode_der,\n");
619 OUT("SET_print,\n");
620 OUT("SET_free,\n");
621 OUT("0,\t/* Use generic outmost tag fetcher */\n");
622 OUT("asn1_DEF_%s_tags,\n", p);
623 OUT("sizeof(asn1_DEF_%s_tags)\n", p);
624 OUT("\t/sizeof(asn1_DEF_%s_tags[0]),\n", p);
625 OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
626 OUT("%d,\t/* Whether CONSTRUCTED */\n", 1);
627 OUT("&asn1_DEF_%s_specs\t/* Additional specs */\n", p);
628 );
629 OUT("};\n");
630 OUT("\n");
631
632 REDIR(OT_DEPS);
633 OUT("#include <constr_SET.h>\n");
634 OUT("\n");
635 if(!arg->embed)
636 OUT("extern asn1_TYPE_descriptor_t asn1_DEF_%s;\n", p);
637 REDIR(OT_TYPE_DECLS);
638
639 return 0;
640}
641
642int
643asn1c_lang_C_type_SET_OF(arg_t *arg) {
644 asn1p_expr_t *expr = arg->expr;
645 asn1p_expr_t *v;
646
647 DEPENDENCIES;
648
649 if(arg->embed) {
650 OUT("struct %s {\n", MKID(expr->Identifier));
651 } else {
652 OUT("typedef struct %s {\n",
653 MKID(expr->Identifier));
654 }
655
656 TQ_FOR(v, &(expr->members), next) {
657 INDENTED(OUT("A_SET_OF(%s) list;\n",
658 asn1c_type_name(arg, v, TNF_RSAFE)));
659 }
660
661 PCTX_DEF;
662 OUT("} %s%s", expr->marker?"*":"", MKID(expr->Identifier));
663 if(arg->embed) OUT(";\n"); else OUT("_t;\n");
664
665 /*
666 * SET OF/SEQUENCE OF definition, SET OF mode.
667 */
668 return asn1c_lang_C_type_SEx_OF_def(arg, 0);
669}
670
671static int
672asn1c_lang_C_type_SEx_OF_def(arg_t *arg, int seq_of) {
673 asn1p_expr_t *expr = arg->expr;
674 asn1p_expr_t *v;
675 int tags_impl_skip = 0;
676 char *p;
677
678 REDIR(OT_DEPS);
679
680 if(seq_of) {
681 OUT("#include <constr_SEQUENCE_OF.h>\n");
682 } else {
683 OUT("#include <constr_SET_OF.h>\n");
684 OUT("\n");
685 }
686
687 REDIR(OT_STAT_DEFS);
688
689 /*
690 * Print out the table according to which the parsing is performed.
691 */
692 p = MKID(expr->Identifier);
693 OUT("static asn1_SET_OF_element_t asn1_DEF_%s_elements[] = {\n", p);
694
695 INDENTED(OUT("{ ");
696 v = TQ_FIRST(&(expr->members));
697 INDENT(+1);
698 if(C99_MODE) OUT(".tag = ");
699 _print_tag(arg, v, NULL);
700 OUT(",\n");
701 if(C99_MODE) OUT(".type = ");
702 OUT("(void *)&asn1_DEF_%s",
703 asn1c_type_name(arg, v, TNF_SAFE));
704 OUT(" ");
705 OUT("},\n");
706 INDENT(-1);
707 );
708 OUT("};\n");
709
710 p = MKID(expr->Identifier);
711 OUT("static ber_tlv_tag_t asn1_DEF_%s_tags[] = {\n", p);
712 INDENTED(
713 if(expr->tag.tag_class) {
714 _print_tag(arg, expr, &expr->tag);
715 if(expr->tag.tag_mode != TM_EXPLICIT)
716 tags_impl_skip++;
717 }
718 if(!expr->tag.tag_class
719 || (expr->meta_type == AMT_TYPE
720 && expr->tag.tag_mode == TM_EXPLICIT)) {
721 struct asn1p_type_tag_s tag;
722 if(expr->tag.tag_class)
723 OUT(",\n");
724 tag.tag_class = TC_UNIVERSAL;
725 tag.tag_mode = TM_IMPLICIT;
726 tag.tag_value = expr_type2uclass_value[expr->expr_type];
727 _print_tag(arg, expr, &tag);
728 }
729 OUT("\n");
730 );
731 OUT("};\n");
732
733 OUT("static asn1_SET_OF_specifics_t asn1_DEF_%s_specs = {\n", p);
734 INDENTED(
735 OUT("sizeof(struct %s),\n", p);
736 OUT("offsetof(struct %s, _ber_dec_ctx),\n", p);
737 OUT("asn1_DEF_%s_elements\n", p);
738 );
739 OUT("};\n");
740 OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
741 INDENTED(
742 OUT("\"%s\",\n", expr->Identifier);
743 if(seq_of) {
744 OUT("SEQUENCE_OF_constraint,\n");
745 OUT("SEQUENCE_OF_decode_ber,\n");
746 OUT("SEQUENCE_OF_encode_der,\n");
747 OUT("SEQUENCE_OF_print,\n");
748 OUT("SEQUENCE_OF_free,\n");
749 } else {
750 OUT("SET_OF_constraint,\n");
751 OUT("SET_OF_decode_ber,\n");
752 OUT("SET_OF_encode_der,\n");
753 OUT("SET_OF_print,\n");
754 OUT("SET_OF_free,\n");
755 }
756 OUT("0,\t/* Use generic outmost tag fetcher */\n");
757 OUT("asn1_DEF_%s_tags,\n", p);
758 OUT("sizeof(asn1_DEF_%s_tags)\n", p);
759 OUT("\t/sizeof(asn1_DEF_%s_tags[0]),\n", p);
760 OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
761 OUT("%d,\t/* Whether CONSTRUCTED */\n", 1);
762 OUT("&asn1_DEF_%s_specs\t/* Additional specs */\n", p);
763 );
764 OUT("};\n");
765 OUT("\n");
766
767 REDIR(OT_DEPS);
768 if(!arg->embed)
769 OUT("extern asn1_TYPE_descriptor_t asn1_DEF_%s;\n", p);
770 REDIR(OT_TYPE_DECLS);
771
772 return 0;
773}
774
775int
776asn1c_lang_C_type_CHOICE(arg_t *arg) {
777 asn1p_expr_t *expr = arg->expr;
778 asn1p_expr_t *v;
779 char *p;
780
781 DEPENDENCIES;
782
783 p = MKID(expr->Identifier);
784
785 if(arg->embed) {
786 OUT("struct %s {\n", p);
787 } else {
788 OUT("typedef struct %s {\n", p);
789 }
790
791 INDENTED(
792 OUT("enum {\n");
793 INDENTED(
794 OUT("%s_PR_NOTHING,\t"
795 "/* No components present */\n", p);
796 TQ_FOR(v, &(expr->members), next) {
797 if(v->expr_type == A1TC_EXTENSIBLE) continue;
798 p = MKID(expr->Identifier);
799 OUT("%s_PR_", p);
800 p = MKID(v->Identifier);
801 OUT("%s,\n", p, p);
802 }
803 );
804 OUT("} present;\n");
805
806 OUT("union {\n", p);
807 TQ_FOR(v, &(expr->members), next) {
808 EMBED(v);
809 }
810 if(UNNAMED_UNIONS) OUT("};\n");
811 else OUT("} choice;\n");
812 );
813
814 PCTX_DEF;
815 OUT("} %s%s", expr->marker?"*":"", MKID(expr->Identifier));
816 if(arg->embed) OUT(";\n"); else OUT("_t;\n");
817
818 return asn1c_lang_C_type_CHOICE_def(arg);
819}
820
821static int
822asn1c_lang_C_type_CHOICE_def(arg_t *arg) {
823 asn1p_expr_t *expr = arg->expr;
824 asn1p_expr_t *v;
825 int elements; /* Number of elements */
826 int tags_impl_skip = 0;
827 int comp_mode = 0; /* {root,ext=1,root,root,...} */
828 int extensible = 0;
829 tag2el_t *tag2el = NULL;
830 int tag2el_count = 0;
831 char *p;
832
833 /*
834 * Fetch every inner tag from the tag to elements map.
835 */
836 if(_fill_tag2el_map(arg, &tag2el, &tag2el_count, -1)) {
837 if(tag2el) free(tag2el);
838 return -1;
839 } else {
840 /*
841 * Sort the map according to canonical order of their tags.
842 */
843 _ctc_arg = arg;
844 qsort(tag2el, tag2el_count, sizeof(*tag2el), _tag2el_cmp);
845 }
846
847 REDIR(OT_STAT_DEFS);
848
849 OUT("#include <constr_CHOICE.h>\n");
850 OUT("\n");
851
852 /*
853 * Print out the table according to which the parsing is performed.
854 */
855 p = MKID(expr->Identifier);
856 OUT("static asn1_CHOICE_element_t asn1_DEF_%s_elements[] = {\n", p);
857
858 elements = 0;
859 INDENTED(TQ_FOR(v, &(expr->members), next) {
860 if(v->expr_type != A1TC_EXTENSIBLE) {
861 if(comp_mode == 1)
862 v->marker = EM_OPTIONAL;
863 elements++;
864 } else {
865 if(comp_mode < 3) comp_mode++;
866 continue;
867 }
868 OUT("{ ");
869 p = MKID(expr->Identifier);
870 OUT("offsetof(struct %s, ", p);
871 p = MKID(v->Identifier);
872 if(!UNNAMED_UNIONS) OUT("choice.");
873 OUT("%s), ", p);
874 if(v->marker) {
875 OUT("1, /* Optional element */\n");
876 } else {
877 OUT("0,\n");
878 }
879 INDENT(+1);
880 if(C99_MODE) OUT(".tag = ");
881 _print_tag(arg, v, NULL);
882 OUT(",\n");
883 if(C99_MODE) OUT(".tag_mode = ");
884 if(v->tag.tag_class) {
885 if(v->tag.tag_mode == TM_IMPLICIT)
886 OUT("-1,\t/* IMPLICIT tag at current level */\n");
887 else
888 OUT("+1,\t/* EXPLICIT tag at current level */\n");
889 } else {
890 OUT("0,\n");
891 }
892 if(C99_MODE) OUT(".type = ");
893 OUT("(void *)&asn1_DEF_%s,\n",
894 asn1c_type_name(arg, v, TNF_SAFE));
895 if(C99_MODE) OUT(".name = ");
896 OUT("\"%s\"\n", v->Identifier);
897 OUT("},\n");
898 INDENT(-1);
899 });
900 OUT("};\n");
901
902 p = MKID(expr->Identifier);
903 OUT("static ber_tlv_tag_t asn1_DEF_%s_tags[] = {\n", p);
904 if(arg->embed) {
905 /*
906 * Our parent structure has already taken this into account.
907 */
908 } else {
909 INDENTED(
910 if(expr->tag.tag_class) {
911 _print_tag(arg, expr, &expr->tag);
912 if(expr->tag.tag_mode != TM_EXPLICIT)
913 tags_impl_skip++;
914 }
915 OUT("\n");
916 );
917 }
918 OUT("};\n");
919
920 /*
921 * Tags to elements map.
922 */
923 p = MKID(expr->Identifier);
924 OUT("static asn1_CHOICE_tag2member_t asn1_DEF_%s_tag2el[] = {\n", p);
925 if(tag2el_count) {
926 int i;
927 for(i = 0; i < tag2el_count; i++) {
928 OUT(" { ");
929 _print_tag(arg, expr, &tag2el[i].el_tag);
930 OUT(", ");
931 OUT("%d ", tag2el[i].el_no);
932 OUT("}, /* %s at %d */\n",
933 tag2el[i].from_expr->Identifier,
934 tag2el[i].from_expr->_lineno
935 );
936 }
937 }
938 OUT("};\n");
939
940 OUT("static asn1_CHOICE_specifics_t asn1_DEF_%s_specs = {\n", p);
941 INDENTED(
942 OUT("sizeof(struct %s),\n", p);
943 OUT("offsetof(struct %s, _ber_dec_ctx),\n", p);
944 OUT("offsetof(struct %s, present),\n", p);
945 OUT("sizeof(((struct %s *)0)->present),\n", p);
946 OUT("asn1_DEF_%s_elements,\n", p);
947 OUT("%d,\t/* Elements count */\n", elements);
948 OUT("asn1_DEF_%s_tag2el,\n", p);
949 OUT("%d,\t/* Count of tags in the map */\n", tag2el_count);
950 OUT("%d\t/* Whether extensible */\n", extensible);
951 );
952 OUT("};\n");
953 OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
954 INDENTED(
955 OUT("\"%s\",\n", expr->Identifier);
956 OUT("CHOICE_constraint,\n");
957 OUT("CHOICE_decode_ber,\n");
958 OUT("CHOICE_encode_der,\n");
959 OUT("CHOICE_print,\n");
960 OUT("CHOICE_free,\n");
961 OUT("CHOICE_outmost_tag,\n");
962 OUT("asn1_DEF_%s_tags,\n", p);
963 OUT("sizeof(asn1_DEF_%s_tags)\n", p);
964 OUT("\t/sizeof(asn1_DEF_%s_tags[0]),\n", p);
965 OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
966 OUT("%d,\t/* Whether CONSTRUCTED */\n", 1);
967 OUT("&asn1_DEF_%s_specs\t/* Additional specs */\n", p);
968 );
969 OUT("};\n");
970 OUT("\n");
971
972 REDIR(OT_DEPS);
973 if(!arg->embed)
974 OUT("extern asn1_TYPE_descriptor_t asn1_DEF_%s;\n", p);
975 REDIR(OT_TYPE_DECLS);
976
977 return 0;
978}
979
980int
981asn1c_lang_C_type_REFERENCE(arg_t *arg) {
982 asn1p_ref_t *ref;
983
984 ref = arg->expr->reference;
985 if(ref->components[ref->comp_count-1].name[0] == '&') {
986 asn1p_module_t *mod;
987 asn1p_expr_t *extract;
988 arg_t tmp;
989 int ret;
990
991 extract = asn1f_class_access_ex(arg->asn, arg->mod, arg->expr,
992 ref, &mod);
993 if(extract == NULL)
994 return -1;
995
996 extract = asn1p_expr_clone(extract);
997 if(extract) {
998 if(extract->Identifier)
999 free(extract->Identifier);
1000 extract->Identifier = strdup(arg->expr->Identifier);
1001 if(extract->Identifier == NULL) {
1002 asn1p_expr_free(extract);
1003 return -1;
1004 }
1005 } else {
1006 return -1;
1007 }
1008
1009 tmp = *arg;
1010 tmp.asn = arg->asn;
1011 tmp.mod = mod;
1012 tmp.expr = extract;
1013
1014 ret = arg->default_cb(&tmp);
1015
1016 asn1p_expr_free(extract);
1017
1018 return ret;
1019 }
1020
1021
1022 return asn1c_lang_C_type_SIMPLE_TYPE(arg);
1023}
1024
1025int
1026asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
1027 asn1p_expr_t *expr = arg->expr;
1028 int tags_impl_skip = 0;
1029 char *p;
1030
1031 if(arg->embed) {
1032 REDIR(OT_TYPE_DECLS);
1033
1034 OUT("%s\t", asn1c_type_name(arg, arg->expr,
1035 expr->marker?TNF_RSAFE:TNF_CTYPE));
1036 OUT("%s", expr->marker?"*":" ");
1037 OUT("%s;", MKID(expr->Identifier));
1038 if(expr->marker) OUT("\t/* %s */",
1039 (expr->marker==EM_OPTIONAL)?"OPTIONAL":"DEFAULT");
1040 OUT("\n");
1041 return 0;
1042 }
1043
1044 REDIR(OT_DEPS);
1045
1046 OUT("#include <%s.h>\n", asn1c_type_name(arg, expr, TNF_INCLUDE));
1047
1048 REDIR(OT_TYPE_DECLS);
1049
1050 OUT("typedef %s\t", asn1c_type_name(arg, arg->expr, TNF_CTYPE));
1051 OUT("%s", expr->marker?"*":" ");
1052 OUT("%s_t;\n", MKID(expr->Identifier));
1053 OUT("\n");
1054
1055 REDIR(OT_STAT_DEFS);
1056
1057 p = MKID(expr->Identifier);
1058 OUT("static ber_tlv_tag_t asn1_DEF_%s_tags[] = {\n", p);
1059 INDENTED(
1060 if(expr->tag.tag_class) {
1061 _print_tag(arg, expr, &expr->tag);
1062 if(expr->tag.tag_mode != TM_EXPLICIT)
1063 tags_impl_skip++;
1064 }
1065 if(!expr->tag.tag_class
1066 || (expr->meta_type == AMT_TYPE
1067 && expr->tag.tag_mode == TM_EXPLICIT)) {
1068 struct asn1p_type_tag_s tag;
1069 if(expr->tag.tag_class)
1070 OUT(",\n");
1071 tag.tag_class = TC_UNIVERSAL;
1072 tag.tag_mode = TM_IMPLICIT;
1073 tag.tag_value = expr_type2uclass_value[expr->expr_type];
1074 _print_tag(arg, expr, &tag);
1075 }
1076 OUT("\n");
1077 );
1078 OUT("};\n");
1079
1080 OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
1081 INDENTED(
1082 OUT("\"%s\",\n", expr->Identifier);
1083 OUT("%s_constraint,\n", p);
1084 OUT("%s_decode_ber,\n", p);
1085 OUT("%s_encode_der,\n", p);
1086 OUT("%s_print,\n", p);
1087 OUT("%s_free,\n", p);
1088 OUT("0,\t/* Use generic outmost tag fetcher */\n");
1089 OUT("asn1_DEF_%s_tags,\n", p);
1090 OUT("sizeof(asn1_DEF_%s_tags)\n", p);
1091 OUT("\t/sizeof(asn1_DEF_%s_tags[0]),\n", p);
1092 OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
1093 OUT("-0\t/* Unknown yet */\n");
1094 );
1095 OUT("};\n");
1096 OUT("\n");
1097
1098 /*
1099 * Constraint checking.
1100 */
1101 if(expr->constraints) /* Emit tables with FROM() constraints */
1102 emit_alphabet_tables(arg, expr->constraints, 0);
1103 p = MKID(expr->Identifier);
1104 OUT("int\n");
1105 OUT("%s_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,\n", p);
1106 INDENTED(
1107 OUT("\t\tasn_app_consume_bytes_f *app_errlog, void *app_key) {\n");
1108 OUT("\n");
1109 if(expr->constraints) {
1110
1111 emit_constraint_checking_code(arg);
1112
1113 OUT("/* Check the constraints of the underlying type */\n");
1114 OUT("return asn1_DEF_%s.check_constraints\n",
1115 asn1c_type_name(arg, expr, TNF_SAFE));
1116 OUT("\t(td, sptr, app_errlog, app_key);\n");
1117 } else {
1118 OUT("/* Make the underlying type checker permanent */\n");
1119 OUT("td->check_constraints = asn1_DEF_%s.check_constraints;\n",
1120 asn1c_type_name(arg, expr, TNF_SAFE));
1121 OUT("return td->check_constraints\n");
1122 OUT("\t(td, sptr, app_errlog, app_key);\n");
1123 }
1124 );
1125 OUT("}\n");
1126 OUT("\n");
1127
1128 /*
1129 * Emit suicidal functions.
1130 */
1131
1132 {
1133 /*
1134 * This function replaces certain fields from the definition
1135 * of a type with the corresponding fields from the basic type
1136 * (from which the current type is inherited).
1137 */
1138 char *type_name = asn1c_type_name(arg, expr, TNF_SAFE);
1139 OUT("/*\n");
1140 OUT(" * This type is implemented using %s,\n", type_name);
1141 OUT(" * so adjust the DEF appropriately.\n");
1142 OUT(" */\n");
1143 OUT("static void\n");
1144 OUT("inherit_TYPE_descriptor(asn1_TYPE_descriptor_t *td) {\n");
1145 INDENT(+1);
1146 OUT("td->ber_decoder = asn1_DEF_%s.ber_decoder;\n", type_name);
1147 OUT("td->der_encoder = asn1_DEF_%s.der_encoder;\n", type_name);
1148 OUT("td->free_struct = asn1_DEF_%s.free_struct;\n", type_name);
1149 OUT("td->print_struct = asn1_DEF_%s.print_struct;\n", type_name);
1150 OUT("td->last_tag_form = asn1_DEF_%s.last_tag_form;\n", type_name);
1151 OUT("td->specifics = asn1_DEF_%s.specifics;\n", type_name);
1152 INDENT(-1);
1153 OUT("}\n");
1154 OUT("\n");
1155 }
1156
1157 p = MKID(expr->Identifier);
1158 OUT("ber_dec_rval_t\n");
1159 OUT("%s_decode_ber(asn1_TYPE_descriptor_t *td,\n", p);
1160 INDENTED(
1161 OUT("\tvoid **structure, void *bufptr, size_t size, int tag_mode) {\n");
1162 OUT("inherit_TYPE_descriptor(td);\n");
1163 OUT("return td->ber_decoder(td, structure,\n");
1164 OUT("\tbufptr, size, tag_mode);\n");
1165 );
1166 OUT("}\n");
1167 OUT("\n");
1168
1169 p = MKID(expr->Identifier);
1170 OUT("der_enc_rval_t\n");
1171 OUT("%s_encode_der(asn1_TYPE_descriptor_t *td,\n", p);
1172 INDENTED(
1173 OUT("\tvoid *structure, int tag_mode, ber_tlv_tag_t tag,\n");
1174 OUT("\tasn_app_consume_bytes_f *cb, void *app_key) {\n");
1175 OUT("inherit_TYPE_descriptor(td);\n");
1176 OUT("return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);\n");
1177 );
1178 OUT("}\n");
1179 OUT("\n");
1180
1181 p = MKID(expr->Identifier);
1182 OUT("int\n");
1183 OUT("%s_print(asn1_TYPE_descriptor_t *td, const void *struct_ptr,\n", p);
1184 INDENTED(
1185 OUT("\tint ilevel, asn_app_consume_bytes_f *cb, void *app_key) {\n");
1186 OUT("inherit_TYPE_descriptor(td);\n");
1187 OUT("return td->print_struct(td, struct_ptr, ilevel, cb, app_key);\n");
1188 );
1189 OUT("}\n");
1190 OUT("\n");
1191
1192 p = MKID(expr->Identifier);
1193 OUT("void\n");
1194 OUT("%s_free(asn1_TYPE_descriptor_t *td,\n", p);
1195 INDENTED(
1196 OUT("\tvoid *struct_ptr, int contents_only) {\n");
1197 OUT("inherit_TYPE_descriptor(td);\n");
1198 OUT("td->free_struct(td, struct_ptr, contents_only);\n");
1199 );
1200 OUT("}\n");
1201 OUT("\n");
1202
1203 REDIR(OT_FUNC_DECLS);
1204
1205 p = MKID(expr->Identifier);
1206 OUT("extern asn1_TYPE_descriptor_t asn1_DEF_%s;\n", p);
1207 OUT("asn_constr_check_f %s_constraint;\n", p);
1208 OUT("ber_type_decoder_f %s_decode_ber;\n", p);
1209 OUT("der_type_encoder_f %s_encode_der;\n", p);
1210 OUT("asn_struct_print_f %s_print;\n", p);
1211 OUT("asn_struct_free_f %s_free;\n", p);
1212
1213 return 0;
1214}
1215
1216int
1217asn1c_lang_C_type_EXTENSIBLE(arg_t *arg) {
1218
1219 OUT("/*\n");
1220 OUT(" * This type is extensible,\n");
1221 OUT(" * possible extensions are below.\n");
1222 OUT(" */\n");
1223
1224 return 0;
1225}
1226
1227static int
1228_print_tag(arg_t *arg, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag_p) {
1229 struct asn1p_type_tag_s tag;
1230
1231 if(tag_p) {
1232 tag = *tag_p;
1233 } else {
1234 if(asn1f_fetch_tag(arg->asn, arg->mod, expr, &tag)) {
1235 OUT("-1 /* Ambiguous tag (CHOICE?) */");
1236 return 0;
1237 }
1238 }
1239
1240 OUT("(");
1241 switch(tag.tag_class) {
1242 case TC_UNIVERSAL: OUT("ASN_TAG_CLASS_UNIVERSAL"); break;
1243 case TC_APPLICATION: OUT("ASN_TAG_CLASS_APPLICATION"); break;
1244 case TC_CONTEXT_SPECIFIC: OUT("ASN_TAG_CLASS_CONTEXT"); break;
1245 case TC_PRIVATE: OUT("ASN_TAG_CLASS_PRIVATE"); break;
1246 case TC_NOCLASS:
1247 break;
1248 }
1249 OUT(" | (%lld << 2))", tag.tag_value);
1250
1251 return 0;
1252}
1253
1254/*
1255 * For constructed types, number of external tags may be greater than
1256 * number of elements in the type because of CHOICE type.
1257 * T ::= SET { -- Three possible tags:
1258 * a INTEGER, -- One tag is here...
1259 * b Choice1 -- ... and two more tags are there.
1260 * }
1261 * Choice1 ::= CHOICE {
1262 * s1 IA5String,
1263 * s2 ObjectDescriptor
1264 * }
1265 */
1266static int
1267_fill_tag2el_map(arg_t *arg, tag2el_t **tag2el, int *count, int el_no) {
1268 asn1p_expr_t *expr = arg->expr;
1269 arg_t tmparg = *arg;
1270 asn1p_expr_t *v;
1271 int element = 0;
1272
1273 TQ_FOR(v, &(expr->members), next) {
1274 if(v->expr_type == A1TC_EXTENSIBLE)
1275 continue;
1276
1277 tmparg.expr = v;
1278
1279 if(_add_tag2el_member(&tmparg, tag2el, count,
1280 (el_no==-1)?element:el_no)) {
1281 return -1;
1282 }
1283
1284 element++;
1285 }
1286
1287 return 0;
1288}
1289
1290static int
1291_add_tag2el_member(arg_t *arg, tag2el_t **tag2el, int *count, int el_no) {
1292 struct asn1p_type_tag_s tag;
1293 int ret;
1294
1295 assert(el_no >= 0);
1296
1297 ret = asn1f_fetch_tag(arg->asn, arg->mod, arg->expr, &tag);
1298 if(ret == 0) {
1299 void *p;
1300 p = realloc(*tag2el, sizeof(tag2el_t) * ((*count) + 1));
1301 if(p) *tag2el = p;
1302 else return -1;
1303
1304 DEBUG("Found tag for %s: %ld",
1305 arg->expr->Identifier,
1306 (long)tag.tag_value);
1307
1308 (*tag2el)[*count].el_tag = tag;
1309 (*tag2el)[*count].el_no = el_no;
1310 (*tag2el)[*count].from_expr = arg->expr;
1311 (*count)++;
1312 return 0;
1313 }
1314
1315 DEBUG("Searching tag in complex expression %s:%x at line %d",
1316 arg->expr->Identifier,
1317 arg->expr->expr_type,
1318 arg->expr->_lineno);
1319
1320 /*
1321 * Iterate over members of CHOICE type.
1322 */
1323 if(arg->expr->expr_type == ASN_CONSTR_CHOICE) {
1324 return _fill_tag2el_map(arg, tag2el, count, el_no);
1325 }
1326
1327 if(arg->expr->expr_type == A1TC_REFERENCE) {
1328 arg_t tmp = *arg;
1329 asn1p_expr_t *expr;
1330 expr = asn1f_lookup_symbol_ex(tmp.asn, &tmp.mod, tmp.expr,
1331 arg->expr->reference);
1332 if(expr) {
1333 tmp.expr = expr;
1334 return _add_tag2el_member(&tmp, tag2el, count, el_no);
1335 } else {
1336 FATAL("Cannot dereference %s at line %d",
1337 arg->expr->Identifier,
1338 arg->expr->_lineno);
1339 return -1;
1340 }
1341 }
1342
1343 DEBUG("No tag for %s at line %d",
1344 arg->expr->Identifier,
1345 arg->expr->_lineno);
1346
1347 return -1;
1348}
1349
1350static int
1351emit_constraint_checking_code(arg_t *arg) {
1352 asn1p_expr_t *expr = arg->expr;
1353 asn1p_expr_type_e etype;
1354 int size_present, value_present;
1355
1356 if(expr->constraints == NULL)
1357 return 0; /* No constraints defined */
1358
1359 etype = _find_terminal_type(arg);
1360
1361 size_present = check_constraint_type_presence(expr->constraints,
1362 ACT_CT_SIZE);
1363 value_present = check_constraint_type_presence(expr->constraints,
1364 ACT_EL_VALUE);
1365
1366 if(size_present || value_present) {
Lev Walkine3e41572004-06-03 04:35:44 +00001367 OUT("const %s_t *st = sptr;\n", MKID(arg->expr->Identifier));
Lev Walkinf15320b2004-06-03 03:38:44 +00001368 if(size_present) {
1369 OUT("size_t size;\n");
1370 OUT("size_t min_size __attribute__ ((unused)) = %ld;\n",
1371 compute_min_size(arg));
1372 OUT("size_t max_size __attribute__ ((unused)) = %ld;\n",
1373 compute_max_size(arg));
1374 }
1375 if(value_present)
1376 switch(etype) {
1377 case ASN_BASIC_INTEGER:
1378 case ASN_BASIC_ENUMERATED:
1379 OUT("long value;\n");
1380 break;
1381 case ASN_BASIC_BOOLEAN:
1382 OUT("int value;\n");
1383 break;
1384 default:
1385 break;
1386 }
1387 OUT("\n");
1388 }
1389
1390 OUT("if(!sptr) {\n");
1391 INDENT(+1);
1392 OUT("_ASN_ERRLOG(\"%%s: value not given\", td->name);\n");
1393 OUT("return -1;\n");
1394 INDENT(-1);
1395 OUT("}\n");
1396 OUT("\n");
1397
1398 if(size_present)
1399 emit_size_determination_code(arg);
1400 if(value_present)
1401 emit_value_determination_code(arg);
1402
1403 OUT("\n");
1404 OUT("if(\n");
1405 emit_single_constraint_check(arg, expr->constraints, 0);
1406 OUT(") {\n");
1407 INDENTED(OUT("/* Constraint check succeeded */\n"));
1408 OUT("} else {\n");
1409 INDENT(+1);
1410 OUT("_ASN_ERRLOG(\"%%s: constraint failed\", td->name);\n");
1411 OUT("return -1;\n");
1412 INDENT(-1);
1413 OUT("}\n");
1414
1415 return 0;
1416}
1417
1418static int
1419emit_single_constraint_check(arg_t *arg, asn1p_constraint_t *ct, int mode) {
1420 char *s_v;
1421 int el;
1422
1423 assert(arg && ct);
1424
1425 switch(ct->type) {
1426 case ACT_INVALID:
1427 assert(ct->type != ACT_INVALID);
1428 OUT("-1 /* Invalid constraint at line %d */\n", ct->_lineno);
1429 break;
1430 case ACT_EL_VALUE:
1431 OUT("(");
1432 if(mode == ACT_CT_SIZE) s_v = "size";
1433 else s_v = "value";
1434 OUT("%s", s_v);
1435 if(ct->value->type != ATV_TRUE)
1436 OUT(" == ");
1437 switch(ct->value->type) {
1438 case ATV_INTEGER: OUT("%lld",
1439 (long long)ct->value->value.v_integer); break;
1440 case ATV_MIN: OUT("min_%s", s_v); break;
1441 case ATV_MAX: OUT("max_%s", s_v); break;
1442 case ATV_FALSE: OUT("0"); break;
1443 case ATV_TRUE: break;
1444 default:
1445 break;
1446 }
1447 OUT(")\n");
1448 break;
1449 case ACT_EL_RANGE:
1450 case ACT_EL_LLRANGE:
1451 case ACT_EL_RLRANGE:
1452 case ACT_EL_ULRANGE:
1453 if(mode == ACT_CT_SIZE) {
1454 s_v = "size";
1455 } else {
1456 s_v = "value";
1457 }
1458 OUT("((%s", s_v);
1459 switch(ct->type) {
1460 case ACT_EL_RANGE:
1461 case ACT_EL_RLRANGE:
1462 OUT(" >= "); break;
1463 case ACT_EL_LLRANGE:
1464 case ACT_EL_ULRANGE:
1465 OUT(" > "); break;
1466 default: break;
1467 }
1468 switch(ct->range_start->type) {
1469 case ATV_INTEGER: OUT("%lld",
1470 (long long)ct->range_start->value.v_integer); break;
1471 case ATV_MIN: OUT("min_%s", s_v); break;
1472 case ATV_MAX: OUT("max_%s", s_v); break;
1473 case ATV_FALSE: OUT("0"); break;
1474 case ATV_TRUE: break;
1475 default:
1476 break;
1477 }
1478 OUT(") && (%s", s_v);
1479 switch(ct->type) {
1480 case ACT_EL_RANGE:
1481 case ACT_EL_LLRANGE:
1482 OUT(" <= "); break;
1483 case ACT_EL_RLRANGE:
1484 case ACT_EL_ULRANGE:
1485 OUT(" < "); break;
1486 default: break;
1487 }
1488 switch(ct->range_stop->type) {
1489 case ATV_INTEGER: OUT("%lld",
1490 (long long)ct->range_stop->value.v_integer); break;
1491 case ATV_MIN: OUT("min_%s", s_v); break;
1492 case ATV_MAX: OUT("max_%s", s_v); break;
1493 case ATV_FALSE: OUT("0"); break;
1494 case ATV_TRUE: break;
1495 default:
1496 break;
1497 }
1498 OUT("))\n");
1499 break;
1500 case ACT_EL_EXT:
1501 OUT("0 /* Extensible (...), but not defined herein */\n");
1502 break;
1503 case ACT_CT_SIZE:
1504 if(mode) {
1505 OUT("0 /* Invalid constraint at line %d */\n",
1506 ct->_lineno);
1507 return -1;
1508 }
1509 assert(ct->el_count == 1);
1510 return emit_single_constraint_check(arg,
1511 ct->elements[0], ACT_CT_SIZE);
1512 case ACT_CT_FROM:
1513 if(mode) {
1514 OUT("0 /* Invalid constraint at line %d */\n",
1515 ct->_lineno);
1516 return -1;
1517 }
1518 OUT("check_alphabet_%x(sptr)\n", ct);
1519 break;
1520 case ACT_CT_WCOMP:
1521 case ACT_CT_WCOMPS:
1522 OUT("%d /* Unsupported constraint at line %d */\n",
1523 ct->type, ct->_lineno);
1524 return -1;
1525 break;
1526 case ACT_CA_SET:
1527 OUT("(\n");
1528 INDENT(+1);
1529 for(el = 0; el < ct->el_count; el++) {
1530 if(el) OUT("&& ");
1531 emit_single_constraint_check(arg,
1532 ct->elements[el], mode);
1533 }
1534 INDENT(-1);
1535 OUT(")\n");
1536 break;
1537 case ACT_CA_CSV:
1538 OUT("(\n");
1539 INDENT(+1);
1540 for(el = 0; el < ct->el_count; el++) {
1541 if(el) OUT("|| ");
1542 emit_single_constraint_check(arg,
1543 ct->elements[el], mode);
1544 }
1545 INDENT(-1);
1546 OUT(")\n");
1547 break;
1548 case ACT_CA_UNI:
1549 OUT("(\n");
1550 INDENT(+1);
1551 for(el = 0; el < ct->el_count; el++) {
1552 if(el) OUT("|| ");
1553 emit_single_constraint_check(arg,
1554 ct->elements[el], mode);
1555 }
1556 INDENT(-1);
1557 OUT(")\n");
1558 break;
1559 case ACT_CA_INT:
1560 OUT("(\n");
1561 INDENT(+1);
1562 for(el = 0; el < ct->el_count; el++) {
1563 if(el) OUT("&& ");
1564 emit_single_constraint_check(arg,
1565 ct->elements[el], mode);
1566 }
1567 INDENT(-1);
1568 OUT(")\n");
1569 break;
1570 case ACT_CA_CRC:
1571 WARNING("Unsupported component relation constraint at line %d",
1572 ct->_lineno);
1573 OUT("%d /* Unsupported component relation constraint "
1574 "at line %d */\n",
1575 ct->type, ct->_lineno);
1576 return -1;
1577 case ACT_CA_EXC:
1578 WARNING("Unsupported EXCEPT constraint at line %d",
1579 ct->_lineno);
1580 OUT("%d /* Unsupported EXCEPT constraint at line %d */\n",
1581 ct->type, ct->_lineno);
1582 return -1;
1583 }
1584
1585 return 0;
1586}
1587
1588static int
1589check_constraint_type_presence(asn1p_constraint_t *ct, enum asn1p_constraint_type_e type) {
1590 int el;
1591
1592 if(ct == NULL) return 0;
1593
1594 if(ct->type == type) return 1;
1595
1596 if(type == ACT_EL_VALUE) {
1597 if(ct->type >= ACT_CT_SIZE
1598 && ct->type <= ACT_CT_WCOMPS)
1599 /* Values defined further
1600 * are not really value's values */
1601 return 0;
1602 if(ct->type > ACT_EL_VALUE && ct->type < ACT_CT_SIZE)
1603 return 1; /* Also values */
1604 }
1605
1606 for(el = 0; el < ct->el_count; el++) {
1607 if(check_constraint_type_presence(ct->elements[el], type))
1608 return 1;
1609 }
1610
1611 return 0;
1612}
1613
1614static int
1615emit_alphabet_tables(arg_t *arg, asn1p_constraint_t *ct, int *table) {
1616 int ch = 0;
1617 int ch_start = 0;
1618 int ch_stop = 0;
1619 int el = 0;
1620
1621 assert(arg && ct);
1622
1623 switch(ct->type) {
1624 case ACT_INVALID:
1625 break;
1626 case ACT_EL_VALUE:
1627 if(!table) break;
1628
1629 switch(ct->value->type) {
1630 case ATV_INTEGER:
1631 if(ct->value->value.v_integer < 0
1632 || ct->value->value.v_integer > 255) {
1633 OUT("\n");
1634 OUT("#error Value %lld out of range "
1635 "for alphabet character at line %d\n",
1636 (long long)ct->value->value.v_integer,
1637 ct->_lineno);
1638 break;
1639 } else {
1640 ch = ct->value->value.v_integer;
1641 table[ch] = 1;
1642 }
1643 break;
1644 case ATV_STRING:
1645 for(ch = 0; ch < ct->value->value.string.size; ch++)
1646 table[ct->value->value.string.buf[ch]] = 1;
1647 break;
1648 default:
1649 OUT("\n");
1650 WARNING("Invalid alphabet character specification "
1651 "at line %d", ct->_lineno);
1652 OUT("#error Invalid alphabet character specification "
1653 "at line %d\n", ct->_lineno);
1654 break;
1655 }
1656 break;
1657 case ACT_EL_RANGE:
1658 case ACT_EL_LLRANGE:
1659 case ACT_EL_RLRANGE:
1660 case ACT_EL_ULRANGE:
1661 if(!table) break;
1662
1663 ch_start = 0;
1664 ch_stop = 255;
1665
1666 switch(ct->range_start->type) {
1667 case ATV_INTEGER:
1668 ch_start = ct->range_start->value.v_integer; break;
1669 case ATV_MIN: ch_start = 0; break;
1670 case ATV_MAX: ch_start = 255; break;
1671 case ATV_STRING:
1672 if(ct->range_start->value.string.size == 1) {
1673 ch_start = ct->range_start->value.string.buf[0];
1674 break;
1675 }
1676 /* Fall through */
1677 default:
1678 OUT("\n");
1679 FATAL("Invalid alphabet range constraint "
1680 "at line %d\n", ct->_lineno);
1681 OUT("#error Invalid alphabet range constraint "
1682 "at line %d\n", ct->_lineno);
1683 return -1;
1684 }
1685
1686 switch(ct->range_stop->type) {
1687 case ATV_INTEGER:
1688 ch_stop = ct->range_stop->value.v_integer; break;
1689 case ATV_MIN: ch_stop = 0; break;
1690 case ATV_MAX: ch_stop = 255; break;
1691 case ATV_STRING:
1692 if(ct->range_stop->value.string.size == 1) {
1693 ch_stop = ct->range_stop->value.string.buf[0];
1694 break;
1695 }
1696 /* Fall through */
1697 default:
1698 OUT("\n");
1699 FATAL("Invalid alphabet range constraint "
1700 "at line %d\n", ct->_lineno);
1701 OUT("#error Invalid alphabet range constraint "
1702 "at line %d\n", ct->_lineno);
1703 break;
1704 }
1705
1706 switch(ct->type) {
1707 case ACT_EL_RANGE: break;
1708 case ACT_EL_RLRANGE: ch_stop--; break;
1709 case ACT_EL_LLRANGE: ch_start++; break;
1710 case ACT_EL_ULRANGE: ch_start++; ch_stop--; break;
1711 default: break;
1712 }
1713
1714 if(ch_start > ch_stop) {
1715 WARNING("Empty character range "
1716 "alphabet constraint at line %d", ct->_lineno);
1717 OUT("#warning Empty character range "
1718 "alphabet constraint at line %d\n", ct->_lineno);
1719 break;
1720 }
1721
1722 for(ch = ch_start; ch <= ch_stop; ch++) {
1723 if(ch < 0 || ch > 255) continue;
1724 table[ch] = 1;
1725 }
1726
1727 break;
1728 case ACT_EL_EXT:
1729 break;
1730 case ACT_CT_SIZE:
1731 break;
1732 case ACT_CT_FROM:
1733 if(table) {
1734 OUT("#error Nested FROM in subtype constraints\n");
1735 return -1;
1736 } else {
1737 table = alloca(256 * sizeof(table[0]));
1738 memset(table, 0, 256 * sizeof(table[0]));
1739
1740 for(el = 0; el < ct->el_count; el++) {
1741 emit_alphabet_tables(arg, ct->elements[el],
1742 table);
1743 }
1744 OUT("static int alphabet_table_%x[256] = {\n", ct);
1745 for(ch = 0; ch < 256; ch++) {
1746 OUT("%d,", table[ch]?1:0);
1747 if(!((ch+1) % 16)) {
1748 if(ch) {
1749 int c;
1750 OUT("\t/* ");
1751 for(c = ch - 16; c < ch; c++) {
1752 if(table[c]) {
1753 if(c > 0x20
1754 && c < 0x80)
1755 OUT("%c", c);
1756 else
1757 OUT(".", c);
1758 } else {
1759 OUT(" ");
1760 }
1761 }
1762 OUT(" */");
1763 }
1764 OUT("\n");
1765 }
1766 }
1767 OUT("};\n");
Lev Walkinf9127e32004-06-03 05:18:55 +00001768 OUT("static int check_alphabet_%x(const void *sptr) {\n", ct);
Lev Walkinf15320b2004-06-03 03:38:44 +00001769 INDENT(+1);
1770 OUT("int *table = alphabet_table_%x;\n", ct);
1771 emit_alphabet_check_cycle(arg);
1772 OUT("return 1;\n");
1773 INDENT(-1);
1774 OUT("};\n");
1775 }
1776 break;
1777 case ACT_CT_WCOMP:
1778 case ACT_CT_WCOMPS:
1779 break;
1780 case ACT_CA_CRC:
1781 break;
1782 case ACT_CA_SET:
1783 case ACT_CA_CSV:
1784 case ACT_CA_UNI:
1785 for(el = 0; el < ct->el_count; el++)
1786 emit_alphabet_tables(arg, ct->elements[el], table);
1787 break;
1788 case ACT_CA_INT:
1789 if(table) {
1790 int table2[256];
1791
1792 assert(ct->el_count >= 1);
1793 emit_alphabet_tables(arg, ct->elements[0], table);
1794 for(el = 1; el < ct->el_count; el++) {
1795 memset(table2, 0, sizeof(table2));
1796 emit_alphabet_tables(arg,
1797 ct->elements[el], table2);
1798 /* Intersection */
1799 for(ch = 0; ch < 256; ch++) {
1800 if(table2[ch] == 0)
1801 table[ch] = 0;
1802 }
1803 }
1804 } else {
1805 for(el = 0; el < ct->el_count; el++)
1806 emit_alphabet_tables(arg, ct->elements[el], 0);
1807 }
1808
1809 break;
1810 case ACT_CA_EXC:
1811 OUT("EXC\n");
1812 if(table) {
1813 int table2[256];
1814
1815 assert(ct->el_count >= 1);
1816 emit_alphabet_tables(arg, ct->elements[0], table);
1817 for(el = 1; el < ct->el_count; el++) {
1818 memset(table2, 0, sizeof(table2));
1819 emit_alphabet_tables(arg,
1820 ct->elements[el], table2);
1821 /* Exclusion */
1822 for(ch = 0; ch < 256; ch++) {
1823 if(table2[ch])
1824 table[ch] = 0;
1825 }
1826 }
1827 } else {
1828 for(el = 0; el < ct->el_count; el++)
1829 emit_alphabet_tables(arg, ct->elements[el], 0);
1830 }
1831 break;
1832 }
1833
1834 return 0;
1835}
1836
1837static int
1838emit_alphabet_check_cycle(arg_t *arg) {
1839 asn1p_expr_type_e etype;
1840
1841 etype = _find_terminal_type(arg);
1842 if(!(etype & ASN_STRING_MASK)
1843 && !(etype == ASN_BASIC_OCTET_STRING)) {
1844 OUT("#error Cannot apply FROM constraint to ASN.1 type %s\n",
1845 ASN_EXPR_TYPE2STR(etype));
1846 return -1;
1847 }
1848
1849 OUT("/* The underlying type is %s */\n",
1850 ASN_EXPR_TYPE2STR(etype));
Lev Walkine3e41572004-06-03 04:35:44 +00001851 OUT("const %s_t *st = sptr;\n", MKID(arg->expr->Identifier));
Lev Walkinf15320b2004-06-03 03:38:44 +00001852
1853 switch(etype) {
1854 case ASN_STRING_UTF8String:
1855 OUT("uint8_t *ch = st->buf;\n");
1856 OUT("uint8_t *end = ch + st->size;\n");
1857 OUT("\n");
1858 OUT("for(; ch < end; ch++) {\n");
1859 INDENT(+1);
1860 OUT("if(*ch >= 0x80 || !table[*ch]) return 0;\n");
1861 INDENT(-1);
1862 OUT("}\n");
1863 break;
1864 case ASN_STRING_UniversalString:
1865 OUT("uint32_t *ch = st->buf;\n");
1866 OUT("uint32_t *end = ch + st->size;\n");
1867 OUT("\n");
1868 OUT("for(; ch < end; ch++) {\n");
1869 INDENT(+1);
1870 OUT("uint32_t wc = (((uint8_t *)ch)[0] << 24)\n");
1871 OUT("\t\t| (((uint8_t *)ch)[1] << 16)\n");
1872 OUT("\t\t| (((uint8_t *)ch)[2] << 8)\n");
1873 OUT("\t\t| ((uint8_t *)ch)[3]\n");
1874 OUT("if(wc > 255 || !table[wc]) return 0;\n");
1875 INDENT(-1);
1876 OUT("}\n");
1877 OUT("if(ch != end) return 0; /* (size%4)! */\n");
1878 break;
1879 case ASN_STRING_BMPString:
1880 OUT("uint16_t *ch = st->buf;\n");
1881 OUT("uint16_t *end = ch + st->size;\n");
1882 OUT("\n");
1883 OUT("for(; ch < end; ch++) {\n");
1884 INDENT(+1);
1885 OUT("uint16_t wc = (((uint8_t *)ch)[0] << 8)\n");
1886 OUT("\t\t| ((uint8_t *)ch)[1];\n");
1887 OUT("if(wc > 255 || !table[wc]) return 0;\n");
1888 INDENT(-1);
1889 OUT("}\n");
1890 OUT("if(ch != end) return 0; /* (size%2)! */\n");
1891 break;
1892 case ASN_BASIC_OCTET_STRING:
1893 default:
1894 OUT("uint8_t *ch = st->buf;\n");
1895 OUT("uint8_t *end = ch + st->size;\n");
1896 OUT("\n");
1897 OUT("for(; ch < end; ch++) {\n");
1898 INDENT(+1);
1899 OUT("if(!table[*ch]) return 0;\n");
1900 INDENT(-1);
1901 OUT("}\n");
1902 break;
1903 }
1904
1905 return 0;
1906}
1907
1908static int
1909emit_size_determination_code(arg_t *arg) {
1910 asn1p_expr_type_e etype = _find_terminal_type(arg);
1911
1912 switch(etype) {
1913 case ASN_BASIC_BIT_STRING:
1914 OUT("if(st->size > 0) {\n");
1915 OUT("\t/* Size in bits */\n");
1916 OUT("\tsize = (st->size - 1) - (st->buf[0] & 0x7);\n");
1917 OUT("} else {\n");
1918 OUT("\tsize = 0;\n");
1919 OUT("}\n");
1920 break;
1921 case ASN_STRING_UniversalString:
1922 OUT("size = st->size >> 2;\t/* 4 byte per character */\n");
1923 break;
1924 case ASN_STRING_BMPString:
1925 OUT("size = st->size >> 1;\t/* 2 byte per character */\n");
1926 break;
1927 case ASN_STRING_UTF8String:
1928 OUT("size = UTF8String_length(st, td->name, app_errlog, app_key);\n");
1929 OUT("if(size == (size_t)-1) return -1;\n");
1930 break;
1931 default:
1932 if((etype & ASN_STRING_MASK)
1933 || etype == ASN_BASIC_OCTET_STRING) {
1934 OUT("size = st->size;\n");
1935 break;
1936 } else {
1937 WARNING("Size operation is not defined for %s",
1938 ASN_EXPR_TYPE2STR(etype));
1939 OUT("#warning Size operation not defined!\n");
1940 OUT("size = st->size;\n");
1941 }
1942 return -1;
1943 }
1944
1945 return 0;
1946}
1947
1948static int
1949emit_value_determination_code(arg_t *arg) {
1950 asn1p_expr_type_e etype = _find_terminal_type(arg);
1951
1952 switch(etype) {
1953 case ASN_BASIC_INTEGER:
1954 case ASN_BASIC_ENUMERATED:
1955 OUT("if(asn1_INTEGER2long(st, &value)) {\n");
1956 INDENT(+1);
1957 OUT("_ASN_ERRLOG(\"%%s: value too large\", td->name);\n");
1958 OUT("return -1;\n");
1959 INDENT(-1);
1960 OUT("}\n");
1961 break;
1962 case ASN_BASIC_BOOLEAN:
1963 OUT("value = st->value;\n");
1964 break;
1965 default:
1966 WARNING("Value cannot be determined "
1967 "for constraint check for %s at line %d\n",
1968 arg->expr->Identifier, arg->expr->_lineno);
1969 OUT("#error Value cannot be determined for %s at %d\n",
1970 arg->expr->Identifier, arg->expr->_lineno);
1971 break;
1972 }
1973
1974 return 0;
1975}
1976
1977static long compute_min_size(arg_t *arg) { return compute_xxx_size(arg, 0); }
1978static long compute_max_size(arg_t *arg) { return compute_xxx_size(arg, 1); }
1979
1980static long compute_xxx_size(arg_t *arg, int _max) {
1981 asn1p_expr_type_e etype;
1982 long basic_max = 0x7fffffff;
1983 long basic_min = 0x80000000;
1984 long svalue = 0;
1985
1986 etype = _find_terminal_type(arg);
1987 switch(etype) {
1988 case ASN_BASIC_BIT_STRING:
1989 svalue = _max?basic_max/8:0;
1990 break;
1991 case ASN_STRING_UTF8String:
1992 svalue = _max?basic_max/6:0;
1993 break;
1994 case ASN_STRING_UniversalString:
1995 svalue = _max?basic_max/4:0;
1996 break;
1997 case ASN_STRING_BMPString:
1998 svalue = _max?basic_max/2:0;
1999 break;
2000 case ASN_BASIC_OCTET_STRING:
2001 svalue = _max?basic_max:0;
2002 break;
2003 default:
2004 if((etype & ASN_STRING_MASK)) {
2005 svalue = _max?basic_max:0;
2006 break;
2007 }
2008 svalue = _max?basic_max:basic_min;
2009 break;
2010 }
2011
2012 return svalue;
2013}
2014
2015static asn1p_expr_type_e
2016_find_terminal_type(arg_t *arg) {
2017 asn1p_expr_t *expr;
2018 expr = asn1f_find_terminal_type_ex(arg->asn, arg->mod, arg->expr, NULL);
2019 assert(expr);
2020 return expr->expr_type;
2021}