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