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