blob: 197ce1f938fabc30a0db342734dd3c9a428b8b95 [file] [log] [blame]
vlmfa67ddc2004-06-03 03:38:44 +00001/*
2 * Don't look into this file. First, because it's a mess, and second, because
3 * it's a brain of the compiler, and you don't wanna mess with brains do you? ;)
4 */
5#include "asn1c_internal.h"
6#include "asn1c_C.h"
7#include <asn1fix_export.h> /* exportable stuff from libasn1fix */
8
vlm4e03ce22004-06-06 07:20:17 +00009typedef struct tag2el_s {
10 struct asn1p_type_tag_s el_tag;
11 int el_no;
vlmc8aeab42004-06-14 13:09:45 +000012 int toff_first;
13 int toff_last;
vlm4e03ce22004-06-06 07:20:17 +000014 asn1p_expr_t *from_expr;
15} tag2el_t;
16
17static int _fill_tag2el_map(arg_t *arg, tag2el_t **tag2el, int *count, int el_no);
18static int _add_tag2el_member(arg_t *arg, tag2el_t **tag2el, int *count, int el_no);
19
vlmfa67ddc2004-06-03 03:38:44 +000020static int asn1c_lang_C_type_SEQUENCE_def(arg_t *arg);
21static int asn1c_lang_C_type_SET_def(arg_t *arg);
22static int asn1c_lang_C_type_CHOICE_def(arg_t *arg);
23static int asn1c_lang_C_type_SEx_OF_def(arg_t *arg, int seq_of);
24static int _print_tag(arg_t *arg, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag_p);
vlm79b08d52004-07-01 00:52:50 +000025static int check_if_extensible(asn1p_expr_t *expr);
vlm6e73a042004-08-11 07:17:22 +000026static int emit_tags_vector(arg_t *arg, asn1p_expr_t *expr, int *tags_impl_skip, int choice_mode);
vlm4e03ce22004-06-06 07:20:17 +000027static int emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count);
vlmfa67ddc2004-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
vlmfa67ddc2004-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
vlm33a4ff12004-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)
vlmfa67ddc2004-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;
vlm4e03ce22004-06-06 07:20:17 +0000166 tag2el_t *tag2el = NULL;
167 int tag2el_count = 0;
vlm6e73a042004-08-11 07:17:22 +0000168 int tags_count;
vlmfa67ddc2004-06-03 03:38:44 +0000169 char *p;
170
vlm4e03ce22004-06-06 07:20:17 +0000171 /*
172 * Fetch every inner tag from the tag to elements map.
173 */
174 if(_fill_tag2el_map(arg, &tag2el, &tag2el_count, -1)) {
175 if(tag2el) free(tag2el);
176 return -1;
177 }
178
vlm33a4ff12004-08-11 05:21:32 +0000179 GEN_INCLUDE("constr_SEQUENCE");
180 if(!arg->embed)
181 GEN_DECLARE(expr); /* asn1_DEF_xxx */
vlmfa67ddc2004-06-03 03:38:44 +0000182
vlm33a4ff12004-08-11 05:21:32 +0000183 REDIR(OT_STAT_DEFS);
vlmfa67ddc2004-06-03 03:38:44 +0000184
185 /*
186 * Print out the table according to which the parsing is performed.
187 */
188 p = MKID(expr->Identifier);
189 OUT("static asn1_SEQUENCE_element_t asn1_DEF_%s_elements[] = {\n", p);
190
191 elements = 0;
192 INDENTED(TQ_FOR(v, &(expr->members), next) {
193 if(v->expr_type == A1TC_EXTENSIBLE) {
194 if((++comp_mode) == 1)
195 ext_start = elements - 1;
196 else
197 ext_stop = elements - 1;
198 continue;
199 }
200 OUT("{ ");
201 elements++;
202 OUT("offsetof(struct %s, ", MKID(expr->Identifier));
203 OUT("%s), ", MKID(v->Identifier));
204 if(v->marker) {
205 asn1p_expr_t *tv;
206 int opts = 0;
207 for(tv = v; tv && tv->marker;
208 tv = TQ_NEXT(tv, next), opts++) {
209 if(tv->expr_type == A1TC_EXTENSIBLE)
210 opts--;
211 }
212 OUT("%d,", opts);
213 } else {
214 OUT("0,");
215 }
216 OUT("\n");
217 INDENT(+1);
218 if(C99_MODE) OUT(".tag = ");
219 _print_tag(arg, v, NULL);
220 OUT(",\n");
221 if(C99_MODE) OUT(".tag_mode = ");
222 if(v->tag.tag_class) {
223 if(v->tag.tag_mode == TM_IMPLICIT)
224 OUT("-1,\t/* IMPLICIT tag at current level */\n");
225 else
226 OUT("+1,\t/* EXPLICIT tag at current level */\n");
227 } else {
228 OUT("0,\n");
229 }
230 if(C99_MODE) OUT(".type = ");
231 OUT("(void *)&asn1_DEF_%s,\n",
232 asn1c_type_name(arg, v, TNF_SAFE));
233 if(C99_MODE) OUT(".name = ");
234 OUT("\"%s\"\n", v->Identifier);
235 OUT("},\n");
236 INDENT(-1);
237 });
238 OUT("};\n");
239
vlm4a3f5822004-06-28 21:13:46 +0000240 /*
241 * Print out asn1_DEF_<type>_tags[] vector.
242 */
vlm6e73a042004-08-11 07:17:22 +0000243 tags_count = emit_tags_vector(arg, expr, &tags_impl_skip, 0);
vlmfa67ddc2004-06-03 03:38:44 +0000244
vlm4e03ce22004-06-06 07:20:17 +0000245 /*
246 * Tags to elements map.
247 */
248 emit_tag2member_map(arg, tag2el, tag2el_count);
249
vlm4a3f5822004-06-28 21:13:46 +0000250 p = MKID(expr->Identifier);
vlmfa67ddc2004-06-03 03:38:44 +0000251 OUT("static asn1_SEQUENCE_specifics_t asn1_DEF_%s_specs = {\n", p);
252 INDENTED(
253 OUT("sizeof(struct %s),\n", p);
254 OUT("offsetof(struct %s, _ber_dec_ctx),\n", p);
255 OUT("asn1_DEF_%s_elements,\n", p);
256 OUT("%d,\t/* Elements count */\n", elements);
vlm4e03ce22004-06-06 07:20:17 +0000257 OUT("asn1_DEF_%s_tag2el,\n", p);
258 OUT("%d,\t/* Count of tags in the map */\n", tag2el_count);
vlmfa67ddc2004-06-03 03:38:44 +0000259 OUT("%d,\t/* Start extensions */\n",
260 ext_start);
261 OUT("%d\t/* Stop extensions */\n",
262 (ext_stop<ext_start)?elements+1:ext_stop, ext_stop);
263 );
264 OUT("};\n");
265 OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
266 INDENTED(
267 OUT("\"%s\",\n", expr->Identifier);
268 OUT("SEQUENCE_constraint,\n");
269 OUT("SEQUENCE_decode_ber,\n");
270 OUT("SEQUENCE_encode_der,\n");
271 OUT("SEQUENCE_print,\n");
272 OUT("SEQUENCE_free,\n");
273 OUT("0,\t/* Use generic outmost tag fetcher */\n");
vlm6e73a042004-08-11 07:17:22 +0000274 if(tags_count) {
275 OUT("asn1_DEF_%s_tags,\n", p);
276 OUT("sizeof(asn1_DEF_%s_tags)\n", p);
277 OUT("\t/sizeof(asn1_DEF_%s_tags[0]), /* %d */\n",
278 p, tags_count);
279 } else {
280 OUT("0,\t/* No explicit tags (pointer) */\n");
281 OUT("0,\t/* No explicit tags (count) */\n");
282 }
vlmfa67ddc2004-06-03 03:38:44 +0000283 OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
284 OUT("%d,\t/* Whether CONSTRUCTED */\n", 1);
285 OUT("&asn1_DEF_%s_specs\t/* Additional specs */\n", p);
286 );
287 OUT("};\n");
288 OUT("\n");
289
vlmfa67ddc2004-06-03 03:38:44 +0000290 REDIR(OT_TYPE_DECLS);
291
292 return 0;
293}
294
295int
296asn1c_lang_C_type_SEQUENCE_OF(arg_t *arg) {
297 asn1p_expr_t *expr = arg->expr;
298 asn1p_expr_t *v;
299
300 DEPENDENCIES;
301
302 if(arg->embed) {
303 OUT("struct %s {\n", MKID(expr->Identifier));
304 } else {
305 OUT("typedef struct %s {\n", MKID(expr->Identifier));
306 }
307
308 TQ_FOR(v, &(expr->members), next) {
309 INDENTED(OUT("A_SEQUENCE_OF(%s) list;\n",
310 asn1c_type_name(arg, v, TNF_RSAFE)));
311 }
312
313 PCTX_DEF;
314 OUT("} %s%s", expr->marker?"*":"", MKID(expr->Identifier));
315 if(arg->embed) OUT(";\n"); else OUT("_t;\n");
316
317 /*
318 * SET OF/SEQUENCE OF definition, SEQUENCE OF mode.
319 */
320 return asn1c_lang_C_type_SEx_OF_def(arg, 1);
321}
322
323int
324asn1c_lang_C_type_SET(arg_t *arg) {
325 asn1p_expr_t *expr = arg->expr;
326 asn1p_expr_t *v;
327 long mcount;
328 char *id;
329 int comp_mode = 0; /* {root,ext=1,root,root,...} */
330
331 DEPENDENCIES;
332
333 REDIR(OT_DEPS);
334
335 OUT("\n");
336 OUT("/*\n");
337 OUT(" * Method of determining the components presence\n");
338 OUT(" */\n");
339 mcount = 0;
vlm6e73a042004-08-11 07:17:22 +0000340 OUT("typedef enum %s_PR {\n", MKID(expr->Identifier));
vlmfa67ddc2004-06-03 03:38:44 +0000341 TQ_FOR(v, &(expr->members), next) {
342 if(v->expr_type == A1TC_EXTENSIBLE) continue;
343 INDENTED(
344 id = MKID(expr->Identifier);
345 OUT("%s_PR_", id);
346 id = MKID(v->Identifier);
347 OUT("%s,\t/* Member %s is present */\n",
348 id, id)
349 );
350 mcount++;
351 }
vlm6e73a042004-08-11 07:17:22 +0000352 id = MKID(expr->Identifier);
353 OUT("} %s_PR;\n", id);
vlmfa67ddc2004-06-03 03:38:44 +0000354
355 REDIR(OT_TYPE_DECLS);
356
357 if(arg->embed) {
vlm6e73a042004-08-11 07:17:22 +0000358 OUT("struct %s {\n", id);
vlmfa67ddc2004-06-03 03:38:44 +0000359 } else {
vlm6e73a042004-08-11 07:17:22 +0000360 OUT("typedef struct %s {\n", id);
vlmfa67ddc2004-06-03 03:38:44 +0000361 }
362
363 TQ_FOR(v, &(expr->members), next) {
364 if(v->expr_type == A1TC_EXTENSIBLE) {
365 if(comp_mode < 3) comp_mode++;
366 }
367 if(comp_mode == 1 && !v->marker)
368 v->marker = EM_OPTIONAL;
369 EMBED(v);
370 }
371
372 INDENTED(
373 id = MKID(expr->Identifier);
374 OUT("\n");
375 OUT("/* Presence bitmask: ASN_SET_ISPRESENT(p%s, %s_PR_x) */\n",
376 id, id);
377 OUT("unsigned int _presence_map\n");
378 OUT("\t[((%ld+(8*sizeof(unsigned int))-1)/(8*sizeof(unsigned int)))];\n", mcount);
379 );
380
381 PCTX_DEF;
382 OUT("} %s%s", expr->marker?"*":"", MKID(expr->Identifier));
383 if(arg->embed) OUT(";\n"); else OUT("_t;\n");
384
385 return asn1c_lang_C_type_SET_def(arg);
386}
387
vlmfa67ddc2004-06-03 03:38:44 +0000388static int
389asn1c_lang_C_type_SET_def(arg_t *arg) {
390 asn1p_expr_t *expr = arg->expr;
391 asn1p_expr_t *v;
392 int elements;
393 int tags_impl_skip = 0;
394 int comp_mode = 0; /* {root,ext=1,root,root,...} */
vlmfa67ddc2004-06-03 03:38:44 +0000395 tag2el_t *tag2el = NULL;
396 int tag2el_count = 0;
vlm6e73a042004-08-11 07:17:22 +0000397 int tags_count;
vlmfa67ddc2004-06-03 03:38:44 +0000398 char *p;
399
400 /*
401 * Fetch every inner tag from the tag to elements map.
402 */
403 if(_fill_tag2el_map(arg, &tag2el, &tag2el_count, -1)) {
404 if(tag2el) free(tag2el);
405 return -1;
vlmfa67ddc2004-06-03 03:38:44 +0000406 }
407
vlm33a4ff12004-08-11 05:21:32 +0000408 GEN_INCLUDE("constr_SET");
409 if(!arg->embed)
410 GEN_DECLARE(expr); /* asn1_DEF_xxx */
vlmfa67ddc2004-06-03 03:38:44 +0000411
412 REDIR(OT_STAT_DEFS);
413
vlmfa67ddc2004-06-03 03:38:44 +0000414 /*
415 * Print out the table according to which the parsing is performed.
416 */
417 p = MKID(expr->Identifier);
418 OUT("static asn1_SET_element_t asn1_DEF_%s_elements[] = {\n", p);
419
420 elements = 0;
421 INDENTED(TQ_FOR(v, &(expr->members), next) {
422 if(v->expr_type != A1TC_EXTENSIBLE) {
423 if(comp_mode == 1)
424 v->marker = EM_OPTIONAL;
425 elements++;
426 } else {
427 if(comp_mode < 3) comp_mode++;
428 continue;
429 }
430 OUT("{ ");
431 p = MKID(expr->Identifier);
432 OUT("offsetof(struct %s, ", p);
433 p = MKID(v->Identifier);
434 OUT("%s), ", p);
435 if(v->marker) {
436 OUT("1, /* Optional element */\n");
437 } else {
438 OUT("0,\n");
439 }
440 INDENT(+1);
441 if(C99_MODE) OUT(".tag = ");
442 _print_tag(arg, v, NULL);
443 OUT(",\n");
444 if(C99_MODE) OUT(".tag_mode = ");
445 if(v->tag.tag_class) {
446 if(v->tag.tag_mode == TM_IMPLICIT)
447 OUT("-1,\t/* IMPLICIT tag at current level */\n");
448 else
449 OUT("+1,\t/* EXPLICIT tag at current level */\n");
450 } else {
451 OUT("0,\n");
452 }
453 if(C99_MODE) OUT(".type = ");
454 OUT("(void *)&asn1_DEF_%s,\n",
455 asn1c_type_name(arg, v, TNF_SAFE));
456 if(C99_MODE) OUT(".name = ");
457 OUT("\"%s\"\n", v->Identifier);
458 OUT("},\n");
459 INDENT(-1);
460 });
461 OUT("};\n");
462
vlm4a3f5822004-06-28 21:13:46 +0000463 /*
464 * Print out asn1_DEF_<type>_tags[] vector.
465 */
vlm6e73a042004-08-11 07:17:22 +0000466 tags_count = emit_tags_vector(arg, expr, &tags_impl_skip, 0);
vlmfa67ddc2004-06-03 03:38:44 +0000467
468 /*
469 * Tags to elements map.
470 */
vlm4e03ce22004-06-06 07:20:17 +0000471 emit_tag2member_map(arg, tag2el, tag2el_count);
vlmfa67ddc2004-06-03 03:38:44 +0000472
473 /*
474 * Emit a map of mandatory elements.
475 */
vlm4a3f5822004-06-28 21:13:46 +0000476 p = MKID(expr->Identifier);
vlmfa67ddc2004-06-03 03:38:44 +0000477 OUT("static uint8_t asn1_DEF_%s_mmap", p);
478 OUT("[(%d + (8 * sizeof(unsigned int)) - 1) / 8]", elements);
479 OUT(" = {\n", p);
480 INDENTED(
481 if(elements) {
482 int delimit = 0;
483 int el = 0;
484 TQ_FOR(v, &(expr->members), next) {
485 if(v->expr_type == A1TC_EXTENSIBLE) continue;
486 if(delimit) {
487 OUT(",\n");
488 delimit = 0;
489 } else if(el) {
490 OUT(" | ");
491 }
492 OUT("(%d << %d)", v->marker?0:1, 7 - (el % 8));
493 if(el && (el % 8) == 0)
494 delimit = 1;
495 el++;
496 }
497 } else {
498 OUT("0");
499 }
500 );
501 OUT("\n");
502 OUT("};\n");
503
504 OUT("static asn1_SET_specifics_t asn1_DEF_%s_specs = {\n", p);
505 INDENTED(
506 OUT("sizeof(struct %s),\n", p);
507 OUT("offsetof(struct %s, _ber_dec_ctx),\n", p);
508 OUT("offsetof(struct %s, _presence_map),\n", p);
509 OUT("asn1_DEF_%s_elements,\n", p);
510 OUT("%d,\t/* Elements count */\n", elements);
511 OUT("asn1_DEF_%s_tag2el,\n", p);
512 OUT("%d,\t/* Count of tags in the map */\n", tag2el_count);
vlm79b08d52004-07-01 00:52:50 +0000513 OUT("%d,\t/* Whether extensible */\n",
514 check_if_extensible(expr));
vlmfa67ddc2004-06-03 03:38:44 +0000515 OUT("(unsigned int *)asn1_DEF_%s_mmap\t/* Mandatory elements map */\n", p);
516 );
517 OUT("};\n");
518 OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
519 INDENTED(
520 OUT("\"%s\",\n", expr->Identifier);
521 OUT("SET_constraint,\n");
522 OUT("SET_decode_ber,\n");
523 OUT("SET_encode_der,\n");
524 OUT("SET_print,\n");
525 OUT("SET_free,\n");
526 OUT("0,\t/* Use generic outmost tag fetcher */\n");
vlm6e73a042004-08-11 07:17:22 +0000527 if(tags_count) {
528 OUT("asn1_DEF_%s_tags,\n", p);
529 OUT("sizeof(asn1_DEF_%s_tags)\n", p);
530 OUT("\t/sizeof(asn1_DEF_%s_tags[0]), /* %d */\n",
531 p, tags_count);
532 } else {
533 OUT("0,\t/* No explicit tags (pointer) */\n");
534 OUT("0,\t/* No explicit tags (count) */\n");
535 }
vlmfa67ddc2004-06-03 03:38:44 +0000536 OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
537 OUT("%d,\t/* Whether CONSTRUCTED */\n", 1);
538 OUT("&asn1_DEF_%s_specs\t/* Additional specs */\n", p);
539 );
540 OUT("};\n");
541 OUT("\n");
542
vlmfa67ddc2004-06-03 03:38:44 +0000543 REDIR(OT_TYPE_DECLS);
544
545 return 0;
546}
547
548int
549asn1c_lang_C_type_SET_OF(arg_t *arg) {
550 asn1p_expr_t *expr = arg->expr;
551 asn1p_expr_t *v;
552
553 DEPENDENCIES;
554
555 if(arg->embed) {
556 OUT("struct %s {\n", MKID(expr->Identifier));
557 } else {
558 OUT("typedef struct %s {\n",
559 MKID(expr->Identifier));
560 }
561
562 TQ_FOR(v, &(expr->members), next) {
563 INDENTED(OUT("A_SET_OF(%s) list;\n",
564 asn1c_type_name(arg, v, TNF_RSAFE)));
565 }
566
567 PCTX_DEF;
568 OUT("} %s%s", expr->marker?"*":"", MKID(expr->Identifier));
569 if(arg->embed) OUT(";\n"); else OUT("_t;\n");
570
571 /*
572 * SET OF/SEQUENCE OF definition, SET OF mode.
573 */
574 return asn1c_lang_C_type_SEx_OF_def(arg, 0);
575}
576
577static int
578asn1c_lang_C_type_SEx_OF_def(arg_t *arg, int seq_of) {
579 asn1p_expr_t *expr = arg->expr;
580 asn1p_expr_t *v;
581 int tags_impl_skip = 0;
vlm6e73a042004-08-11 07:17:22 +0000582 int tags_count;
vlmfa67ddc2004-06-03 03:38:44 +0000583 char *p;
584
vlm33a4ff12004-08-11 05:21:32 +0000585 /*
586 * Print out the table according to which the parsing is performed.
587 */
vlmfa67ddc2004-06-03 03:38:44 +0000588 if(seq_of) {
vlm33a4ff12004-08-11 05:21:32 +0000589 GEN_INCLUDE("constr_SEQUENCE_OF");
vlmfa67ddc2004-06-03 03:38:44 +0000590 } else {
vlm33a4ff12004-08-11 05:21:32 +0000591 GEN_INCLUDE("constr_SET_OF");
vlmfa67ddc2004-06-03 03:38:44 +0000592 }
vlm33a4ff12004-08-11 05:21:32 +0000593 if(!arg->embed)
594 GEN_DECLARE(expr); /* asn1_DEF_xxx */
vlmfa67ddc2004-06-03 03:38:44 +0000595
596 REDIR(OT_STAT_DEFS);
597
598 /*
599 * Print out the table according to which the parsing is performed.
600 */
601 p = MKID(expr->Identifier);
602 OUT("static asn1_SET_OF_element_t asn1_DEF_%s_elements[] = {\n", p);
603
604 INDENTED(OUT("{ ");
605 v = TQ_FIRST(&(expr->members));
606 INDENT(+1);
607 if(C99_MODE) OUT(".tag = ");
608 _print_tag(arg, v, NULL);
609 OUT(",\n");
610 if(C99_MODE) OUT(".type = ");
611 OUT("(void *)&asn1_DEF_%s",
612 asn1c_type_name(arg, v, TNF_SAFE));
613 OUT(" ");
614 OUT("},\n");
615 INDENT(-1);
616 );
617 OUT("};\n");
618
vlm4a3f5822004-06-28 21:13:46 +0000619 /*
620 * Print out asn1_DEF_<type>_tags[] vector.
621 */
vlm6e73a042004-08-11 07:17:22 +0000622 tags_count = emit_tags_vector(arg, expr, &tags_impl_skip, 0);
vlmfa67ddc2004-06-03 03:38:44 +0000623
vlm4a3f5822004-06-28 21:13:46 +0000624 p = MKID(expr->Identifier);
vlmfa67ddc2004-06-03 03:38:44 +0000625 OUT("static asn1_SET_OF_specifics_t asn1_DEF_%s_specs = {\n", p);
626 INDENTED(
627 OUT("sizeof(struct %s),\n", p);
628 OUT("offsetof(struct %s, _ber_dec_ctx),\n", p);
629 OUT("asn1_DEF_%s_elements\n", p);
630 );
631 OUT("};\n");
632 OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
633 INDENTED(
634 OUT("\"%s\",\n", expr->Identifier);
635 if(seq_of) {
636 OUT("SEQUENCE_OF_constraint,\n");
637 OUT("SEQUENCE_OF_decode_ber,\n");
638 OUT("SEQUENCE_OF_encode_der,\n");
639 OUT("SEQUENCE_OF_print,\n");
640 OUT("SEQUENCE_OF_free,\n");
641 } else {
642 OUT("SET_OF_constraint,\n");
643 OUT("SET_OF_decode_ber,\n");
644 OUT("SET_OF_encode_der,\n");
645 OUT("SET_OF_print,\n");
646 OUT("SET_OF_free,\n");
647 }
648 OUT("0,\t/* Use generic outmost tag fetcher */\n");
vlm6e73a042004-08-11 07:17:22 +0000649 if(tags_count) {
650 OUT("asn1_DEF_%s_tags,\n", p);
651 OUT("sizeof(asn1_DEF_%s_tags)\n", p);
652 OUT("\t/sizeof(asn1_DEF_%s_tags[0]), /* %d */\n",
653 p, tags_count);
654 } else {
655 OUT("0,\t/* No explicit tags (pointer) */\n");
656 OUT("0,\t/* No explicit tags (count) */\n");
657 }
vlmfa67ddc2004-06-03 03:38:44 +0000658 OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
659 OUT("%d,\t/* Whether CONSTRUCTED */\n", 1);
660 OUT("&asn1_DEF_%s_specs\t/* Additional specs */\n", p);
661 );
662 OUT("};\n");
663 OUT("\n");
664
vlmfa67ddc2004-06-03 03:38:44 +0000665 REDIR(OT_TYPE_DECLS);
666
667 return 0;
668}
669
670int
671asn1c_lang_C_type_CHOICE(arg_t *arg) {
672 asn1p_expr_t *expr = arg->expr;
673 asn1p_expr_t *v;
674 char *p;
675
676 DEPENDENCIES;
677
vlm33a4ff12004-08-11 05:21:32 +0000678 REDIR(OT_DEPS);
679
vlmfa67ddc2004-06-03 03:38:44 +0000680 p = MKID(expr->Identifier);
vlm33a4ff12004-08-11 05:21:32 +0000681 OUT("typedef enum %s_PR {\n", p);
682 INDENTED(
683 p = MKID(expr->Identifier);
684 OUT("%s_PR_NOTHING,\t"
685 "/* No components present */\n", p);
686 TQ_FOR(v, &(expr->members), next) {
687 if(v->expr_type == A1TC_EXTENSIBLE) {
688 OUT("/* Extensions may appear below */\n");
689 continue;
690 }
691 p = MKID(expr->Identifier);
692 OUT("%s_PR_", p);
693 p = MKID(v->Identifier);
694 OUT("%s,\n", p, p);
695 }
696 );
697 p = MKID(expr->Identifier);
vlm6e73a042004-08-11 07:17:22 +0000698 OUT("} %s_PR;\n", p);
vlm33a4ff12004-08-11 05:21:32 +0000699
700 REDIR(OT_TYPE_DECLS);
vlmfa67ddc2004-06-03 03:38:44 +0000701
702 if(arg->embed) {
703 OUT("struct %s {\n", p);
704 } else {
705 OUT("typedef struct %s {\n", p);
706 }
707
708 INDENTED(
vlm6e73a042004-08-11 07:17:22 +0000709 OUT("%s_PR present;\n", p);
vlmfa67ddc2004-06-03 03:38:44 +0000710 OUT("union {\n", p);
711 TQ_FOR(v, &(expr->members), next) {
712 EMBED(v);
713 }
714 if(UNNAMED_UNIONS) OUT("};\n");
715 else OUT("} choice;\n");
716 );
717
718 PCTX_DEF;
719 OUT("} %s%s", expr->marker?"*":"", MKID(expr->Identifier));
720 if(arg->embed) OUT(";\n"); else OUT("_t;\n");
721
722 return asn1c_lang_C_type_CHOICE_def(arg);
723}
724
725static int
726asn1c_lang_C_type_CHOICE_def(arg_t *arg) {
727 asn1p_expr_t *expr = arg->expr;
728 asn1p_expr_t *v;
729 int elements; /* Number of elements */
730 int tags_impl_skip = 0;
731 int comp_mode = 0; /* {root,ext=1,root,root,...} */
vlmfa67ddc2004-06-03 03:38:44 +0000732 tag2el_t *tag2el = NULL;
733 int tag2el_count = 0;
vlm6e73a042004-08-11 07:17:22 +0000734 int tags_count;
vlmfa67ddc2004-06-03 03:38:44 +0000735 char *p;
736
737 /*
738 * Fetch every inner tag from the tag to elements map.
739 */
740 if(_fill_tag2el_map(arg, &tag2el, &tag2el_count, -1)) {
741 if(tag2el) free(tag2el);
742 return -1;
vlmfa67ddc2004-06-03 03:38:44 +0000743 }
744
vlm33a4ff12004-08-11 05:21:32 +0000745 GEN_INCLUDE("constr_CHOICE");
746 if(!arg->embed)
747 GEN_DECLARE(expr); /* asn1_DEF_xxx */
vlmfa67ddc2004-06-03 03:38:44 +0000748
vlm33a4ff12004-08-11 05:21:32 +0000749 REDIR(OT_STAT_DEFS);
vlmfa67ddc2004-06-03 03:38:44 +0000750
751 /*
752 * Print out the table according to which the parsing is performed.
753 */
754 p = MKID(expr->Identifier);
755 OUT("static asn1_CHOICE_element_t asn1_DEF_%s_elements[] = {\n", p);
756
757 elements = 0;
758 INDENTED(TQ_FOR(v, &(expr->members), next) {
759 if(v->expr_type != A1TC_EXTENSIBLE) {
760 if(comp_mode == 1)
761 v->marker = EM_OPTIONAL;
762 elements++;
763 } else {
764 if(comp_mode < 3) comp_mode++;
765 continue;
766 }
767 OUT("{ ");
768 p = MKID(expr->Identifier);
769 OUT("offsetof(struct %s, ", p);
770 p = MKID(v->Identifier);
771 if(!UNNAMED_UNIONS) OUT("choice.");
772 OUT("%s), ", p);
773 if(v->marker) {
774 OUT("1, /* Optional element */\n");
775 } else {
776 OUT("0,\n");
777 }
778 INDENT(+1);
779 if(C99_MODE) OUT(".tag = ");
780 _print_tag(arg, v, NULL);
781 OUT(",\n");
782 if(C99_MODE) OUT(".tag_mode = ");
783 if(v->tag.tag_class) {
784 if(v->tag.tag_mode == TM_IMPLICIT)
785 OUT("-1,\t/* IMPLICIT tag at current level */\n");
786 else
787 OUT("+1,\t/* EXPLICIT tag at current level */\n");
788 } else {
789 OUT("0,\n");
790 }
791 if(C99_MODE) OUT(".type = ");
792 OUT("(void *)&asn1_DEF_%s,\n",
793 asn1c_type_name(arg, v, TNF_SAFE));
794 if(C99_MODE) OUT(".name = ");
795 OUT("\"%s\"\n", v->Identifier);
796 OUT("},\n");
797 INDENT(-1);
798 });
799 OUT("};\n");
800
vlm6e73a042004-08-11 07:17:22 +0000801
vlmfa67ddc2004-06-03 03:38:44 +0000802 if(arg->embed) {
803 /*
804 * Our parent structure has already taken this into account.
805 */
vlm6e73a042004-08-11 07:17:22 +0000806 tags_count = 0;
vlmfa67ddc2004-06-03 03:38:44 +0000807 } else {
vlm6e73a042004-08-11 07:17:22 +0000808 tags_count = emit_tags_vector(arg, expr, &tags_impl_skip, 1);
vlmfa67ddc2004-06-03 03:38:44 +0000809 }
vlmfa67ddc2004-06-03 03:38:44 +0000810
811 /*
812 * Tags to elements map.
813 */
vlm4e03ce22004-06-06 07:20:17 +0000814 emit_tag2member_map(arg, tag2el, tag2el_count);
vlmfa67ddc2004-06-03 03:38:44 +0000815
vlm6e73a042004-08-11 07:17:22 +0000816 p = MKID(expr->Identifier);
vlmfa67ddc2004-06-03 03:38:44 +0000817 OUT("static asn1_CHOICE_specifics_t asn1_DEF_%s_specs = {\n", p);
818 INDENTED(
819 OUT("sizeof(struct %s),\n", p);
820 OUT("offsetof(struct %s, _ber_dec_ctx),\n", p);
821 OUT("offsetof(struct %s, present),\n", p);
822 OUT("sizeof(((struct %s *)0)->present),\n", p);
823 OUT("asn1_DEF_%s_elements,\n", p);
824 OUT("%d,\t/* Elements count */\n", elements);
825 OUT("asn1_DEF_%s_tag2el,\n", p);
826 OUT("%d,\t/* Count of tags in the map */\n", tag2el_count);
vlm79b08d52004-07-01 00:52:50 +0000827 OUT("%d\t/* Whether extensible */\n",
828 check_if_extensible(expr));
vlmfa67ddc2004-06-03 03:38:44 +0000829 );
830 OUT("};\n");
831 OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
832 INDENTED(
833 OUT("\"%s\",\n", expr->Identifier);
834 OUT("CHOICE_constraint,\n");
835 OUT("CHOICE_decode_ber,\n");
836 OUT("CHOICE_encode_der,\n");
837 OUT("CHOICE_print,\n");
838 OUT("CHOICE_free,\n");
839 OUT("CHOICE_outmost_tag,\n");
vlm6e73a042004-08-11 07:17:22 +0000840 if(tags_count) {
841 OUT("asn1_DEF_%s_tags,\n", p);
842 OUT("sizeof(asn1_DEF_%s_tags)\n", p);
843 OUT("\t/sizeof(asn1_DEF_%s_tags[0]), /* %d */\n",
844 p, tags_count);
845 } else {
846 OUT("0,\t/* No explicit tags (pointer) */\n");
847 OUT("0,\t/* No explicit tags (count) */\n");
848 }
vlmfa67ddc2004-06-03 03:38:44 +0000849 OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
850 OUT("%d,\t/* Whether CONSTRUCTED */\n", 1);
851 OUT("&asn1_DEF_%s_specs\t/* Additional specs */\n", p);
852 );
853 OUT("};\n");
854 OUT("\n");
855
vlmfa67ddc2004-06-03 03:38:44 +0000856 REDIR(OT_TYPE_DECLS);
857
858 return 0;
859}
860
861int
862asn1c_lang_C_type_REFERENCE(arg_t *arg) {
863 asn1p_ref_t *ref;
864
865 ref = arg->expr->reference;
866 if(ref->components[ref->comp_count-1].name[0] == '&') {
867 asn1p_module_t *mod;
868 asn1p_expr_t *extract;
869 arg_t tmp;
870 int ret;
871
872 extract = asn1f_class_access_ex(arg->asn, arg->mod, arg->expr,
873 ref, &mod);
874 if(extract == NULL)
875 return -1;
876
877 extract = asn1p_expr_clone(extract);
878 if(extract) {
879 if(extract->Identifier)
880 free(extract->Identifier);
881 extract->Identifier = strdup(arg->expr->Identifier);
882 if(extract->Identifier == NULL) {
883 asn1p_expr_free(extract);
884 return -1;
885 }
886 } else {
887 return -1;
888 }
889
890 tmp = *arg;
891 tmp.asn = arg->asn;
892 tmp.mod = mod;
893 tmp.expr = extract;
894
895 ret = arg->default_cb(&tmp);
896
897 asn1p_expr_free(extract);
898
899 return ret;
900 }
901
902
903 return asn1c_lang_C_type_SIMPLE_TYPE(arg);
904}
905
906int
907asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
908 asn1p_expr_t *expr = arg->expr;
909 int tags_impl_skip = 0;
vlm6e73a042004-08-11 07:17:22 +0000910 int tags_count;
vlmfa67ddc2004-06-03 03:38:44 +0000911 char *p;
912
913 if(arg->embed) {
914 REDIR(OT_TYPE_DECLS);
915
916 OUT("%s\t", asn1c_type_name(arg, arg->expr,
917 expr->marker?TNF_RSAFE:TNF_CTYPE));
918 OUT("%s", expr->marker?"*":" ");
919 OUT("%s;", MKID(expr->Identifier));
920 if(expr->marker) OUT("\t/* %s */",
921 (expr->marker==EM_OPTIONAL)?"OPTIONAL":"DEFAULT");
922 OUT("\n");
923 return 0;
924 }
925
vlmfa67ddc2004-06-03 03:38:44 +0000926
vlm33a4ff12004-08-11 05:21:32 +0000927 GEN_INCLUDE(asn1c_type_name(arg, expr, TNF_INCLUDE));
vlmfa67ddc2004-06-03 03:38:44 +0000928
929 REDIR(OT_TYPE_DECLS);
930
931 OUT("typedef %s\t", asn1c_type_name(arg, arg->expr, TNF_CTYPE));
932 OUT("%s", expr->marker?"*":" ");
933 OUT("%s_t;\n", MKID(expr->Identifier));
934 OUT("\n");
935
936 REDIR(OT_STAT_DEFS);
937
vlm4a3f5822004-06-28 21:13:46 +0000938 /*
939 * Print out asn1_DEF_<type>_tags[] vector.
940 */
vlm6e73a042004-08-11 07:17:22 +0000941 tags_count = emit_tags_vector(arg, expr, &tags_impl_skip, 0);
vlmfa67ddc2004-06-03 03:38:44 +0000942
vlm4a3f5822004-06-28 21:13:46 +0000943 p = MKID(expr->Identifier);
vlmfa67ddc2004-06-03 03:38:44 +0000944 OUT("asn1_TYPE_descriptor_t asn1_DEF_%s = {\n", p);
945 INDENTED(
946 OUT("\"%s\",\n", expr->Identifier);
947 OUT("%s_constraint,\n", p);
948 OUT("%s_decode_ber,\n", p);
949 OUT("%s_encode_der,\n", p);
950 OUT("%s_print,\n", p);
951 OUT("%s_free,\n", p);
952 OUT("0,\t/* Use generic outmost tag fetcher */\n");
vlm6e73a042004-08-11 07:17:22 +0000953 if(tags_count) {
954 OUT("asn1_DEF_%s_tags,\n", p);
955 OUT("sizeof(asn1_DEF_%s_tags)\n", p);
956 OUT("\t/sizeof(asn1_DEF_%s_tags[0]), /* %d */\n",
957 p, tags_count);
958 } else {
959 OUT("0,\t/* No explicit tags (pointer) */\n");
960 OUT("0,\t/* No explicit tags (count) */\n");
961 }
vlmfa67ddc2004-06-03 03:38:44 +0000962 OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
vlm94faa932004-06-05 08:46:50 +0000963 OUT("-0,\t/* Unknown yet */\n");
964 OUT("0\t/* No specifics */\n");
vlmfa67ddc2004-06-03 03:38:44 +0000965 );
966 OUT("};\n");
967 OUT("\n");
968
969 /*
970 * Constraint checking.
971 */
972 if(expr->constraints) /* Emit tables with FROM() constraints */
973 emit_alphabet_tables(arg, expr->constraints, 0);
974 p = MKID(expr->Identifier);
975 OUT("int\n");
976 OUT("%s_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,\n", p);
977 INDENTED(
978 OUT("\t\tasn_app_consume_bytes_f *app_errlog, void *app_key) {\n");
979 OUT("\n");
980 if(expr->constraints) {
981
982 emit_constraint_checking_code(arg);
983
984 OUT("/* Check the constraints of the underlying type */\n");
985 OUT("return asn1_DEF_%s.check_constraints\n",
986 asn1c_type_name(arg, expr, TNF_SAFE));
987 OUT("\t(td, sptr, app_errlog, app_key);\n");
988 } else {
989 OUT("/* Make the underlying type checker permanent */\n");
990 OUT("td->check_constraints = asn1_DEF_%s.check_constraints;\n",
991 asn1c_type_name(arg, expr, TNF_SAFE));
992 OUT("return td->check_constraints\n");
993 OUT("\t(td, sptr, app_errlog, app_key);\n");
994 }
995 );
996 OUT("}\n");
997 OUT("\n");
998
999 /*
1000 * Emit suicidal functions.
1001 */
1002
1003 {
1004 /*
1005 * This function replaces certain fields from the definition
1006 * of a type with the corresponding fields from the basic type
1007 * (from which the current type is inherited).
1008 */
1009 char *type_name = asn1c_type_name(arg, expr, TNF_SAFE);
1010 OUT("/*\n");
1011 OUT(" * This type is implemented using %s,\n", type_name);
1012 OUT(" * so adjust the DEF appropriately.\n");
1013 OUT(" */\n");
1014 OUT("static void\n");
1015 OUT("inherit_TYPE_descriptor(asn1_TYPE_descriptor_t *td) {\n");
1016 INDENT(+1);
1017 OUT("td->ber_decoder = asn1_DEF_%s.ber_decoder;\n", type_name);
1018 OUT("td->der_encoder = asn1_DEF_%s.der_encoder;\n", type_name);
1019 OUT("td->free_struct = asn1_DEF_%s.free_struct;\n", type_name);
1020 OUT("td->print_struct = asn1_DEF_%s.print_struct;\n", type_name);
1021 OUT("td->last_tag_form = asn1_DEF_%s.last_tag_form;\n", type_name);
1022 OUT("td->specifics = asn1_DEF_%s.specifics;\n", type_name);
1023 INDENT(-1);
1024 OUT("}\n");
1025 OUT("\n");
1026 }
1027
1028 p = MKID(expr->Identifier);
1029 OUT("ber_dec_rval_t\n");
1030 OUT("%s_decode_ber(asn1_TYPE_descriptor_t *td,\n", p);
1031 INDENTED(
1032 OUT("\tvoid **structure, void *bufptr, size_t size, int tag_mode) {\n");
1033 OUT("inherit_TYPE_descriptor(td);\n");
1034 OUT("return td->ber_decoder(td, structure,\n");
1035 OUT("\tbufptr, size, tag_mode);\n");
1036 );
1037 OUT("}\n");
1038 OUT("\n");
1039
1040 p = MKID(expr->Identifier);
1041 OUT("der_enc_rval_t\n");
1042 OUT("%s_encode_der(asn1_TYPE_descriptor_t *td,\n", p);
1043 INDENTED(
1044 OUT("\tvoid *structure, int tag_mode, ber_tlv_tag_t tag,\n");
1045 OUT("\tasn_app_consume_bytes_f *cb, void *app_key) {\n");
1046 OUT("inherit_TYPE_descriptor(td);\n");
1047 OUT("return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);\n");
1048 );
1049 OUT("}\n");
1050 OUT("\n");
1051
1052 p = MKID(expr->Identifier);
1053 OUT("int\n");
1054 OUT("%s_print(asn1_TYPE_descriptor_t *td, const void *struct_ptr,\n", p);
1055 INDENTED(
1056 OUT("\tint ilevel, asn_app_consume_bytes_f *cb, void *app_key) {\n");
1057 OUT("inherit_TYPE_descriptor(td);\n");
1058 OUT("return td->print_struct(td, struct_ptr, ilevel, cb, app_key);\n");
1059 );
1060 OUT("}\n");
1061 OUT("\n");
1062
1063 p = MKID(expr->Identifier);
1064 OUT("void\n");
1065 OUT("%s_free(asn1_TYPE_descriptor_t *td,\n", p);
1066 INDENTED(
1067 OUT("\tvoid *struct_ptr, int contents_only) {\n");
1068 OUT("inherit_TYPE_descriptor(td);\n");
1069 OUT("td->free_struct(td, struct_ptr, contents_only);\n");
1070 );
1071 OUT("}\n");
1072 OUT("\n");
1073
1074 REDIR(OT_FUNC_DECLS);
1075
1076 p = MKID(expr->Identifier);
1077 OUT("extern asn1_TYPE_descriptor_t asn1_DEF_%s;\n", p);
1078 OUT("asn_constr_check_f %s_constraint;\n", p);
1079 OUT("ber_type_decoder_f %s_decode_ber;\n", p);
1080 OUT("der_type_encoder_f %s_encode_der;\n", p);
1081 OUT("asn_struct_print_f %s_print;\n", p);
1082 OUT("asn_struct_free_f %s_free;\n", p);
1083
vlm33a4ff12004-08-11 05:21:32 +00001084 REDIR(OT_TYPE_DECLS);
1085
vlmfa67ddc2004-06-03 03:38:44 +00001086 return 0;
1087}
1088
1089int
1090asn1c_lang_C_type_EXTENSIBLE(arg_t *arg) {
1091
1092 OUT("/*\n");
1093 OUT(" * This type is extensible,\n");
1094 OUT(" * possible extensions are below.\n");
1095 OUT(" */\n");
1096
1097 return 0;
1098}
1099
vlm79b08d52004-07-01 00:52:50 +00001100static int check_if_extensible(asn1p_expr_t *expr) {
1101 asn1p_expr_t *v;
1102 TQ_FOR(v, &(expr->members), next) {
1103 if(v->expr_type == A1TC_EXTENSIBLE) return 1;
1104 }
1105 return 0;
1106}
1107
vlmfa67ddc2004-06-03 03:38:44 +00001108static int
1109_print_tag(arg_t *arg, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag_p) {
1110 struct asn1p_type_tag_s tag;
1111
1112 if(tag_p) {
1113 tag = *tag_p;
1114 } else {
1115 if(asn1f_fetch_tag(arg->asn, arg->mod, expr, &tag)) {
1116 OUT("-1 /* Ambiguous tag (CHOICE?) */");
1117 return 0;
1118 }
1119 }
1120
1121 OUT("(");
1122 switch(tag.tag_class) {
1123 case TC_UNIVERSAL: OUT("ASN_TAG_CLASS_UNIVERSAL"); break;
1124 case TC_APPLICATION: OUT("ASN_TAG_CLASS_APPLICATION"); break;
1125 case TC_CONTEXT_SPECIFIC: OUT("ASN_TAG_CLASS_CONTEXT"); break;
1126 case TC_PRIVATE: OUT("ASN_TAG_CLASS_PRIVATE"); break;
1127 case TC_NOCLASS:
1128 break;
1129 }
1130 OUT(" | (%lld << 2))", tag.tag_value);
1131
1132 return 0;
1133}
1134
vlm4e03ce22004-06-06 07:20:17 +00001135
1136static int
1137_tag2el_cmp(const void *ap, const void *bp) {
1138 const tag2el_t *a = ap;
1139 const tag2el_t *b = bp;
1140 const struct asn1p_type_tag_s *ta = &a->el_tag;
1141 const struct asn1p_type_tag_s *tb = &b->el_tag;
1142
1143 if(ta->tag_class == tb->tag_class) {
1144 if(ta->tag_value == tb->tag_value) {
1145 /*
1146 * Sort by their respective positions.
1147 */
1148 if(a->el_no < b->el_no)
1149 return -1;
1150 else if(a->el_no > b->el_no)
1151 return 1;
1152 return 0;
1153 } else if(ta->tag_value < tb->tag_value)
1154 return -1;
1155 else
1156 return 1;
1157 } else if(ta->tag_class < tb->tag_class) {
1158 return -1;
1159 } else {
1160 return 1;
1161 }
1162}
1163
vlmfa67ddc2004-06-03 03:38:44 +00001164/*
1165 * For constructed types, number of external tags may be greater than
1166 * number of elements in the type because of CHOICE type.
1167 * T ::= SET { -- Three possible tags:
1168 * a INTEGER, -- One tag is here...
1169 * b Choice1 -- ... and two more tags are there.
1170 * }
1171 * Choice1 ::= CHOICE {
1172 * s1 IA5String,
1173 * s2 ObjectDescriptor
1174 * }
1175 */
1176static int
1177_fill_tag2el_map(arg_t *arg, tag2el_t **tag2el, int *count, int el_no) {
1178 asn1p_expr_t *expr = arg->expr;
1179 arg_t tmparg = *arg;
1180 asn1p_expr_t *v;
1181 int element = 0;
1182
1183 TQ_FOR(v, &(expr->members), next) {
1184 if(v->expr_type == A1TC_EXTENSIBLE)
1185 continue;
1186
1187 tmparg.expr = v;
1188
1189 if(_add_tag2el_member(&tmparg, tag2el, count,
1190 (el_no==-1)?element:el_no)) {
1191 return -1;
1192 }
1193
1194 element++;
1195 }
1196
vlm4e03ce22004-06-06 07:20:17 +00001197 /*
vlmc8aeab42004-06-14 13:09:45 +00001198 * Sort the map according to canonical order of their tags
1199 * and element numbers.
vlm4e03ce22004-06-06 07:20:17 +00001200 */
1201 qsort(*tag2el, *count, sizeof(**tag2el), _tag2el_cmp);
1202
vlmc8aeab42004-06-14 13:09:45 +00001203 /*
1204 * Initialize .toff_{first|last} members.
1205 */
1206 if(*count) {
1207 struct asn1p_type_tag_s *cur_tag = 0;
1208 tag2el_t *cur = *tag2el;
1209 tag2el_t *end = cur + *count;
1210 int occur, i;
1211 for(occur = 0; cur < end; cur++) {
1212 if(cur_tag == 0
1213 || cur_tag->tag_value != cur->el_tag.tag_value
1214 || cur_tag->tag_class != cur->el_tag.tag_class) {
1215 cur_tag = &cur->el_tag;
1216 occur = 0;
1217 } else {
1218 occur++;
1219 }
1220 cur->toff_first = -occur;
1221 for(i = 0; i >= -occur; i--)
1222 cur[i].toff_last = -i;
1223 }
1224 }
1225
vlmfa67ddc2004-06-03 03:38:44 +00001226 return 0;
1227}
1228
1229static int
1230_add_tag2el_member(arg_t *arg, tag2el_t **tag2el, int *count, int el_no) {
1231 struct asn1p_type_tag_s tag;
1232 int ret;
1233
1234 assert(el_no >= 0);
1235
1236 ret = asn1f_fetch_tag(arg->asn, arg->mod, arg->expr, &tag);
1237 if(ret == 0) {
1238 void *p;
1239 p = realloc(*tag2el, sizeof(tag2el_t) * ((*count) + 1));
1240 if(p) *tag2el = p;
1241 else return -1;
1242
1243 DEBUG("Found tag for %s: %ld",
1244 arg->expr->Identifier,
1245 (long)tag.tag_value);
1246
1247 (*tag2el)[*count].el_tag = tag;
1248 (*tag2el)[*count].el_no = el_no;
1249 (*tag2el)[*count].from_expr = arg->expr;
1250 (*count)++;
1251 return 0;
1252 }
1253
1254 DEBUG("Searching tag in complex expression %s:%x at line %d",
1255 arg->expr->Identifier,
1256 arg->expr->expr_type,
1257 arg->expr->_lineno);
1258
1259 /*
1260 * Iterate over members of CHOICE type.
1261 */
1262 if(arg->expr->expr_type == ASN_CONSTR_CHOICE) {
1263 return _fill_tag2el_map(arg, tag2el, count, el_no);
1264 }
1265
1266 if(arg->expr->expr_type == A1TC_REFERENCE) {
1267 arg_t tmp = *arg;
1268 asn1p_expr_t *expr;
1269 expr = asn1f_lookup_symbol_ex(tmp.asn, &tmp.mod, tmp.expr,
1270 arg->expr->reference);
1271 if(expr) {
1272 tmp.expr = expr;
1273 return _add_tag2el_member(&tmp, tag2el, count, el_no);
1274 } else {
1275 FATAL("Cannot dereference %s at line %d",
1276 arg->expr->Identifier,
1277 arg->expr->_lineno);
1278 return -1;
1279 }
1280 }
1281
1282 DEBUG("No tag for %s at line %d",
1283 arg->expr->Identifier,
1284 arg->expr->_lineno);
1285
1286 return -1;
1287}
1288
1289static int
vlm4e03ce22004-06-06 07:20:17 +00001290emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count) {
1291 asn1p_expr_t *expr = arg->expr;
1292
1293 OUT("static asn1_TYPE_tag2member_t asn1_DEF_%s_tag2el[] = {\n",
1294 MKID(expr->Identifier));
1295 if(tag2el_count) {
1296 int i;
1297 for(i = 0; i < tag2el_count; i++) {
1298 OUT(" { ");
1299 _print_tag(arg, expr, &tag2el[i].el_tag);
1300 OUT(", ");
vlmc8aeab42004-06-14 13:09:45 +00001301 OUT("%d, ", tag2el[i].el_no);
1302 OUT("%d, ", tag2el[i].toff_first);
1303 OUT("%d ", tag2el[i].toff_last);
vlm4e03ce22004-06-06 07:20:17 +00001304 OUT("}, /* %s at %d */\n",
1305 tag2el[i].from_expr->Identifier,
1306 tag2el[i].from_expr->_lineno
1307 );
1308 }
1309 }
1310 OUT("};\n");
1311
1312 return 0;;
1313}
1314
1315static int
vlm6e73a042004-08-11 07:17:22 +00001316emit_tags_vector(arg_t *arg, asn1p_expr_t *expr, int *tags_impl_skip, int choice_mode) {
1317 int tags_count = 0;
1318 int save_target = arg->target->target;
vlm4a3f5822004-06-28 21:13:46 +00001319 char *p;
1320
vlm6e73a042004-08-11 07:17:22 +00001321 if(save_target != OT_IGNORE) {
1322 int save_impl_skip = *tags_impl_skip;
1323 REDIR(OT_IGNORE);
1324 tags_count = emit_tags_vector(arg, expr,
1325 tags_impl_skip, choice_mode);
1326 REDIR(save_target);
1327 if(tags_count) {
1328 *tags_impl_skip = save_impl_skip;
1329 tags_count = 0;
1330 } else {
1331 return 0;
1332 }
1333 }
1334
1335
vlm4a3f5822004-06-28 21:13:46 +00001336 p = MKID(expr->Identifier);
1337 OUT("static ber_tlv_tag_t asn1_DEF_%s_tags[] = {\n", p);
1338 INDENTED(
1339 if(expr->tag.tag_class) {
vlm6e73a042004-08-11 07:17:22 +00001340 tags_count++;
vlm4a3f5822004-06-28 21:13:46 +00001341 _print_tag(arg, expr, &expr->tag);
1342 if(expr->tag.tag_mode != TM_EXPLICIT)
1343 (*tags_impl_skip)++;
1344 } else {
vlm6e73a042004-08-11 07:17:22 +00001345 if(!choice_mode)
1346 (*tags_impl_skip)++;
vlm4a3f5822004-06-28 21:13:46 +00001347 }
vlm6e73a042004-08-11 07:17:22 +00001348 if(!choice_mode) {
1349 if(!expr->tag.tag_class
1350 || (expr->meta_type == AMT_TYPE
1351 && expr->tag.tag_mode == TM_EXPLICIT)) {
1352 struct asn1p_type_tag_s tag;
1353 if(expr->tag.tag_class)
1354 OUT(",\n");
1355 tag.tag_class = TC_UNIVERSAL;
1356 tag.tag_mode = TM_IMPLICIT;
1357 tag.tag_value = expr_type2uclass_value[expr->expr_type];
1358 _print_tag(arg, expr, &tag);
1359 tags_count++;
1360 }
vlm4a3f5822004-06-28 21:13:46 +00001361 }
1362 OUT("\n");
1363 );
1364 OUT("};\n");
1365
vlm6e73a042004-08-11 07:17:22 +00001366 return tags_count;
vlm4a3f5822004-06-28 21:13:46 +00001367}
1368
1369static int
vlmfa67ddc2004-06-03 03:38:44 +00001370emit_constraint_checking_code(arg_t *arg) {
1371 asn1p_expr_t *expr = arg->expr;
1372 asn1p_expr_type_e etype;
1373 int size_present, value_present;
1374
1375 if(expr->constraints == NULL)
1376 return 0; /* No constraints defined */
1377
1378 etype = _find_terminal_type(arg);
1379
1380 size_present = check_constraint_type_presence(expr->constraints,
1381 ACT_CT_SIZE);
1382 value_present = check_constraint_type_presence(expr->constraints,
1383 ACT_EL_VALUE);
1384
1385 if(size_present || value_present) {
vlmaaec3ef2004-06-03 04:35:44 +00001386 OUT("const %s_t *st = sptr;\n", MKID(arg->expr->Identifier));
vlmfa67ddc2004-06-03 03:38:44 +00001387 if(size_present) {
1388 OUT("size_t size;\n");
1389 OUT("size_t min_size __attribute__ ((unused)) = %ld;\n",
1390 compute_min_size(arg));
1391 OUT("size_t max_size __attribute__ ((unused)) = %ld;\n",
1392 compute_max_size(arg));
1393 }
1394 if(value_present)
1395 switch(etype) {
1396 case ASN_BASIC_INTEGER:
1397 case ASN_BASIC_ENUMERATED:
1398 OUT("long value;\n");
1399 break;
1400 case ASN_BASIC_BOOLEAN:
1401 OUT("int value;\n");
1402 break;
1403 default:
1404 break;
1405 }
1406 OUT("\n");
1407 }
1408
1409 OUT("if(!sptr) {\n");
1410 INDENT(+1);
vlm1b247ee2004-08-12 07:56:02 +00001411 OUT("_ASN_ERRLOG(app_errlog, app_key,\n");
1412 OUT("\t\"%%s: value not given\", td->name);\n");
vlmfa67ddc2004-06-03 03:38:44 +00001413 OUT("return -1;\n");
1414 INDENT(-1);
1415 OUT("}\n");
1416 OUT("\n");
1417
1418 if(size_present)
1419 emit_size_determination_code(arg);
1420 if(value_present)
1421 emit_value_determination_code(arg);
1422
1423 OUT("\n");
1424 OUT("if(\n");
1425 emit_single_constraint_check(arg, expr->constraints, 0);
1426 OUT(") {\n");
1427 INDENTED(OUT("/* Constraint check succeeded */\n"));
1428 OUT("} else {\n");
1429 INDENT(+1);
vlm1b247ee2004-08-12 07:56:02 +00001430 OUT("_ASN_ERRLOG(app_errlog, app_key,\n");
1431 OUT("\t\"%%s: constraint failed\", td->name);\n");
vlmfa67ddc2004-06-03 03:38:44 +00001432 OUT("return -1;\n");
1433 INDENT(-1);
1434 OUT("}\n");
1435
1436 return 0;
1437}
1438
1439static int
1440emit_single_constraint_check(arg_t *arg, asn1p_constraint_t *ct, int mode) {
1441 char *s_v;
1442 int el;
1443
1444 assert(arg && ct);
1445
1446 switch(ct->type) {
1447 case ACT_INVALID:
1448 assert(ct->type != ACT_INVALID);
1449 OUT("-1 /* Invalid constraint at line %d */\n", ct->_lineno);
1450 break;
1451 case ACT_EL_VALUE:
1452 OUT("(");
1453 if(mode == ACT_CT_SIZE) s_v = "size";
1454 else s_v = "value";
1455 OUT("%s", s_v);
1456 if(ct->value->type != ATV_TRUE)
1457 OUT(" == ");
1458 switch(ct->value->type) {
1459 case ATV_INTEGER: OUT("%lld",
1460 (long long)ct->value->value.v_integer); break;
1461 case ATV_MIN: OUT("min_%s", s_v); break;
1462 case ATV_MAX: OUT("max_%s", s_v); break;
1463 case ATV_FALSE: OUT("0"); break;
1464 case ATV_TRUE: break;
1465 default:
1466 break;
1467 }
1468 OUT(")\n");
1469 break;
1470 case ACT_EL_RANGE:
1471 case ACT_EL_LLRANGE:
1472 case ACT_EL_RLRANGE:
1473 case ACT_EL_ULRANGE:
1474 if(mode == ACT_CT_SIZE) {
1475 s_v = "size";
1476 } else {
1477 s_v = "value";
1478 }
1479 OUT("((%s", s_v);
1480 switch(ct->type) {
1481 case ACT_EL_RANGE:
1482 case ACT_EL_RLRANGE:
1483 OUT(" >= "); break;
1484 case ACT_EL_LLRANGE:
1485 case ACT_EL_ULRANGE:
1486 OUT(" > "); break;
1487 default: break;
1488 }
1489 switch(ct->range_start->type) {
1490 case ATV_INTEGER: OUT("%lld",
1491 (long long)ct->range_start->value.v_integer); break;
1492 case ATV_MIN: OUT("min_%s", s_v); break;
1493 case ATV_MAX: OUT("max_%s", s_v); break;
1494 case ATV_FALSE: OUT("0"); break;
1495 case ATV_TRUE: break;
1496 default:
1497 break;
1498 }
1499 OUT(") && (%s", s_v);
1500 switch(ct->type) {
1501 case ACT_EL_RANGE:
1502 case ACT_EL_LLRANGE:
1503 OUT(" <= "); break;
1504 case ACT_EL_RLRANGE:
1505 case ACT_EL_ULRANGE:
1506 OUT(" < "); break;
1507 default: break;
1508 }
1509 switch(ct->range_stop->type) {
1510 case ATV_INTEGER: OUT("%lld",
1511 (long long)ct->range_stop->value.v_integer); break;
1512 case ATV_MIN: OUT("min_%s", s_v); break;
1513 case ATV_MAX: OUT("max_%s", s_v); break;
1514 case ATV_FALSE: OUT("0"); break;
1515 case ATV_TRUE: break;
1516 default:
1517 break;
1518 }
1519 OUT("))\n");
1520 break;
1521 case ACT_EL_EXT:
1522 OUT("0 /* Extensible (...), but not defined herein */\n");
1523 break;
1524 case ACT_CT_SIZE:
1525 if(mode) {
1526 OUT("0 /* Invalid constraint at line %d */\n",
1527 ct->_lineno);
1528 return -1;
1529 }
1530 assert(ct->el_count == 1);
1531 return emit_single_constraint_check(arg,
1532 ct->elements[0], ACT_CT_SIZE);
1533 case ACT_CT_FROM:
1534 if(mode) {
1535 OUT("0 /* Invalid constraint at line %d */\n",
1536 ct->_lineno);
1537 return -1;
1538 }
1539 OUT("check_alphabet_%x(sptr)\n", ct);
1540 break;
1541 case ACT_CT_WCOMP:
1542 case ACT_CT_WCOMPS:
1543 OUT("%d /* Unsupported constraint at line %d */\n",
1544 ct->type, ct->_lineno);
1545 return -1;
1546 break;
1547 case ACT_CA_SET:
1548 OUT("(\n");
1549 INDENT(+1);
1550 for(el = 0; el < ct->el_count; el++) {
1551 if(el) OUT("&& ");
1552 emit_single_constraint_check(arg,
1553 ct->elements[el], mode);
1554 }
1555 INDENT(-1);
1556 OUT(")\n");
1557 break;
1558 case ACT_CA_CSV:
1559 OUT("(\n");
1560 INDENT(+1);
1561 for(el = 0; el < ct->el_count; el++) {
1562 if(el) OUT("|| ");
1563 emit_single_constraint_check(arg,
1564 ct->elements[el], mode);
1565 }
1566 INDENT(-1);
1567 OUT(")\n");
1568 break;
1569 case ACT_CA_UNI:
1570 OUT("(\n");
1571 INDENT(+1);
1572 for(el = 0; el < ct->el_count; el++) {
1573 if(el) OUT("|| ");
1574 emit_single_constraint_check(arg,
1575 ct->elements[el], mode);
1576 }
1577 INDENT(-1);
1578 OUT(")\n");
1579 break;
1580 case ACT_CA_INT:
1581 OUT("(\n");
1582 INDENT(+1);
1583 for(el = 0; el < ct->el_count; el++) {
1584 if(el) OUT("&& ");
1585 emit_single_constraint_check(arg,
1586 ct->elements[el], mode);
1587 }
1588 INDENT(-1);
1589 OUT(")\n");
1590 break;
1591 case ACT_CA_CRC:
1592 WARNING("Unsupported component relation constraint at line %d",
1593 ct->_lineno);
1594 OUT("%d /* Unsupported component relation constraint "
1595 "at line %d */\n",
1596 ct->type, ct->_lineno);
1597 return -1;
1598 case ACT_CA_EXC:
1599 WARNING("Unsupported EXCEPT constraint at line %d",
1600 ct->_lineno);
1601 OUT("%d /* Unsupported EXCEPT constraint at line %d */\n",
1602 ct->type, ct->_lineno);
1603 return -1;
1604 }
1605
1606 return 0;
1607}
1608
1609static int
1610check_constraint_type_presence(asn1p_constraint_t *ct, enum asn1p_constraint_type_e type) {
1611 int el;
1612
1613 if(ct == NULL) return 0;
1614
1615 if(ct->type == type) return 1;
1616
1617 if(type == ACT_EL_VALUE) {
1618 if(ct->type >= ACT_CT_SIZE
1619 && ct->type <= ACT_CT_WCOMPS)
1620 /* Values defined further
1621 * are not really value's values */
1622 return 0;
1623 if(ct->type > ACT_EL_VALUE && ct->type < ACT_CT_SIZE)
1624 return 1; /* Also values */
1625 }
1626
1627 for(el = 0; el < ct->el_count; el++) {
1628 if(check_constraint_type_presence(ct->elements[el], type))
1629 return 1;
1630 }
1631
1632 return 0;
1633}
1634
1635static int
1636emit_alphabet_tables(arg_t *arg, asn1p_constraint_t *ct, int *table) {
1637 int ch = 0;
1638 int ch_start = 0;
1639 int ch_stop = 0;
1640 int el = 0;
1641
1642 assert(arg && ct);
1643
1644 switch(ct->type) {
1645 case ACT_INVALID:
1646 break;
1647 case ACT_EL_VALUE:
1648 if(!table) break;
1649
1650 switch(ct->value->type) {
1651 case ATV_INTEGER:
1652 if(ct->value->value.v_integer < 0
1653 || ct->value->value.v_integer > 255) {
1654 OUT("\n");
1655 OUT("#error Value %lld out of range "
1656 "for alphabet character at line %d\n",
1657 (long long)ct->value->value.v_integer,
1658 ct->_lineno);
1659 break;
1660 } else {
1661 ch = ct->value->value.v_integer;
1662 table[ch] = 1;
1663 }
1664 break;
1665 case ATV_STRING:
1666 for(ch = 0; ch < ct->value->value.string.size; ch++)
1667 table[ct->value->value.string.buf[ch]] = 1;
1668 break;
1669 default:
1670 OUT("\n");
1671 WARNING("Invalid alphabet character specification "
1672 "at line %d", ct->_lineno);
1673 OUT("#error Invalid alphabet character specification "
1674 "at line %d\n", ct->_lineno);
1675 break;
1676 }
1677 break;
1678 case ACT_EL_RANGE:
1679 case ACT_EL_LLRANGE:
1680 case ACT_EL_RLRANGE:
1681 case ACT_EL_ULRANGE:
1682 if(!table) break;
1683
1684 ch_start = 0;
1685 ch_stop = 255;
1686
1687 switch(ct->range_start->type) {
1688 case ATV_INTEGER:
1689 ch_start = ct->range_start->value.v_integer; break;
1690 case ATV_MIN: ch_start = 0; break;
1691 case ATV_MAX: ch_start = 255; break;
1692 case ATV_STRING:
1693 if(ct->range_start->value.string.size == 1) {
1694 ch_start = ct->range_start->value.string.buf[0];
1695 break;
1696 }
1697 /* Fall through */
1698 default:
1699 OUT("\n");
1700 FATAL("Invalid alphabet range constraint "
1701 "at line %d\n", ct->_lineno);
1702 OUT("#error Invalid alphabet range constraint "
1703 "at line %d\n", ct->_lineno);
1704 return -1;
1705 }
1706
1707 switch(ct->range_stop->type) {
1708 case ATV_INTEGER:
1709 ch_stop = ct->range_stop->value.v_integer; break;
1710 case ATV_MIN: ch_stop = 0; break;
1711 case ATV_MAX: ch_stop = 255; break;
1712 case ATV_STRING:
1713 if(ct->range_stop->value.string.size == 1) {
1714 ch_stop = ct->range_stop->value.string.buf[0];
1715 break;
1716 }
1717 /* Fall through */
1718 default:
1719 OUT("\n");
1720 FATAL("Invalid alphabet range constraint "
1721 "at line %d\n", ct->_lineno);
1722 OUT("#error Invalid alphabet range constraint "
1723 "at line %d\n", ct->_lineno);
1724 break;
1725 }
1726
1727 switch(ct->type) {
1728 case ACT_EL_RANGE: break;
1729 case ACT_EL_RLRANGE: ch_stop--; break;
1730 case ACT_EL_LLRANGE: ch_start++; break;
1731 case ACT_EL_ULRANGE: ch_start++; ch_stop--; break;
1732 default: break;
1733 }
1734
1735 if(ch_start > ch_stop) {
1736 WARNING("Empty character range "
1737 "alphabet constraint at line %d", ct->_lineno);
vlm4a3f5822004-06-28 21:13:46 +00001738 OUT_NOINDENT("#warning Empty character range "
vlmfa67ddc2004-06-03 03:38:44 +00001739 "alphabet constraint at line %d\n", ct->_lineno);
1740 break;
1741 }
1742
1743 for(ch = ch_start; ch <= ch_stop; ch++) {
1744 if(ch < 0 || ch > 255) continue;
1745 table[ch] = 1;
1746 }
1747
1748 break;
1749 case ACT_EL_EXT:
1750 break;
1751 case ACT_CT_SIZE:
1752 break;
1753 case ACT_CT_FROM:
1754 if(table) {
1755 OUT("#error Nested FROM in subtype constraints\n");
1756 return -1;
1757 } else {
1758 table = alloca(256 * sizeof(table[0]));
1759 memset(table, 0, 256 * sizeof(table[0]));
1760
1761 for(el = 0; el < ct->el_count; el++) {
1762 emit_alphabet_tables(arg, ct->elements[el],
1763 table);
1764 }
1765 OUT("static int alphabet_table_%x[256] = {\n", ct);
1766 for(ch = 0; ch < 256; ch++) {
1767 OUT("%d,", table[ch]?1:0);
1768 if(!((ch+1) % 16)) {
1769 if(ch) {
1770 int c;
1771 OUT("\t/* ");
1772 for(c = ch - 16; c < ch; c++) {
1773 if(table[c]) {
1774 if(c > 0x20
1775 && c < 0x80)
1776 OUT("%c", c);
1777 else
1778 OUT(".", c);
1779 } else {
1780 OUT(" ");
1781 }
1782 }
1783 OUT(" */");
1784 }
1785 OUT("\n");
1786 }
1787 }
1788 OUT("};\n");
vlm27c7df02004-06-03 05:18:55 +00001789 OUT("static int check_alphabet_%x(const void *sptr) {\n", ct);
vlmfa67ddc2004-06-03 03:38:44 +00001790 INDENT(+1);
1791 OUT("int *table = alphabet_table_%x;\n", ct);
1792 emit_alphabet_check_cycle(arg);
1793 OUT("return 1;\n");
1794 INDENT(-1);
1795 OUT("};\n");
1796 }
1797 break;
1798 case ACT_CT_WCOMP:
1799 case ACT_CT_WCOMPS:
1800 break;
1801 case ACT_CA_CRC:
1802 break;
1803 case ACT_CA_SET:
1804 case ACT_CA_CSV:
1805 case ACT_CA_UNI:
1806 for(el = 0; el < ct->el_count; el++)
1807 emit_alphabet_tables(arg, ct->elements[el], table);
1808 break;
1809 case ACT_CA_INT:
1810 if(table) {
1811 int table2[256];
1812
1813 assert(ct->el_count >= 1);
1814 emit_alphabet_tables(arg, ct->elements[0], table);
1815 for(el = 1; el < ct->el_count; el++) {
1816 memset(table2, 0, sizeof(table2));
1817 emit_alphabet_tables(arg,
1818 ct->elements[el], table2);
1819 /* Intersection */
1820 for(ch = 0; ch < 256; ch++) {
1821 if(table2[ch] == 0)
1822 table[ch] = 0;
1823 }
1824 }
1825 } else {
1826 for(el = 0; el < ct->el_count; el++)
1827 emit_alphabet_tables(arg, ct->elements[el], 0);
1828 }
1829
1830 break;
1831 case ACT_CA_EXC:
1832 OUT("EXC\n");
1833 if(table) {
1834 int table2[256];
1835
1836 assert(ct->el_count >= 1);
1837 emit_alphabet_tables(arg, ct->elements[0], table);
1838 for(el = 1; el < ct->el_count; el++) {
1839 memset(table2, 0, sizeof(table2));
1840 emit_alphabet_tables(arg,
1841 ct->elements[el], table2);
1842 /* Exclusion */
1843 for(ch = 0; ch < 256; ch++) {
1844 if(table2[ch])
1845 table[ch] = 0;
1846 }
1847 }
1848 } else {
1849 for(el = 0; el < ct->el_count; el++)
1850 emit_alphabet_tables(arg, ct->elements[el], 0);
1851 }
1852 break;
1853 }
1854
1855 return 0;
1856}
1857
1858static int
1859emit_alphabet_check_cycle(arg_t *arg) {
1860 asn1p_expr_type_e etype;
1861
1862 etype = _find_terminal_type(arg);
1863 if(!(etype & ASN_STRING_MASK)
1864 && !(etype == ASN_BASIC_OCTET_STRING)) {
1865 OUT("#error Cannot apply FROM constraint to ASN.1 type %s\n",
1866 ASN_EXPR_TYPE2STR(etype));
1867 return -1;
1868 }
1869
1870 OUT("/* The underlying type is %s */\n",
1871 ASN_EXPR_TYPE2STR(etype));
vlmaaec3ef2004-06-03 04:35:44 +00001872 OUT("const %s_t *st = sptr;\n", MKID(arg->expr->Identifier));
vlmfa67ddc2004-06-03 03:38:44 +00001873
1874 switch(etype) {
1875 case ASN_STRING_UTF8String:
1876 OUT("uint8_t *ch = st->buf;\n");
1877 OUT("uint8_t *end = ch + st->size;\n");
1878 OUT("\n");
1879 OUT("for(; ch < end; ch++) {\n");
1880 INDENT(+1);
1881 OUT("if(*ch >= 0x80 || !table[*ch]) return 0;\n");
1882 INDENT(-1);
1883 OUT("}\n");
1884 break;
1885 case ASN_STRING_UniversalString:
1886 OUT("uint32_t *ch = st->buf;\n");
1887 OUT("uint32_t *end = ch + st->size;\n");
1888 OUT("\n");
1889 OUT("for(; ch < end; ch++) {\n");
1890 INDENT(+1);
1891 OUT("uint32_t wc = (((uint8_t *)ch)[0] << 24)\n");
1892 OUT("\t\t| (((uint8_t *)ch)[1] << 16)\n");
1893 OUT("\t\t| (((uint8_t *)ch)[2] << 8)\n");
1894 OUT("\t\t| ((uint8_t *)ch)[3]\n");
1895 OUT("if(wc > 255 || !table[wc]) return 0;\n");
1896 INDENT(-1);
1897 OUT("}\n");
1898 OUT("if(ch != end) return 0; /* (size%4)! */\n");
1899 break;
1900 case ASN_STRING_BMPString:
1901 OUT("uint16_t *ch = st->buf;\n");
1902 OUT("uint16_t *end = ch + st->size;\n");
1903 OUT("\n");
1904 OUT("for(; ch < end; ch++) {\n");
1905 INDENT(+1);
1906 OUT("uint16_t wc = (((uint8_t *)ch)[0] << 8)\n");
1907 OUT("\t\t| ((uint8_t *)ch)[1];\n");
1908 OUT("if(wc > 255 || !table[wc]) return 0;\n");
1909 INDENT(-1);
1910 OUT("}\n");
1911 OUT("if(ch != end) return 0; /* (size%2)! */\n");
1912 break;
1913 case ASN_BASIC_OCTET_STRING:
1914 default:
1915 OUT("uint8_t *ch = st->buf;\n");
1916 OUT("uint8_t *end = ch + st->size;\n");
1917 OUT("\n");
1918 OUT("for(; ch < end; ch++) {\n");
1919 INDENT(+1);
1920 OUT("if(!table[*ch]) return 0;\n");
1921 INDENT(-1);
1922 OUT("}\n");
1923 break;
1924 }
1925
1926 return 0;
1927}
1928
1929static int
1930emit_size_determination_code(arg_t *arg) {
1931 asn1p_expr_type_e etype = _find_terminal_type(arg);
1932
1933 switch(etype) {
1934 case ASN_BASIC_BIT_STRING:
1935 OUT("if(st->size > 0) {\n");
1936 OUT("\t/* Size in bits */\n");
1937 OUT("\tsize = (st->size - 1) - (st->buf[0] & 0x7);\n");
1938 OUT("} else {\n");
1939 OUT("\tsize = 0;\n");
1940 OUT("}\n");
1941 break;
1942 case ASN_STRING_UniversalString:
1943 OUT("size = st->size >> 2;\t/* 4 byte per character */\n");
1944 break;
1945 case ASN_STRING_BMPString:
1946 OUT("size = st->size >> 1;\t/* 2 byte per character */\n");
1947 break;
1948 case ASN_STRING_UTF8String:
1949 OUT("size = UTF8String_length(st, td->name, app_errlog, app_key);\n");
1950 OUT("if(size == (size_t)-1) return -1;\n");
1951 break;
1952 default:
1953 if((etype & ASN_STRING_MASK)
1954 || etype == ASN_BASIC_OCTET_STRING) {
1955 OUT("size = st->size;\n");
1956 break;
1957 } else {
vlm4a3f5822004-06-28 21:13:46 +00001958 const char *type_name = ASN_EXPR_TYPE2STR(etype);
1959 if(!type_name) type_name = arg->expr->Identifier;
1960 WARNING("SIZE constraint is not defined for %s",
1961 type_name);
1962 OUT_NOINDENT("#warning SIZE constraint "
1963 "not defined for %s!\n", type_name);
vlmfa67ddc2004-06-03 03:38:44 +00001964 OUT("size = st->size;\n");
1965 }
1966 return -1;
1967 }
1968
1969 return 0;
1970}
1971
1972static int
1973emit_value_determination_code(arg_t *arg) {
1974 asn1p_expr_type_e etype = _find_terminal_type(arg);
1975
1976 switch(etype) {
1977 case ASN_BASIC_INTEGER:
1978 case ASN_BASIC_ENUMERATED:
vlm6e73a042004-08-11 07:17:22 +00001979 if(arg->flags & A1C_USE_NATIVE_INTEGERS) {
1980 OUT("value = *(int *)st;\n");
1981 } else {
1982 OUT("if(asn1_INTEGER2long(st, &value)) {\n");
1983 INDENT(+1);
vlm1b247ee2004-08-12 07:56:02 +00001984 OUT("_ASN_ERRLOG(app_errlog, app_key,\n");
1985 OUT("\t\"%%s: value too large\", td->name);\n");
vlm6e73a042004-08-11 07:17:22 +00001986 OUT("return -1;\n");
1987 INDENT(-1);
1988 OUT("}\n");
1989 }
vlmfa67ddc2004-06-03 03:38:44 +00001990 break;
1991 case ASN_BASIC_BOOLEAN:
1992 OUT("value = st->value;\n");
1993 break;
1994 default:
1995 WARNING("Value cannot be determined "
1996 "for constraint check for %s at line %d\n",
1997 arg->expr->Identifier, arg->expr->_lineno);
1998 OUT("#error Value cannot be determined for %s at %d\n",
1999 arg->expr->Identifier, arg->expr->_lineno);
2000 break;
2001 }
2002
2003 return 0;
2004}
2005
2006static long compute_min_size(arg_t *arg) { return compute_xxx_size(arg, 0); }
2007static long compute_max_size(arg_t *arg) { return compute_xxx_size(arg, 1); }
2008
2009static long compute_xxx_size(arg_t *arg, int _max) {
2010 asn1p_expr_type_e etype;
2011 long basic_max = 0x7fffffff;
2012 long basic_min = 0x80000000;
2013 long svalue = 0;
2014
2015 etype = _find_terminal_type(arg);
2016 switch(etype) {
2017 case ASN_BASIC_BIT_STRING:
2018 svalue = _max?basic_max/8:0;
2019 break;
2020 case ASN_STRING_UTF8String:
2021 svalue = _max?basic_max/6:0;
2022 break;
2023 case ASN_STRING_UniversalString:
2024 svalue = _max?basic_max/4:0;
2025 break;
2026 case ASN_STRING_BMPString:
2027 svalue = _max?basic_max/2:0;
2028 break;
2029 case ASN_BASIC_OCTET_STRING:
2030 svalue = _max?basic_max:0;
2031 break;
2032 default:
2033 if((etype & ASN_STRING_MASK)) {
2034 svalue = _max?basic_max:0;
2035 break;
2036 }
2037 svalue = _max?basic_max:basic_min;
2038 break;
2039 }
2040
2041 return svalue;
2042}
2043
2044static asn1p_expr_type_e
2045_find_terminal_type(arg_t *arg) {
2046 asn1p_expr_t *expr;
2047 expr = asn1f_find_terminal_type_ex(arg->asn, arg->mod, arg->expr, NULL);
vlm4a3f5822004-06-28 21:13:46 +00002048 if(expr) return expr->expr_type;
2049 return A1TC_INVALID;
vlmfa67ddc2004-06-03 03:38:44 +00002050}
vlm79b08d52004-07-01 00:52:50 +00002051