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