blob: ac13873372336c7b5e191a6e35915c440b4ec718 [file] [log] [blame]
vlmfa67ddc2004-06-03 03:38:44 +00001/*
2 * Don't look into this file. First, because it's a mess, and second, because
3 * it's a brain of the compiler, and you don't wanna mess with brains do you? ;)
4 */
5#include "asn1c_internal.h"
6#include "asn1c_C.h"
vlm1d036692004-08-19 13:29:46 +00007#include "asn1c_constraint.h"
8#include <asn1fix_export.h> /* Stuff exported by libasn1fix */
vlmfa67ddc2004-06-03 03:38:44 +00009
vlm4e03ce22004-06-06 07:20:17 +000010typedef struct tag2el_s {
11 struct asn1p_type_tag_s el_tag;
12 int el_no;
vlmc8aeab42004-06-14 13:09:45 +000013 int toff_first;
14 int toff_last;
vlm4e03ce22004-06-06 07:20:17 +000015 asn1p_expr_t *from_expr;
16} tag2el_t;
17
18static int _fill_tag2el_map(arg_t *arg, tag2el_t **tag2el, int *count, int el_no);
19static int _add_tag2el_member(arg_t *arg, tag2el_t **tag2el, int *count, int el_no);
20
vlmfa67ddc2004-06-03 03:38:44 +000021static int asn1c_lang_C_type_SEQUENCE_def(arg_t *arg);
22static int asn1c_lang_C_type_SET_def(arg_t *arg);
23static int asn1c_lang_C_type_CHOICE_def(arg_t *arg);
24static int asn1c_lang_C_type_SEx_OF_def(arg_t *arg, int seq_of);
25static int _print_tag(arg_t *arg, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag_p);
vlm79b08d52004-07-01 00:52:50 +000026static int check_if_extensible(asn1p_expr_t *expr);
vlm6e73a042004-08-11 07:17:22 +000027static int emit_tags_vector(arg_t *arg, asn1p_expr_t *expr, int *tags_impl_skip, int choice_mode);
vlm4e03ce22004-06-06 07:20:17 +000028static int emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count);
vlmfa67ddc2004-06-03 03:38:44 +000029
vlmfa67ddc2004-06-03 03:38:44 +000030#define C99_MODE (arg->flags & A1C_NO_C99)
31#define UNNAMED_UNIONS (arg->flags & A1C_UNNAMED_UNIONS)
32
33#define PCTX_DEF INDENTED( \
34 OUT("\n"); \
35 OUT("/* Context for parsing across buffer boundaries */\n"); \
36 OUT("ber_dec_ctx_t _ber_dec_ctx;\n"));
37
vlm33a4ff12004-08-11 05:21:32 +000038#define DEPENDENCIES do { \
39 TQ_FOR(v, &(expr->members), next) { \
40 if((!(v->expr_type & ASN_CONSTR_MASK) \
41 && v->expr_type > ASN_CONSTR_MASK) \
42 || v->meta_type == AMT_TYPEREF) { \
43 GEN_INCLUDE(asn1c_type_name(arg, v, TNF_INCLUDE));\
44 } \
45 } \
46 if(expr->expr_type == ASN_CONSTR_SET_OF) \
47 GEN_INCLUDE("asn_SET_OF"); \
48 if(expr->expr_type == ASN_CONSTR_SEQUENCE_OF) \
49 GEN_INCLUDE("asn_SEQUENCE_OF"); \
50} while(0)
vlmfa67ddc2004-06-03 03:38:44 +000051
52#define MKID(id) asn1c_make_identifier(0, (id), 0)
53
54int
55asn1c_lang_C_type_ENUMERATED(arg_t *arg) {
56 asn1p_expr_t *expr = arg->expr;
57 asn1p_expr_t *v;
58
59 REDIR(OT_DEPS);
60
61 OUT("typedef enum %s {\n", MKID(expr->Identifier));
62 TQ_FOR(v, &(expr->members), next) {
63 switch(v->expr_type) {
64 case A1TC_UNIVERVAL:
65 OUT("\t%s\t= %lld,\n",
66 asn1c_make_identifier(0,
67 expr->Identifier,
68 v->Identifier, 0),
69 v->value->value.v_integer);
70 break;
71 case A1TC_EXTENSIBLE:
72 OUT("\t/*\n");
73 OUT("\t * Enumeration is extensible\n");
74 OUT("\t */\n");
75 break;
76 default:
77 return -1;
78 }
79 }
80 OUT("} %s_e;\n", MKID(expr->Identifier));
81
82 return asn1c_lang_C_type_SIMPLE_TYPE(arg);
83}
84
85
86int
87asn1c_lang_C_type_INTEGER(arg_t *arg) {
88 asn1p_expr_t *expr = arg->expr;
89 asn1p_expr_t *v;
90
91 REDIR(OT_DEPS);
92
93 if(TQ_FIRST(&(expr->members))) {
94 OUT("typedef enum %s {\n", MKID(expr->Identifier));
95 TQ_FOR(v, &(expr->members), next) {
96 switch(v->expr_type) {
97 case A1TC_UNIVERVAL:
98 OUT("\t%s\t= %lld,\n",
99 asn1c_make_identifier(0,
100 expr->Identifier,
101 v->Identifier, 0),
102 v->value->value.v_integer);
103 break;
104 default:
105 return -1;
106 }
107 }
108 OUT("} %s_e;\n", MKID(expr->Identifier));
109 }
110
111 return asn1c_lang_C_type_SIMPLE_TYPE(arg);
112}
113
114int
115asn1c_lang_C_type_SEQUENCE(arg_t *arg) {
116 asn1p_expr_t *expr = arg->expr;
117 asn1p_expr_t *v;
118 int comp_mode = 0; /* {root,ext=1,root,root,...} */
119
120 DEPENDENCIES;
121
122 if(arg->embed) {
123 OUT("struct %s {\n",
124 MKID(expr->Identifier));
125 } else {
126 OUT("typedef struct %s {\n",
127 MKID(expr->Identifier));
128 }
129
130 TQ_FOR(v, &(expr->members), next) {
131 if(v->expr_type == A1TC_EXTENSIBLE) {
132 if(comp_mode < 3) comp_mode++;
133 }
134 if(comp_mode == 1 && !v->marker)
135 v->marker = EM_OPTIONAL;
136 EMBED(v);
137 }
138
139 PCTX_DEF;
140 OUT("} %s%s", expr->marker?"*":"",
141 MKID(expr->Identifier));
142 if(arg->embed) OUT(";\n"); else OUT("_t;\n");
143
144 return asn1c_lang_C_type_SEQUENCE_def(arg);
145}
146
147static int
148asn1c_lang_C_type_SEQUENCE_def(arg_t *arg) {
149 asn1p_expr_t *expr = arg->expr;
150 asn1p_expr_t *v;
151 int elements; /* Number of elements */
152 int tags_impl_skip = 0;
153 int comp_mode = 0; /* {root,ext=1,root,root,...} */
154 int ext_start = -1;
155 int ext_stop = -1;
vlm4e03ce22004-06-06 07:20:17 +0000156 tag2el_t *tag2el = NULL;
157 int tag2el_count = 0;
vlm6e73a042004-08-11 07:17:22 +0000158 int tags_count;
vlmfa67ddc2004-06-03 03:38:44 +0000159 char *p;
160
vlm4e03ce22004-06-06 07:20:17 +0000161 /*
162 * Fetch every inner tag from the tag to elements map.
163 */
164 if(_fill_tag2el_map(arg, &tag2el, &tag2el_count, -1)) {
165 if(tag2el) free(tag2el);
166 return -1;
167 }
168
vlm33a4ff12004-08-11 05:21:32 +0000169 GEN_INCLUDE("constr_SEQUENCE");
170 if(!arg->embed)
171 GEN_DECLARE(expr); /* asn1_DEF_xxx */
vlmfa67ddc2004-06-03 03:38:44 +0000172
vlm33a4ff12004-08-11 05:21:32 +0000173 REDIR(OT_STAT_DEFS);
vlmfa67ddc2004-06-03 03:38:44 +0000174
175 /*
176 * Print out the table according to which the parsing is performed.
177 */
178 p = MKID(expr->Identifier);
179 OUT("static asn1_SEQUENCE_element_t asn1_DEF_%s_elements[] = {\n", p);
180
181 elements = 0;
182 INDENTED(TQ_FOR(v, &(expr->members), next) {
183 if(v->expr_type == A1TC_EXTENSIBLE) {
184 if((++comp_mode) == 1)
185 ext_start = elements - 1;
186 else
187 ext_stop = elements - 1;
188 continue;
189 }
190 OUT("{ ");
191 elements++;
192 OUT("offsetof(struct %s, ", MKID(expr->Identifier));
193 OUT("%s), ", MKID(v->Identifier));
194 if(v->marker) {
195 asn1p_expr_t *tv;
196 int opts = 0;
197 for(tv = v; tv && tv->marker;
198 tv = TQ_NEXT(tv, next), opts++) {
199 if(tv->expr_type == A1TC_EXTENSIBLE)
200 opts--;
201 }
202 OUT("%d,", opts);
203 } else {
204 OUT("0,");
205 }
206 OUT("\n");
207 INDENT(+1);
208 if(C99_MODE) OUT(".tag = ");
209 _print_tag(arg, v, NULL);
210 OUT(",\n");
211 if(C99_MODE) OUT(".tag_mode = ");
212 if(v->tag.tag_class) {
213 if(v->tag.tag_mode == TM_IMPLICIT)
214 OUT("-1,\t/* IMPLICIT tag at current level */\n");
215 else
216 OUT("+1,\t/* EXPLICIT tag at current level */\n");
217 } else {
218 OUT("0,\n");
219 }
220 if(C99_MODE) OUT(".type = ");
221 OUT("(void *)&asn1_DEF_%s,\n",
222 asn1c_type_name(arg, v, TNF_SAFE));
223 if(C99_MODE) OUT(".name = ");
224 OUT("\"%s\"\n", v->Identifier);
225 OUT("},\n");
226 INDENT(-1);
227 });
228 OUT("};\n");
229
vlm4a3f5822004-06-28 21:13:46 +0000230 /*
231 * Print out asn1_DEF_<type>_tags[] vector.
232 */
vlm6e73a042004-08-11 07:17:22 +0000233 tags_count = emit_tags_vector(arg, expr, &tags_impl_skip, 0);
vlmfa67ddc2004-06-03 03:38:44 +0000234
vlm4e03ce22004-06-06 07:20:17 +0000235 /*
236 * Tags to elements map.
237 */
238 emit_tag2member_map(arg, tag2el, tag2el_count);
239
vlm4a3f5822004-06-28 21:13:46 +0000240 p = MKID(expr->Identifier);
vlmfa67ddc2004-06-03 03:38:44 +0000241 OUT("static asn1_SEQUENCE_specifics_t asn1_DEF_%s_specs = {\n", p);
242 INDENTED(
243 OUT("sizeof(struct %s),\n", p);
244 OUT("offsetof(struct %s, _ber_dec_ctx),\n", p);
245 OUT("asn1_DEF_%s_elements,\n", p);
246 OUT("%d,\t/* Elements count */\n", elements);
vlm4e03ce22004-06-06 07:20:17 +0000247 OUT("asn1_DEF_%s_tag2el,\n", p);
248 OUT("%d,\t/* Count of tags in the map */\n", tag2el_count);
vlmfa67ddc2004-06-03 03:38:44 +0000249 OUT("%d,\t/* Start extensions */\n",
250 ext_start);
251 OUT("%d\t/* Stop extensions */\n",
252 (ext_stop<ext_start)?elements+1:ext_stop, ext_stop);
253 );
254 OUT("};\n");
255 OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
256 INDENTED(
257 OUT("\"%s\",\n", expr->Identifier);
258 OUT("SEQUENCE_constraint,\n");
259 OUT("SEQUENCE_decode_ber,\n");
260 OUT("SEQUENCE_encode_der,\n");
261 OUT("SEQUENCE_print,\n");
262 OUT("SEQUENCE_free,\n");
263 OUT("0,\t/* Use generic outmost tag fetcher */\n");
vlm6e73a042004-08-11 07:17:22 +0000264 if(tags_count) {
265 OUT("asn1_DEF_%s_tags,\n", p);
266 OUT("sizeof(asn1_DEF_%s_tags)\n", p);
267 OUT("\t/sizeof(asn1_DEF_%s_tags[0]), /* %d */\n",
268 p, tags_count);
269 } else {
270 OUT("0,\t/* No explicit tags (pointer) */\n");
271 OUT("0,\t/* No explicit tags (count) */\n");
272 }
vlmfa67ddc2004-06-03 03:38:44 +0000273 OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
274 OUT("%d,\t/* Whether CONSTRUCTED */\n", 1);
275 OUT("&asn1_DEF_%s_specs\t/* Additional specs */\n", p);
276 );
277 OUT("};\n");
278 OUT("\n");
279
vlmfa67ddc2004-06-03 03:38:44 +0000280 REDIR(OT_TYPE_DECLS);
281
282 return 0;
283}
284
285int
286asn1c_lang_C_type_SEQUENCE_OF(arg_t *arg) {
287 asn1p_expr_t *expr = arg->expr;
288 asn1p_expr_t *v;
289
290 DEPENDENCIES;
291
292 if(arg->embed) {
293 OUT("struct %s {\n", MKID(expr->Identifier));
294 } else {
295 OUT("typedef struct %s {\n", MKID(expr->Identifier));
296 }
297
298 TQ_FOR(v, &(expr->members), next) {
299 INDENTED(OUT("A_SEQUENCE_OF(%s) list;\n",
300 asn1c_type_name(arg, v, TNF_RSAFE)));
301 }
302
303 PCTX_DEF;
304 OUT("} %s%s", expr->marker?"*":"", MKID(expr->Identifier));
305 if(arg->embed) OUT(";\n"); else OUT("_t;\n");
306
307 /*
308 * SET OF/SEQUENCE OF definition, SEQUENCE OF mode.
309 */
310 return asn1c_lang_C_type_SEx_OF_def(arg, 1);
311}
312
313int
314asn1c_lang_C_type_SET(arg_t *arg) {
315 asn1p_expr_t *expr = arg->expr;
316 asn1p_expr_t *v;
317 long mcount;
318 char *id;
319 int comp_mode = 0; /* {root,ext=1,root,root,...} */
320
321 DEPENDENCIES;
322
323 REDIR(OT_DEPS);
324
325 OUT("\n");
326 OUT("/*\n");
327 OUT(" * Method of determining the components presence\n");
328 OUT(" */\n");
329 mcount = 0;
vlm6e73a042004-08-11 07:17:22 +0000330 OUT("typedef enum %s_PR {\n", MKID(expr->Identifier));
vlmfa67ddc2004-06-03 03:38:44 +0000331 TQ_FOR(v, &(expr->members), next) {
332 if(v->expr_type == A1TC_EXTENSIBLE) continue;
333 INDENTED(
334 id = MKID(expr->Identifier);
335 OUT("%s_PR_", id);
336 id = MKID(v->Identifier);
337 OUT("%s,\t/* Member %s is present */\n",
338 id, id)
339 );
340 mcount++;
341 }
vlm6e73a042004-08-11 07:17:22 +0000342 id = MKID(expr->Identifier);
343 OUT("} %s_PR;\n", id);
vlmfa67ddc2004-06-03 03:38:44 +0000344
345 REDIR(OT_TYPE_DECLS);
346
347 if(arg->embed) {
vlm6e73a042004-08-11 07:17:22 +0000348 OUT("struct %s {\n", id);
vlmfa67ddc2004-06-03 03:38:44 +0000349 } else {
vlm6e73a042004-08-11 07:17:22 +0000350 OUT("typedef struct %s {\n", id);
vlmfa67ddc2004-06-03 03:38:44 +0000351 }
352
353 TQ_FOR(v, &(expr->members), next) {
354 if(v->expr_type == A1TC_EXTENSIBLE) {
355 if(comp_mode < 3) comp_mode++;
356 }
357 if(comp_mode == 1 && !v->marker)
358 v->marker = EM_OPTIONAL;
359 EMBED(v);
360 }
361
362 INDENTED(
363 id = MKID(expr->Identifier);
364 OUT("\n");
365 OUT("/* Presence bitmask: ASN_SET_ISPRESENT(p%s, %s_PR_x) */\n",
366 id, id);
367 OUT("unsigned int _presence_map\n");
368 OUT("\t[((%ld+(8*sizeof(unsigned int))-1)/(8*sizeof(unsigned int)))];\n", mcount);
369 );
370
371 PCTX_DEF;
372 OUT("} %s%s", expr->marker?"*":"", MKID(expr->Identifier));
373 if(arg->embed) OUT(";\n"); else OUT("_t;\n");
374
375 return asn1c_lang_C_type_SET_def(arg);
376}
377
vlmfa67ddc2004-06-03 03:38:44 +0000378static int
379asn1c_lang_C_type_SET_def(arg_t *arg) {
380 asn1p_expr_t *expr = arg->expr;
381 asn1p_expr_t *v;
382 int elements;
383 int tags_impl_skip = 0;
384 int comp_mode = 0; /* {root,ext=1,root,root,...} */
vlmfa67ddc2004-06-03 03:38:44 +0000385 tag2el_t *tag2el = NULL;
386 int tag2el_count = 0;
vlm6e73a042004-08-11 07:17:22 +0000387 int tags_count;
vlmfa67ddc2004-06-03 03:38:44 +0000388 char *p;
389
390 /*
391 * Fetch every inner tag from the tag to elements map.
392 */
393 if(_fill_tag2el_map(arg, &tag2el, &tag2el_count, -1)) {
394 if(tag2el) free(tag2el);
395 return -1;
vlmfa67ddc2004-06-03 03:38:44 +0000396 }
397
vlm33a4ff12004-08-11 05:21:32 +0000398 GEN_INCLUDE("constr_SET");
399 if(!arg->embed)
400 GEN_DECLARE(expr); /* asn1_DEF_xxx */
vlmfa67ddc2004-06-03 03:38:44 +0000401
402 REDIR(OT_STAT_DEFS);
403
vlmfa67ddc2004-06-03 03:38:44 +0000404 /*
405 * Print out the table according to which the parsing is performed.
406 */
407 p = MKID(expr->Identifier);
408 OUT("static asn1_SET_element_t asn1_DEF_%s_elements[] = {\n", p);
409
410 elements = 0;
411 INDENTED(TQ_FOR(v, &(expr->members), next) {
412 if(v->expr_type != A1TC_EXTENSIBLE) {
413 if(comp_mode == 1)
414 v->marker = EM_OPTIONAL;
415 elements++;
416 } else {
417 if(comp_mode < 3) comp_mode++;
418 continue;
419 }
420 OUT("{ ");
421 p = MKID(expr->Identifier);
422 OUT("offsetof(struct %s, ", p);
423 p = MKID(v->Identifier);
424 OUT("%s), ", p);
425 if(v->marker) {
426 OUT("1, /* Optional element */\n");
427 } else {
428 OUT("0,\n");
429 }
430 INDENT(+1);
431 if(C99_MODE) OUT(".tag = ");
432 _print_tag(arg, v, NULL);
433 OUT(",\n");
434 if(C99_MODE) OUT(".tag_mode = ");
435 if(v->tag.tag_class) {
436 if(v->tag.tag_mode == TM_IMPLICIT)
437 OUT("-1,\t/* IMPLICIT tag at current level */\n");
438 else
439 OUT("+1,\t/* EXPLICIT tag at current level */\n");
440 } else {
441 OUT("0,\n");
442 }
443 if(C99_MODE) OUT(".type = ");
444 OUT("(void *)&asn1_DEF_%s,\n",
445 asn1c_type_name(arg, v, TNF_SAFE));
446 if(C99_MODE) OUT(".name = ");
447 OUT("\"%s\"\n", v->Identifier);
448 OUT("},\n");
449 INDENT(-1);
450 });
451 OUT("};\n");
452
vlm4a3f5822004-06-28 21:13:46 +0000453 /*
454 * Print out asn1_DEF_<type>_tags[] vector.
455 */
vlm6e73a042004-08-11 07:17:22 +0000456 tags_count = emit_tags_vector(arg, expr, &tags_impl_skip, 0);
vlmfa67ddc2004-06-03 03:38:44 +0000457
458 /*
459 * Tags to elements map.
460 */
vlm4e03ce22004-06-06 07:20:17 +0000461 emit_tag2member_map(arg, tag2el, tag2el_count);
vlmfa67ddc2004-06-03 03:38:44 +0000462
463 /*
464 * Emit a map of mandatory elements.
465 */
vlm4a3f5822004-06-28 21:13:46 +0000466 p = MKID(expr->Identifier);
vlmfa67ddc2004-06-03 03:38:44 +0000467 OUT("static uint8_t asn1_DEF_%s_mmap", p);
468 OUT("[(%d + (8 * sizeof(unsigned int)) - 1) / 8]", elements);
469 OUT(" = {\n", p);
470 INDENTED(
471 if(elements) {
472 int delimit = 0;
473 int el = 0;
474 TQ_FOR(v, &(expr->members), next) {
475 if(v->expr_type == A1TC_EXTENSIBLE) continue;
476 if(delimit) {
477 OUT(",\n");
478 delimit = 0;
479 } else if(el) {
480 OUT(" | ");
481 }
482 OUT("(%d << %d)", v->marker?0:1, 7 - (el % 8));
483 if(el && (el % 8) == 0)
484 delimit = 1;
485 el++;
486 }
487 } else {
488 OUT("0");
489 }
490 );
491 OUT("\n");
492 OUT("};\n");
493
494 OUT("static asn1_SET_specifics_t asn1_DEF_%s_specs = {\n", p);
495 INDENTED(
496 OUT("sizeof(struct %s),\n", p);
497 OUT("offsetof(struct %s, _ber_dec_ctx),\n", p);
498 OUT("offsetof(struct %s, _presence_map),\n", p);
499 OUT("asn1_DEF_%s_elements,\n", p);
500 OUT("%d,\t/* Elements count */\n", elements);
501 OUT("asn1_DEF_%s_tag2el,\n", p);
502 OUT("%d,\t/* Count of tags in the map */\n", tag2el_count);
vlm79b08d52004-07-01 00:52:50 +0000503 OUT("%d,\t/* Whether extensible */\n",
504 check_if_extensible(expr));
vlmfa67ddc2004-06-03 03:38:44 +0000505 OUT("(unsigned int *)asn1_DEF_%s_mmap\t/* Mandatory elements map */\n", p);
506 );
507 OUT("};\n");
508 OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
509 INDENTED(
510 OUT("\"%s\",\n", expr->Identifier);
511 OUT("SET_constraint,\n");
512 OUT("SET_decode_ber,\n");
513 OUT("SET_encode_der,\n");
514 OUT("SET_print,\n");
515 OUT("SET_free,\n");
516 OUT("0,\t/* Use generic outmost tag fetcher */\n");
vlm6e73a042004-08-11 07:17:22 +0000517 if(tags_count) {
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]), /* %d */\n",
521 p, tags_count);
522 } else {
523 OUT("0,\t/* No explicit tags (pointer) */\n");
524 OUT("0,\t/* No explicit tags (count) */\n");
525 }
vlmfa67ddc2004-06-03 03:38:44 +0000526 OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
527 OUT("%d,\t/* Whether CONSTRUCTED */\n", 1);
528 OUT("&asn1_DEF_%s_specs\t/* Additional specs */\n", p);
529 );
530 OUT("};\n");
531 OUT("\n");
532
vlmfa67ddc2004-06-03 03:38:44 +0000533 REDIR(OT_TYPE_DECLS);
534
535 return 0;
536}
537
538int
539asn1c_lang_C_type_SET_OF(arg_t *arg) {
540 asn1p_expr_t *expr = arg->expr;
541 asn1p_expr_t *v;
542
543 DEPENDENCIES;
544
545 if(arg->embed) {
546 OUT("struct %s {\n", MKID(expr->Identifier));
547 } else {
548 OUT("typedef struct %s {\n",
549 MKID(expr->Identifier));
550 }
551
552 TQ_FOR(v, &(expr->members), next) {
553 INDENTED(OUT("A_SET_OF(%s) list;\n",
554 asn1c_type_name(arg, v, TNF_RSAFE)));
555 }
556
557 PCTX_DEF;
558 OUT("} %s%s", expr->marker?"*":"", MKID(expr->Identifier));
559 if(arg->embed) OUT(";\n"); else OUT("_t;\n");
560
561 /*
562 * SET OF/SEQUENCE OF definition, SET OF mode.
563 */
564 return asn1c_lang_C_type_SEx_OF_def(arg, 0);
565}
566
567static int
568asn1c_lang_C_type_SEx_OF_def(arg_t *arg, int seq_of) {
569 asn1p_expr_t *expr = arg->expr;
570 asn1p_expr_t *v;
571 int tags_impl_skip = 0;
vlm6e73a042004-08-11 07:17:22 +0000572 int tags_count;
vlmfa67ddc2004-06-03 03:38:44 +0000573 char *p;
574
vlm33a4ff12004-08-11 05:21:32 +0000575 /*
576 * Print out the table according to which the parsing is performed.
577 */
vlmfa67ddc2004-06-03 03:38:44 +0000578 if(seq_of) {
vlm33a4ff12004-08-11 05:21:32 +0000579 GEN_INCLUDE("constr_SEQUENCE_OF");
vlmfa67ddc2004-06-03 03:38:44 +0000580 } else {
vlm33a4ff12004-08-11 05:21:32 +0000581 GEN_INCLUDE("constr_SET_OF");
vlmfa67ddc2004-06-03 03:38:44 +0000582 }
vlm33a4ff12004-08-11 05:21:32 +0000583 if(!arg->embed)
584 GEN_DECLARE(expr); /* asn1_DEF_xxx */
vlmfa67ddc2004-06-03 03:38:44 +0000585
586 REDIR(OT_STAT_DEFS);
587
588 /*
589 * Print out the table according to which the parsing is performed.
590 */
591 p = MKID(expr->Identifier);
592 OUT("static asn1_SET_OF_element_t asn1_DEF_%s_elements[] = {\n", p);
593
594 INDENTED(OUT("{ ");
595 v = TQ_FIRST(&(expr->members));
596 INDENT(+1);
597 if(C99_MODE) OUT(".tag = ");
598 _print_tag(arg, v, NULL);
599 OUT(",\n");
600 if(C99_MODE) OUT(".type = ");
601 OUT("(void *)&asn1_DEF_%s",
602 asn1c_type_name(arg, v, TNF_SAFE));
603 OUT(" ");
604 OUT("},\n");
605 INDENT(-1);
606 );
607 OUT("};\n");
608
vlm4a3f5822004-06-28 21:13:46 +0000609 /*
610 * Print out asn1_DEF_<type>_tags[] vector.
611 */
vlm6e73a042004-08-11 07:17:22 +0000612 tags_count = emit_tags_vector(arg, expr, &tags_impl_skip, 0);
vlmfa67ddc2004-06-03 03:38:44 +0000613
vlm4a3f5822004-06-28 21:13:46 +0000614 p = MKID(expr->Identifier);
vlmfa67ddc2004-06-03 03:38:44 +0000615 OUT("static asn1_SET_OF_specifics_t asn1_DEF_%s_specs = {\n", p);
616 INDENTED(
617 OUT("sizeof(struct %s),\n", p);
618 OUT("offsetof(struct %s, _ber_dec_ctx),\n", p);
619 OUT("asn1_DEF_%s_elements\n", p);
620 );
621 OUT("};\n");
622 OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
623 INDENTED(
624 OUT("\"%s\",\n", expr->Identifier);
625 if(seq_of) {
626 OUT("SEQUENCE_OF_constraint,\n");
627 OUT("SEQUENCE_OF_decode_ber,\n");
628 OUT("SEQUENCE_OF_encode_der,\n");
629 OUT("SEQUENCE_OF_print,\n");
630 OUT("SEQUENCE_OF_free,\n");
631 } else {
632 OUT("SET_OF_constraint,\n");
633 OUT("SET_OF_decode_ber,\n");
634 OUT("SET_OF_encode_der,\n");
635 OUT("SET_OF_print,\n");
636 OUT("SET_OF_free,\n");
637 }
638 OUT("0,\t/* Use generic outmost tag fetcher */\n");
vlm6e73a042004-08-11 07:17:22 +0000639 if(tags_count) {
640 OUT("asn1_DEF_%s_tags,\n", p);
641 OUT("sizeof(asn1_DEF_%s_tags)\n", p);
642 OUT("\t/sizeof(asn1_DEF_%s_tags[0]), /* %d */\n",
643 p, tags_count);
644 } else {
645 OUT("0,\t/* No explicit tags (pointer) */\n");
646 OUT("0,\t/* No explicit tags (count) */\n");
647 }
vlmfa67ddc2004-06-03 03:38:44 +0000648 OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
649 OUT("%d,\t/* Whether CONSTRUCTED */\n", 1);
650 OUT("&asn1_DEF_%s_specs\t/* Additional specs */\n", p);
651 );
652 OUT("};\n");
653 OUT("\n");
654
vlmfa67ddc2004-06-03 03:38:44 +0000655 REDIR(OT_TYPE_DECLS);
656
657 return 0;
658}
659
660int
661asn1c_lang_C_type_CHOICE(arg_t *arg) {
662 asn1p_expr_t *expr = arg->expr;
663 asn1p_expr_t *v;
664 char *p;
665
666 DEPENDENCIES;
667
vlm33a4ff12004-08-11 05:21:32 +0000668 REDIR(OT_DEPS);
669
vlmfa67ddc2004-06-03 03:38:44 +0000670 p = MKID(expr->Identifier);
vlm33a4ff12004-08-11 05:21:32 +0000671 OUT("typedef enum %s_PR {\n", p);
672 INDENTED(
673 p = MKID(expr->Identifier);
674 OUT("%s_PR_NOTHING,\t"
675 "/* No components present */\n", p);
676 TQ_FOR(v, &(expr->members), next) {
677 if(v->expr_type == A1TC_EXTENSIBLE) {
678 OUT("/* Extensions may appear below */\n");
679 continue;
680 }
681 p = MKID(expr->Identifier);
682 OUT("%s_PR_", p);
683 p = MKID(v->Identifier);
684 OUT("%s,\n", p, p);
685 }
686 );
687 p = MKID(expr->Identifier);
vlm6e73a042004-08-11 07:17:22 +0000688 OUT("} %s_PR;\n", p);
vlm33a4ff12004-08-11 05:21:32 +0000689
690 REDIR(OT_TYPE_DECLS);
vlmfa67ddc2004-06-03 03:38:44 +0000691
692 if(arg->embed) {
693 OUT("struct %s {\n", p);
694 } else {
695 OUT("typedef struct %s {\n", p);
696 }
697
698 INDENTED(
vlm6e73a042004-08-11 07:17:22 +0000699 OUT("%s_PR present;\n", p);
vlmfa67ddc2004-06-03 03:38:44 +0000700 OUT("union {\n", p);
701 TQ_FOR(v, &(expr->members), next) {
702 EMBED(v);
703 }
704 if(UNNAMED_UNIONS) OUT("};\n");
705 else OUT("} choice;\n");
706 );
707
708 PCTX_DEF;
709 OUT("} %s%s", expr->marker?"*":"", MKID(expr->Identifier));
710 if(arg->embed) OUT(";\n"); else OUT("_t;\n");
711
712 return asn1c_lang_C_type_CHOICE_def(arg);
713}
714
715static int
716asn1c_lang_C_type_CHOICE_def(arg_t *arg) {
717 asn1p_expr_t *expr = arg->expr;
718 asn1p_expr_t *v;
719 int elements; /* Number of elements */
720 int tags_impl_skip = 0;
721 int comp_mode = 0; /* {root,ext=1,root,root,...} */
vlmfa67ddc2004-06-03 03:38:44 +0000722 tag2el_t *tag2el = NULL;
723 int tag2el_count = 0;
vlm6e73a042004-08-11 07:17:22 +0000724 int tags_count;
vlmfa67ddc2004-06-03 03:38:44 +0000725 char *p;
726
727 /*
728 * Fetch every inner tag from the tag to elements map.
729 */
730 if(_fill_tag2el_map(arg, &tag2el, &tag2el_count, -1)) {
731 if(tag2el) free(tag2el);
732 return -1;
vlmfa67ddc2004-06-03 03:38:44 +0000733 }
734
vlm33a4ff12004-08-11 05:21:32 +0000735 GEN_INCLUDE("constr_CHOICE");
736 if(!arg->embed)
737 GEN_DECLARE(expr); /* asn1_DEF_xxx */
vlmfa67ddc2004-06-03 03:38:44 +0000738
vlm33a4ff12004-08-11 05:21:32 +0000739 REDIR(OT_STAT_DEFS);
vlmfa67ddc2004-06-03 03:38:44 +0000740
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
vlm6e73a042004-08-11 07:17:22 +0000791
vlmfa67ddc2004-06-03 03:38:44 +0000792 if(arg->embed) {
793 /*
794 * Our parent structure has already taken this into account.
795 */
vlm6e73a042004-08-11 07:17:22 +0000796 tags_count = 0;
vlmfa67ddc2004-06-03 03:38:44 +0000797 } else {
vlm6e73a042004-08-11 07:17:22 +0000798 tags_count = emit_tags_vector(arg, expr, &tags_impl_skip, 1);
vlmfa67ddc2004-06-03 03:38:44 +0000799 }
vlmfa67ddc2004-06-03 03:38:44 +0000800
801 /*
802 * Tags to elements map.
803 */
vlm4e03ce22004-06-06 07:20:17 +0000804 emit_tag2member_map(arg, tag2el, tag2el_count);
vlmfa67ddc2004-06-03 03:38:44 +0000805
vlm6e73a042004-08-11 07:17:22 +0000806 p = MKID(expr->Identifier);
vlmfa67ddc2004-06-03 03:38:44 +0000807 OUT("static asn1_CHOICE_specifics_t asn1_DEF_%s_specs = {\n", p);
808 INDENTED(
809 OUT("sizeof(struct %s),\n", p);
810 OUT("offsetof(struct %s, _ber_dec_ctx),\n", p);
811 OUT("offsetof(struct %s, present),\n", p);
812 OUT("sizeof(((struct %s *)0)->present),\n", p);
813 OUT("asn1_DEF_%s_elements,\n", p);
814 OUT("%d,\t/* Elements count */\n", elements);
815 OUT("asn1_DEF_%s_tag2el,\n", p);
816 OUT("%d,\t/* Count of tags in the map */\n", tag2el_count);
vlm79b08d52004-07-01 00:52:50 +0000817 OUT("%d\t/* Whether extensible */\n",
818 check_if_extensible(expr));
vlmfa67ddc2004-06-03 03:38:44 +0000819 );
820 OUT("};\n");
821 OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
822 INDENTED(
823 OUT("\"%s\",\n", expr->Identifier);
824 OUT("CHOICE_constraint,\n");
825 OUT("CHOICE_decode_ber,\n");
826 OUT("CHOICE_encode_der,\n");
827 OUT("CHOICE_print,\n");
828 OUT("CHOICE_free,\n");
829 OUT("CHOICE_outmost_tag,\n");
vlm6e73a042004-08-11 07:17:22 +0000830 if(tags_count) {
831 OUT("asn1_DEF_%s_tags,\n", p);
832 OUT("sizeof(asn1_DEF_%s_tags)\n", p);
833 OUT("\t/sizeof(asn1_DEF_%s_tags[0]), /* %d */\n",
834 p, tags_count);
835 } else {
836 OUT("0,\t/* No explicit tags (pointer) */\n");
837 OUT("0,\t/* No explicit tags (count) */\n");
838 }
vlmfa67ddc2004-06-03 03:38:44 +0000839 OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
840 OUT("%d,\t/* Whether CONSTRUCTED */\n", 1);
841 OUT("&asn1_DEF_%s_specs\t/* Additional specs */\n", p);
842 );
843 OUT("};\n");
844 OUT("\n");
845
vlmfa67ddc2004-06-03 03:38:44 +0000846 REDIR(OT_TYPE_DECLS);
847
848 return 0;
849}
850
851int
852asn1c_lang_C_type_REFERENCE(arg_t *arg) {
853 asn1p_ref_t *ref;
854
855 ref = arg->expr->reference;
856 if(ref->components[ref->comp_count-1].name[0] == '&') {
857 asn1p_module_t *mod;
858 asn1p_expr_t *extract;
859 arg_t tmp;
860 int ret;
861
862 extract = asn1f_class_access_ex(arg->asn, arg->mod, arg->expr,
863 ref, &mod);
864 if(extract == NULL)
865 return -1;
866
867 extract = asn1p_expr_clone(extract);
868 if(extract) {
869 if(extract->Identifier)
870 free(extract->Identifier);
871 extract->Identifier = strdup(arg->expr->Identifier);
872 if(extract->Identifier == NULL) {
873 asn1p_expr_free(extract);
874 return -1;
875 }
876 } else {
877 return -1;
878 }
879
880 tmp = *arg;
881 tmp.asn = arg->asn;
882 tmp.mod = mod;
883 tmp.expr = extract;
884
885 ret = arg->default_cb(&tmp);
886
887 asn1p_expr_free(extract);
888
889 return ret;
890 }
891
892
893 return asn1c_lang_C_type_SIMPLE_TYPE(arg);
894}
895
896int
897asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
898 asn1p_expr_t *expr = arg->expr;
899 int tags_impl_skip = 0;
vlm6e73a042004-08-11 07:17:22 +0000900 int tags_count;
vlmfa67ddc2004-06-03 03:38:44 +0000901 char *p;
902
903 if(arg->embed) {
904 REDIR(OT_TYPE_DECLS);
905
906 OUT("%s\t", asn1c_type_name(arg, arg->expr,
907 expr->marker?TNF_RSAFE:TNF_CTYPE));
908 OUT("%s", expr->marker?"*":" ");
909 OUT("%s;", MKID(expr->Identifier));
910 if(expr->marker) OUT("\t/* %s */",
911 (expr->marker==EM_OPTIONAL)?"OPTIONAL":"DEFAULT");
912 OUT("\n");
913 return 0;
914 }
915
vlmfa67ddc2004-06-03 03:38:44 +0000916
vlm33a4ff12004-08-11 05:21:32 +0000917 GEN_INCLUDE(asn1c_type_name(arg, expr, TNF_INCLUDE));
vlmfa67ddc2004-06-03 03:38:44 +0000918
919 REDIR(OT_TYPE_DECLS);
920
921 OUT("typedef %s\t", asn1c_type_name(arg, arg->expr, TNF_CTYPE));
922 OUT("%s", expr->marker?"*":" ");
923 OUT("%s_t;\n", MKID(expr->Identifier));
924 OUT("\n");
925
926 REDIR(OT_STAT_DEFS);
927
vlm4a3f5822004-06-28 21:13:46 +0000928 /*
929 * Print out asn1_DEF_<type>_tags[] vector.
930 */
vlm6e73a042004-08-11 07:17:22 +0000931 tags_count = emit_tags_vector(arg, expr, &tags_impl_skip, 0);
vlmfa67ddc2004-06-03 03:38:44 +0000932
vlm4a3f5822004-06-28 21:13:46 +0000933 p = MKID(expr->Identifier);
vlmfa67ddc2004-06-03 03:38:44 +0000934 OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
935 INDENTED(
936 OUT("\"%s\",\n", expr->Identifier);
937 OUT("%s_constraint,\n", p);
938 OUT("%s_decode_ber,\n", p);
939 OUT("%s_encode_der,\n", p);
940 OUT("%s_print,\n", p);
941 OUT("%s_free,\n", p);
942 OUT("0,\t/* Use generic outmost tag fetcher */\n");
vlm6e73a042004-08-11 07:17:22 +0000943 if(tags_count) {
944 OUT("asn1_DEF_%s_tags,\n", p);
945 OUT("sizeof(asn1_DEF_%s_tags)\n", p);
946 OUT("\t/sizeof(asn1_DEF_%s_tags[0]), /* %d */\n",
947 p, tags_count);
948 } else {
949 OUT("0,\t/* No explicit tags (pointer) */\n");
950 OUT("0,\t/* No explicit tags (count) */\n");
951 }
vlmfa67ddc2004-06-03 03:38:44 +0000952 OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
vlm94faa932004-06-05 08:46:50 +0000953 OUT("-0,\t/* Unknown yet */\n");
954 OUT("0\t/* No specifics */\n");
vlmfa67ddc2004-06-03 03:38:44 +0000955 );
956 OUT("};\n");
957 OUT("\n");
958
959 /*
960 * Constraint checking.
961 */
vlm1d036692004-08-19 13:29:46 +0000962 /* Emit FROM() tables and others */
963 asn1c_emit_constraint_tables(arg, 0);
964
vlmfa67ddc2004-06-03 03:38:44 +0000965 p = MKID(expr->Identifier);
966 OUT("int\n");
967 OUT("%s_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,\n", p);
968 INDENTED(
969 OUT("\t\tasn_app_consume_bytes_f *app_errlog, void *app_key) {\n");
970 OUT("\n");
vlm1d036692004-08-19 13:29:46 +0000971 if(asn1c_emit_constraint_checking_code(arg) == 1) {
972 if(0) {
vlmfa67ddc2004-06-03 03:38:44 +0000973 OUT("/* Check the constraints of the underlying type */\n");
974 OUT("return asn1_DEF_%s.check_constraints\n",
975 asn1c_type_name(arg, expr, TNF_SAFE));
976 OUT("\t(td, sptr, app_errlog, app_key);\n");
vlm1d036692004-08-19 13:29:46 +0000977 } else {
vlmfa67ddc2004-06-03 03:38:44 +0000978 OUT("/* Make the underlying type checker permanent */\n");
979 OUT("td->check_constraints = asn1_DEF_%s.check_constraints;\n",
980 asn1c_type_name(arg, expr, TNF_SAFE));
981 OUT("return td->check_constraints\n");
982 OUT("\t(td, sptr, app_errlog, app_key);\n");
vlm1d036692004-08-19 13:29:46 +0000983 }
vlmfa67ddc2004-06-03 03:38:44 +0000984 }
985 );
986 OUT("}\n");
987 OUT("\n");
988
989 /*
990 * Emit suicidal functions.
991 */
992
993 {
994 /*
995 * This function replaces certain fields from the definition
996 * of a type with the corresponding fields from the basic type
997 * (from which the current type is inherited).
998 */
999 char *type_name = asn1c_type_name(arg, expr, TNF_SAFE);
1000 OUT("/*\n");
1001 OUT(" * This type is implemented using %s,\n", type_name);
1002 OUT(" * so adjust the DEF appropriately.\n");
1003 OUT(" */\n");
1004 OUT("static void\n");
1005 OUT("inherit_TYPE_descriptor(asn1_TYPE_descriptor_t *td) {\n");
1006 INDENT(+1);
1007 OUT("td->ber_decoder = asn1_DEF_%s.ber_decoder;\n", type_name);
1008 OUT("td->der_encoder = asn1_DEF_%s.der_encoder;\n", type_name);
1009 OUT("td->free_struct = asn1_DEF_%s.free_struct;\n", type_name);
1010 OUT("td->print_struct = asn1_DEF_%s.print_struct;\n", type_name);
1011 OUT("td->last_tag_form = asn1_DEF_%s.last_tag_form;\n", type_name);
1012 OUT("td->specifics = asn1_DEF_%s.specifics;\n", type_name);
1013 INDENT(-1);
1014 OUT("}\n");
1015 OUT("\n");
1016 }
1017
1018 p = MKID(expr->Identifier);
1019 OUT("ber_dec_rval_t\n");
1020 OUT("%s_decode_ber(asn1_TYPE_descriptor_t *td,\n", p);
1021 INDENTED(
1022 OUT("\tvoid **structure, void *bufptr, size_t size, int tag_mode) {\n");
1023 OUT("inherit_TYPE_descriptor(td);\n");
1024 OUT("return td->ber_decoder(td, structure,\n");
1025 OUT("\tbufptr, size, tag_mode);\n");
1026 );
1027 OUT("}\n");
1028 OUT("\n");
1029
1030 p = MKID(expr->Identifier);
1031 OUT("der_enc_rval_t\n");
1032 OUT("%s_encode_der(asn1_TYPE_descriptor_t *td,\n", p);
1033 INDENTED(
1034 OUT("\tvoid *structure, int tag_mode, ber_tlv_tag_t tag,\n");
1035 OUT("\tasn_app_consume_bytes_f *cb, void *app_key) {\n");
1036 OUT("inherit_TYPE_descriptor(td);\n");
1037 OUT("return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);\n");
1038 );
1039 OUT("}\n");
1040 OUT("\n");
1041
1042 p = MKID(expr->Identifier);
1043 OUT("int\n");
1044 OUT("%s_print(asn1_TYPE_descriptor_t *td, const void *struct_ptr,\n", p);
1045 INDENTED(
1046 OUT("\tint ilevel, asn_app_consume_bytes_f *cb, void *app_key) {\n");
1047 OUT("inherit_TYPE_descriptor(td);\n");
1048 OUT("return td->print_struct(td, struct_ptr, ilevel, cb, app_key);\n");
1049 );
1050 OUT("}\n");
1051 OUT("\n");
1052
1053 p = MKID(expr->Identifier);
1054 OUT("void\n");
1055 OUT("%s_free(asn1_TYPE_descriptor_t *td,\n", p);
1056 INDENTED(
1057 OUT("\tvoid *struct_ptr, int contents_only) {\n");
1058 OUT("inherit_TYPE_descriptor(td);\n");
1059 OUT("td->free_struct(td, struct_ptr, contents_only);\n");
1060 );
1061 OUT("}\n");
1062 OUT("\n");
1063
1064 REDIR(OT_FUNC_DECLS);
1065
1066 p = MKID(expr->Identifier);
1067 OUT("extern asn1_TYPE_descriptor_t asn1_DEF_%s;\n", p);
1068 OUT("asn_constr_check_f %s_constraint;\n", p);
1069 OUT("ber_type_decoder_f %s_decode_ber;\n", p);
1070 OUT("der_type_encoder_f %s_encode_der;\n", p);
1071 OUT("asn_struct_print_f %s_print;\n", p);
1072 OUT("asn_struct_free_f %s_free;\n", p);
1073
vlm33a4ff12004-08-11 05:21:32 +00001074 REDIR(OT_TYPE_DECLS);
1075
vlmfa67ddc2004-06-03 03:38:44 +00001076 return 0;
1077}
1078
1079int
1080asn1c_lang_C_type_EXTENSIBLE(arg_t *arg) {
1081
1082 OUT("/*\n");
1083 OUT(" * This type is extensible,\n");
1084 OUT(" * possible extensions are below.\n");
1085 OUT(" */\n");
1086
1087 return 0;
1088}
1089
vlm79b08d52004-07-01 00:52:50 +00001090static int check_if_extensible(asn1p_expr_t *expr) {
1091 asn1p_expr_t *v;
1092 TQ_FOR(v, &(expr->members), next) {
1093 if(v->expr_type == A1TC_EXTENSIBLE) return 1;
1094 }
1095 return 0;
1096}
1097
vlmfa67ddc2004-06-03 03:38:44 +00001098static int
1099_print_tag(arg_t *arg, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag_p) {
1100 struct asn1p_type_tag_s tag;
1101
1102 if(tag_p) {
1103 tag = *tag_p;
1104 } else {
1105 if(asn1f_fetch_tag(arg->asn, arg->mod, expr, &tag)) {
1106 OUT("-1 /* Ambiguous tag (CHOICE?) */");
1107 return 0;
1108 }
1109 }
1110
1111 OUT("(");
1112 switch(tag.tag_class) {
1113 case TC_UNIVERSAL: OUT("ASN_TAG_CLASS_UNIVERSAL"); break;
1114 case TC_APPLICATION: OUT("ASN_TAG_CLASS_APPLICATION"); break;
1115 case TC_CONTEXT_SPECIFIC: OUT("ASN_TAG_CLASS_CONTEXT"); break;
1116 case TC_PRIVATE: OUT("ASN_TAG_CLASS_PRIVATE"); break;
1117 case TC_NOCLASS:
1118 break;
1119 }
1120 OUT(" | (%lld << 2))", tag.tag_value);
1121
1122 return 0;
1123}
1124
vlm4e03ce22004-06-06 07:20:17 +00001125
1126static int
1127_tag2el_cmp(const void *ap, const void *bp) {
1128 const tag2el_t *a = ap;
1129 const tag2el_t *b = bp;
1130 const struct asn1p_type_tag_s *ta = &a->el_tag;
1131 const struct asn1p_type_tag_s *tb = &b->el_tag;
1132
1133 if(ta->tag_class == tb->tag_class) {
1134 if(ta->tag_value == tb->tag_value) {
1135 /*
1136 * Sort by their respective positions.
1137 */
1138 if(a->el_no < b->el_no)
1139 return -1;
1140 else if(a->el_no > b->el_no)
1141 return 1;
1142 return 0;
1143 } else if(ta->tag_value < tb->tag_value)
1144 return -1;
1145 else
1146 return 1;
1147 } else if(ta->tag_class < tb->tag_class) {
1148 return -1;
1149 } else {
1150 return 1;
1151 }
1152}
1153
vlmfa67ddc2004-06-03 03:38:44 +00001154/*
1155 * For constructed types, number of external tags may be greater than
1156 * number of elements in the type because of CHOICE type.
1157 * T ::= SET { -- Three possible tags:
1158 * a INTEGER, -- One tag is here...
1159 * b Choice1 -- ... and two more tags are there.
1160 * }
1161 * Choice1 ::= CHOICE {
1162 * s1 IA5String,
1163 * s2 ObjectDescriptor
1164 * }
1165 */
1166static int
1167_fill_tag2el_map(arg_t *arg, tag2el_t **tag2el, int *count, int el_no) {
1168 asn1p_expr_t *expr = arg->expr;
1169 arg_t tmparg = *arg;
1170 asn1p_expr_t *v;
1171 int element = 0;
1172
1173 TQ_FOR(v, &(expr->members), next) {
1174 if(v->expr_type == A1TC_EXTENSIBLE)
1175 continue;
1176
1177 tmparg.expr = v;
1178
1179 if(_add_tag2el_member(&tmparg, tag2el, count,
1180 (el_no==-1)?element:el_no)) {
1181 return -1;
1182 }
1183
1184 element++;
1185 }
1186
vlm4e03ce22004-06-06 07:20:17 +00001187 /*
vlmc8aeab42004-06-14 13:09:45 +00001188 * Sort the map according to canonical order of their tags
1189 * and element numbers.
vlm4e03ce22004-06-06 07:20:17 +00001190 */
1191 qsort(*tag2el, *count, sizeof(**tag2el), _tag2el_cmp);
1192
vlmc8aeab42004-06-14 13:09:45 +00001193 /*
1194 * Initialize .toff_{first|last} members.
1195 */
1196 if(*count) {
1197 struct asn1p_type_tag_s *cur_tag = 0;
1198 tag2el_t *cur = *tag2el;
1199 tag2el_t *end = cur + *count;
1200 int occur, i;
1201 for(occur = 0; cur < end; cur++) {
1202 if(cur_tag == 0
1203 || cur_tag->tag_value != cur->el_tag.tag_value
1204 || cur_tag->tag_class != cur->el_tag.tag_class) {
1205 cur_tag = &cur->el_tag;
1206 occur = 0;
1207 } else {
1208 occur++;
1209 }
1210 cur->toff_first = -occur;
1211 for(i = 0; i >= -occur; i--)
1212 cur[i].toff_last = -i;
1213 }
1214 }
1215
vlmfa67ddc2004-06-03 03:38:44 +00001216 return 0;
1217}
1218
1219static int
1220_add_tag2el_member(arg_t *arg, tag2el_t **tag2el, int *count, int el_no) {
1221 struct asn1p_type_tag_s tag;
1222 int ret;
1223
1224 assert(el_no >= 0);
1225
1226 ret = asn1f_fetch_tag(arg->asn, arg->mod, arg->expr, &tag);
1227 if(ret == 0) {
1228 void *p;
1229 p = realloc(*tag2el, sizeof(tag2el_t) * ((*count) + 1));
1230 if(p) *tag2el = p;
1231 else return -1;
1232
1233 DEBUG("Found tag for %s: %ld",
1234 arg->expr->Identifier,
1235 (long)tag.tag_value);
1236
1237 (*tag2el)[*count].el_tag = tag;
1238 (*tag2el)[*count].el_no = el_no;
1239 (*tag2el)[*count].from_expr = arg->expr;
1240 (*count)++;
1241 return 0;
1242 }
1243
1244 DEBUG("Searching tag in complex expression %s:%x at line %d",
1245 arg->expr->Identifier,
1246 arg->expr->expr_type,
1247 arg->expr->_lineno);
1248
1249 /*
1250 * Iterate over members of CHOICE type.
1251 */
1252 if(arg->expr->expr_type == ASN_CONSTR_CHOICE) {
1253 return _fill_tag2el_map(arg, tag2el, count, el_no);
1254 }
1255
1256 if(arg->expr->expr_type == A1TC_REFERENCE) {
1257 arg_t tmp = *arg;
1258 asn1p_expr_t *expr;
1259 expr = asn1f_lookup_symbol_ex(tmp.asn, &tmp.mod, tmp.expr,
1260 arg->expr->reference);
1261 if(expr) {
1262 tmp.expr = expr;
1263 return _add_tag2el_member(&tmp, tag2el, count, el_no);
1264 } else {
1265 FATAL("Cannot dereference %s at line %d",
1266 arg->expr->Identifier,
1267 arg->expr->_lineno);
1268 return -1;
1269 }
1270 }
1271
1272 DEBUG("No tag for %s at line %d",
1273 arg->expr->Identifier,
1274 arg->expr->_lineno);
1275
1276 return -1;
1277}
1278
1279static int
vlm4e03ce22004-06-06 07:20:17 +00001280emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count) {
1281 asn1p_expr_t *expr = arg->expr;
1282
1283 OUT("static asn1_TYPE_tag2member_t asn1_DEF_%s_tag2el[] = {\n",
1284 MKID(expr->Identifier));
1285 if(tag2el_count) {
1286 int i;
1287 for(i = 0; i < tag2el_count; i++) {
1288 OUT(" { ");
1289 _print_tag(arg, expr, &tag2el[i].el_tag);
1290 OUT(", ");
vlmc8aeab42004-06-14 13:09:45 +00001291 OUT("%d, ", tag2el[i].el_no);
1292 OUT("%d, ", tag2el[i].toff_first);
1293 OUT("%d ", tag2el[i].toff_last);
vlm4e03ce22004-06-06 07:20:17 +00001294 OUT("}, /* %s at %d */\n",
1295 tag2el[i].from_expr->Identifier,
1296 tag2el[i].from_expr->_lineno
1297 );
1298 }
1299 }
1300 OUT("};\n");
1301
1302 return 0;;
1303}
1304
1305static int
vlm6e73a042004-08-11 07:17:22 +00001306emit_tags_vector(arg_t *arg, asn1p_expr_t *expr, int *tags_impl_skip, int choice_mode) {
1307 int tags_count = 0;
1308 int save_target = arg->target->target;
vlm4a3f5822004-06-28 21:13:46 +00001309 char *p;
1310
vlm6e73a042004-08-11 07:17:22 +00001311 if(save_target != OT_IGNORE) {
1312 int save_impl_skip = *tags_impl_skip;
1313 REDIR(OT_IGNORE);
1314 tags_count = emit_tags_vector(arg, expr,
1315 tags_impl_skip, choice_mode);
1316 REDIR(save_target);
1317 if(tags_count) {
1318 *tags_impl_skip = save_impl_skip;
1319 tags_count = 0;
1320 } else {
1321 return 0;
1322 }
1323 }
1324
1325
vlm4a3f5822004-06-28 21:13:46 +00001326 p = MKID(expr->Identifier);
1327 OUT("static ber_tlv_tag_t asn1_DEF_%s_tags[] = {\n", p);
1328 INDENTED(
1329 if(expr->tag.tag_class) {
vlm6e73a042004-08-11 07:17:22 +00001330 tags_count++;
vlm4a3f5822004-06-28 21:13:46 +00001331 _print_tag(arg, expr, &expr->tag);
1332 if(expr->tag.tag_mode != TM_EXPLICIT)
1333 (*tags_impl_skip)++;
1334 } else {
vlm6e73a042004-08-11 07:17:22 +00001335 if(!choice_mode)
1336 (*tags_impl_skip)++;
vlm4a3f5822004-06-28 21:13:46 +00001337 }
vlm6e73a042004-08-11 07:17:22 +00001338 if(!choice_mode) {
1339 if(!expr->tag.tag_class
1340 || (expr->meta_type == AMT_TYPE
1341 && expr->tag.tag_mode == TM_EXPLICIT)) {
1342 struct asn1p_type_tag_s tag;
1343 if(expr->tag.tag_class)
1344 OUT(",\n");
1345 tag.tag_class = TC_UNIVERSAL;
1346 tag.tag_mode = TM_IMPLICIT;
1347 tag.tag_value = expr_type2uclass_value[expr->expr_type];
1348 _print_tag(arg, expr, &tag);
1349 tags_count++;
1350 }
vlm4a3f5822004-06-28 21:13:46 +00001351 }
1352 OUT("\n");
1353 );
1354 OUT("};\n");
1355
vlm6e73a042004-08-11 07:17:22 +00001356 return tags_count;
vlm4a3f5822004-06-28 21:13:46 +00001357}