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