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