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? ;)
5 #include "asn1c_internal.h"
7 #include "asn1c_constraint.h"
9 #include "asn1c_misc.h"
10 #include "asn1c_ioc.h"
11 #include "asn1c_naming.h"
12 #include <asn1print.h>
13 #include <asn1fix_crange.h> /* constraint groker from libasn1fix */
14 #include <asn1fix_export.h> /* other exportables from libasn1fix */
15 #include <asn1parser.h>
17 typedef struct tag2el_s {
18 struct asn1p_type_tag_s el_tag;
22 asn1p_expr_t *from_expr;
29 static int _fill_tag2el_map(arg_t *arg, tag2el_t **tag2el, int *count, int el_no, fte_e flags);
30 static int _add_tag2el_member(arg_t *arg, tag2el_t **tag2el, int *count, int el_no, fte_e flags);
34 ONC_avoid_keywords = 0x01,
35 ONC_force_compound_name = 0x02,
37 static int out_name_chain(arg_t *arg, enum onc_flags);
38 static int asn1c_lang_C_type_SEQUENCE_def(
39 arg_t *arg, asn1c_ioc_table_and_objset_t *);
40 static int asn1c_lang_C_type_SET_def(arg_t *arg);
41 static int asn1c_lang_C_type_CHOICE_def(arg_t *arg);
42 static int asn1c_lang_C_type_SEx_OF_def(arg_t *arg, int seq_of);
43 static int asn1c_lang_C_OpenType(arg_t *arg, asn1c_ioc_table_and_objset_t *opt_ioc, const char *column_name);
44 static int _print_tag(arg_t *arg, struct asn1p_type_tag_s *tag_p);
45 static int compute_extensions_start(asn1p_expr_t *expr);
46 static int expr_break_recursion(arg_t *arg, asn1p_expr_t *expr);
47 static int expr_as_xmlvaluelist(arg_t *arg, asn1p_expr_t *expr);
48 static int expr_elements_count(arg_t *arg, asn1p_expr_t *expr);
49 static int emit_single_member_OER_constraint_value(arg_t *arg, asn1cnst_range_t *range);
50 static int emit_single_member_OER_constraint_size(arg_t *arg, asn1cnst_range_t *range);
51 static int emit_single_member_PER_constraint(arg_t *arg, asn1cnst_range_t *range, int juscountvalues, const char *type);
52 static int emit_member_OER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx);
53 static int emit_member_PER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx);
54 static int emit_member_table(arg_t *arg, asn1p_expr_t *expr,
55 asn1c_ioc_table_and_objset_t *);
56 static int emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count, const char *opt_modifier);
57 static int emit_include_dependencies(arg_t *arg);
58 static asn1p_expr_t *terminal_structable(arg_t *arg, asn1p_expr_t *expr);
59 static int expr_defined_recursively(arg_t *arg, asn1p_expr_t *expr);
60 static int asn1c_recurse(arg_t *arg, asn1p_expr_t *expr, int (*callback)(arg_t *arg, void *key), void *key);
61 static asn1p_expr_type_e expr_get_type(arg_t *arg, asn1p_expr_t *expr);
62 static int try_inline_default(arg_t *arg, asn1p_expr_t *expr, int out);
63 static int *compute_canonical_members_order(arg_t *arg, int el_count);
66 _TVM_SAME = 0, /* tags and all_tags are same */
67 _TVM_SUBSET = 1, /* tags are subset of all_tags */
68 _TVM_DIFFERENT = 2, /* tags and all_tags are different */
70 static enum tvm_compat emit_tags_vectors(arg_t *arg, asn1p_expr_t *expr, int *tc, int *atc);
76 static int emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, enum tvm_compat tv_mode, int tags_count, int all_tags_count, int elements_count, enum etd_spec);
78 #define C99_MODE (!(arg->flags & A1C_NO_C99))
79 #define UNNAMED_UNIONS (arg->flags & A1C_UNNAMED_UNIONS)
80 #define HIDE_INNER_DEFS (arg->embed && !(arg->flags & A1C_ALL_DEFS_GLOBAL))
82 #define PCTX_DEF INDENTED( \
84 OUT("/* Context for parsing across buffer boundaries */\n"); \
85 OUT("asn_struct_ctx_t _asn_ctx;\n"));
88 #define DEPENDENCIES do { \
89 emit_include_dependencies(arg); \
90 if(expr->expr_type == ASN_CONSTR_SET_OF) \
91 GEN_INCLUDE_STD("asn_SET_OF"); \
92 if(expr->expr_type == ASN_CONSTR_SEQUENCE_OF) \
93 GEN_INCLUDE_STD("asn_SEQUENCE_OF"); \
96 /* MKID_safe() without checking for reserved keywords */
97 #define MKID(expr) (asn1c_make_identifier(AMI_USE_PREFIX, expr, 0))
98 #define MKID_safe(expr) (asn1c_make_identifier(AMI_CHECK_RESERVED, expr, 0))
101 asn1c_lang_C_type_REAL(arg_t *arg) {
102 return asn1c_lang_C_type_SIMPLE_TYPE(arg);
106 asn1c_integer_t value;
110 static int compar_enumMap_byName(const void *ap, const void *bp) {
111 const struct value2enum *a = (const struct value2enum *)ap;
112 const struct value2enum *b = (const struct value2enum *)bp;
113 return strcmp(a->name, b->name);
115 static int compar_enumMap_byValue(const void *ap, const void *bp) {
116 const struct value2enum *a = (const struct value2enum *)ap;
117 const struct value2enum *b = (const struct value2enum *)bp;
118 if(a->value < b->value)
120 else if(a->value == b->value)
126 asn1c_lang_C_type_common_INTEGER(arg_t *arg) {
127 asn1p_expr_t *expr = arg->expr;
129 int el_count = expr_elements_count(arg, expr);
130 struct value2enum *v2e;
131 int map_extensions = (expr->expr_type == ASN_BASIC_INTEGER);
133 int saved_target = arg->target->target;
135 v2e = calloc(el_count + 1, sizeof(*v2e));
139 * For all ENUMERATED types and for those INTEGER types which
140 * have identifiers, print out an enumeration table.
142 if(expr->expr_type == ASN_BASIC_ENUMERATED || el_count) {
145 OUT("typedef %s {\n", c_name(arg).members_enum);
146 TQ_FOR(v, &(expr->members), next) {
147 switch(v->expr_type) {
150 OUT("%s", c_member_name(arg, v));
152 asn1p_itoa(v->value->value.v_integer),
153 (eidx+1 < el_count) ? "," : "");
154 v2e[eidx].name = v->Identifier;
155 v2e[eidx].value = v->value->value.v_integer;
158 case A1TC_EXTENSIBLE:
160 OUT("\t * Enumeration is extensible\n");
163 map_extensions = eidx + 1;
170 OUT("} %s;\n", c_name(arg).members_name);
171 assert(eidx == el_count);
175 * For all ENUMERATED types print out a mapping table
176 * between identifiers and associated values.
177 * This is prohibited for INTEGER types by by X.693:8.3.4.
179 if(expr->expr_type == ASN_BASIC_ENUMERATED) {
182 * Generate a enumerationName<->value map for XER codec.
186 OUT("static const asn_INTEGER_enum_map_t asn_MAP_%s_value2enum_%d[] = {\n",
187 MKID(expr), expr->_type_unique_index);
188 qsort(v2e, el_count, sizeof(v2e[0]), compar_enumMap_byValue);
189 for(eidx = 0; eidx < el_count; eidx++) {
190 v2e[eidx].idx = eidx;
191 OUT("\t{ %s,\t%ld,\t\"%s\" }%s\n",
192 asn1p_itoa(v2e[eidx].value),
193 (long)strlen(v2e[eidx].name), v2e[eidx].name,
194 (eidx + 1 < el_count) ? "," : "");
197 OUT("\t/* This list is extensible */\n");
200 OUT("static const unsigned int asn_MAP_%s_enum2value_%d[] = {\n",
201 MKID(expr), expr->_type_unique_index);
202 qsort(v2e, el_count, sizeof(v2e[0]), compar_enumMap_byName);
203 for(eidx = 0; eidx < el_count; eidx++) {
204 OUT("\t%d%s\t/* %s(%s) */\n",
206 (eidx + 1 < el_count) ? "," : "",
207 v2e[eidx].name, asn1p_itoa(v2e[eidx].value));
210 OUT("\t/* This list is extensible */\n");
213 if(!(expr->_type_referenced)) OUT("static ");
214 OUT("const asn_INTEGER_specifics_t asn_SPC_%s_specs_%d = {\n",
215 MKID(expr), expr->_type_unique_index);
217 OUT("asn_MAP_%s_value2enum_%d,\t"
218 "/* \"tag\" => N; sorted by tag */\n",
220 expr->_type_unique_index);
221 OUT("asn_MAP_%s_enum2value_%d,\t"
222 "/* N => \"tag\"; sorted by N */\n",
224 expr->_type_unique_index);
225 OUT("%d,\t/* Number of elements in the maps */\n",
228 OUT("%d,\t/* Extensions before this member */\n",
231 OUT("0,\t/* Enumeration is not extensible */\n");
233 if(expr->expr_type == ASN_BASIC_ENUMERATED)
234 OUT("1,\t/* Strict enumeration */\n");
237 OUT("0,\t/* Native long size */\n");
243 if(expr->expr_type == ASN_BASIC_INTEGER
244 && asn1c_type_fits_long(arg, expr) == FL_FITS_UNSIGN) {
246 if(!(expr->_type_referenced)) OUT("static ");
247 OUT("const asn_INTEGER_specifics_t asn_SPC_%s_specs_%d = {\n",
248 MKID(expr), expr->_type_unique_index);
255 OUT("0,\t/* Native long size */\n");
256 OUT("1\t/* Unsigned representation */\n");
264 return asn1c_lang_C_type_SIMPLE_TYPE(arg);
268 asn1c_lang_C_type_BIT_STRING(arg_t *arg) {
269 asn1p_expr_t *expr = arg->expr;
271 int el_count = expr_elements_count(arg, expr);
272 int saved_target = arg->target->target;
277 OUT("typedef %s {\n", c_name(arg).members_enum);
278 TQ_FOR(v, &(expr->members), next) {
279 if(v->expr_type != A1TC_UNIVERVAL) {
280 OUT("/* Unexpected BIT STRING element: %s */\n",
286 OUT("%s", c_member_name(arg, v));
288 asn1p_itoa(v->value->value.v_integer),
289 (eidx < el_count) ? "," : "");
291 OUT("} %s;\n", c_name(arg).members_name);
292 assert(eidx == el_count);
297 return asn1c_lang_C_type_SIMPLE_TYPE(arg);
301 * Check if it is a true open type. That is, type is taken from
302 * the Information Object Set driven constraints.
305 is_open_type(arg_t *arg, asn1p_expr_t *expr, asn1c_ioc_table_and_objset_t *opt_ioc) {
313 if(expr->meta_type == AMT_TYPEREF
314 && expr->expr_type == A1TC_REFERENCE
315 && expr->reference->comp_count == 2
316 && expr->reference->components[1].lex_type
317 == RLT_AmpUppercase) {
318 DEBUG("%s is a true open type", MKID(expr));
326 asn1c_lang_C_type_SEQUENCE(arg_t *arg) {
327 asn1p_expr_t *expr = arg->expr;
329 int comp_mode = 0; /* {root,ext=1,root,root,...} */
330 int saved_target = arg->target->target;
331 asn1c_ioc_table_and_objset_t ioc_tao;
336 ioc_tao = asn1c_get_ioc_table(arg);
338 if(emit_ioc_table(arg, expr, ioc_tao)) {
341 } else if(ioc_tao.fatal_error) {
347 /* Use _anonymous_type field to indicate it's called from
348 * asn1c_lang_C_type_SEx_OF() */
349 if (expr->_anonymous_type) {
353 OUT("%s {\n", c_name(arg).full_name);
355 REDIR(OT_TYPE_DECLS);
356 OUT("typedef %s {\n", c_name(arg).full_name);
359 TQ_FOR(v, &(expr->members), next) {
360 if(v->expr_type == A1TC_EXTENSIBLE)
361 if(comp_mode < 3) comp_mode++;
363 v->marker.flags |= EM_OMITABLE | EM_INDIRECT;
364 try_inline_default(arg, v, 1);
365 if(is_open_type(arg, v, ioc_tao.ioct ? &ioc_tao : 0)) {
366 arg_t tmp_arg = *arg;
370 const char *column_name = v->reference->components[1].name;
371 if(asn1c_lang_C_OpenType(&tmp_arg, &ioc_tao, column_name)) {
379 if((v->expr_type == ASN_CONSTR_SEQUENCE) &&
380 (v->marker.flags & EM_OPTIONAL) &&
381 (v->Identifier == NULL)) {
382 sprintf(ext_name, "ext%d", ext_num++);
383 v->Identifier = strdup(ext_name);
386 EMBED_WITH_IOCT(v, ioc_tao);
392 if (arg->embed && expr->_anonymous_type) {
393 OUT("} %s%s;\n", (expr->marker.flags & EM_INDIRECT)?"*":"",
394 c_name(arg).base_name);
398 OUT("%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
399 c_name(arg).base_name);
401 OUT("} %s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
402 arg->embed ? c_name(arg).as_member : c_name(arg).short_name);
403 if(!expr->_anonymous_type) OUT(";\n");
406 return asn1c_lang_C_type_SEQUENCE_def(arg, ioc_tao.ioct ? &ioc_tao : 0);
410 emit_tag2member_reference(arg_t *arg, asn1p_expr_t *expr,
411 unsigned tag2el_count) {
413 if(C99_MODE) OUT(".tag2el = ");
414 OUT("asn_MAP_%s_tag2el_%d,\n", MKID(expr), expr->_type_unique_index);
415 if(C99_MODE) OUT(".tag2el_count = ");
416 OUT("%d,\t/* Count of tags in the map */\n", tag2el_count);
418 OUT("0,\t/* No top level tags */\n");
419 OUT("0,\t/* No tags in the map */\n");
424 asn1c_lang_C_type_SEQUENCE_def(arg_t *arg, asn1c_ioc_table_and_objset_t *opt_ioc) {
425 asn1p_expr_t *expr = arg->expr;
427 int elements; /* Number of elements */
428 int first_extension = -1;
429 tag2el_t *tag2el = NULL;
430 int tag2el_count = 0;
433 enum tvm_compat tv_mode;
434 int roms_count; /* Root optional members */
435 int aoms_count; /* Additions optional members */
436 int saved_target = arg->target->target;
439 * Fetch every inner tag from the tag to elements map.
441 if(_fill_tag2el_map(arg, &tag2el, &tag2el_count, -1, FTE_ALLTAGS)) {
442 if(tag2el) free(tag2el);
446 GEN_INCLUDE_STD("constr_SEQUENCE");
448 GEN_DECLARE("SEQUENCE", expr); /* asn_DEF_xxx */
453 * Print out the table according to which parsing is performed.
455 if(expr_elements_count(arg, expr)) {
456 int comp_mode = 0; /* {root,ext=1,root,root,...} */
458 if(!(expr->_type_referenced)) OUT("static ");
459 OUT("asn_TYPE_member_t asn_MBR_%s_%d[] = {\n",
460 c_name(arg).part_name, expr->_type_unique_index);
465 INDENTED(TQ_FOR(v, &(expr->members), next) {
466 if(v->expr_type == A1TC_EXTENSIBLE) {
467 if((++comp_mode) == 1)
468 first_extension = elements;
471 if(v->marker.flags & EM_OMITABLE)
472 comp_mode == 1 ? ++aoms_count : ++roms_count;
473 if(emit_member_table(arg, v, opt_ioc) < 0)
479 if((roms_count + aoms_count) && (arg->flags & (A1C_GEN_OER|A1C_GEN_PER))) {
483 OUT("static const int asn_MAP_%s_oms_%d[] = {",
485 expr->_type_unique_index);
486 TQ_FOR(v, &(expr->members), next) {
487 if(v->expr_type == A1TC_EXTENSIBLE) {
491 if((v->marker.flags & EM_OMITABLE)
501 TQ_FOR(v, &(expr->members), next) {
502 if(v->expr_type == A1TC_EXTENSIBLE) {
506 if((v->marker.flags & EM_OMITABLE)
515 if(roms_count > 65536) {
516 FATAL("Too many optional elements in %s "
518 arg->expr->Identifier,
533 * Print out asn_DEF_<type>_[all_]tags[] vectors.
535 tv_mode = emit_tags_vectors(arg, expr, &tags_count, &all_tags_count);
538 * Tags to elements map.
540 emit_tag2member_map(arg, tag2el, tag2el_count, 0);
542 if(!(expr->_type_referenced)) OUT("static ");
543 OUT("asn_SEQUENCE_specifics_t asn_SPC_%s_specs_%d = {\n",
544 MKID(expr), expr->_type_unique_index);
546 OUT("sizeof(%s),\n", c_name(arg).full_name);
547 OUT("offsetof(%s, _asn_ctx),\n", c_name(arg).full_name);
548 emit_tag2member_reference(arg, expr, tag2el_count);
549 if(roms_count + aoms_count) {
550 OUT("asn_MAP_%s_oms_%d,\t/* Optional members */\n",
551 MKID(expr), expr->_type_unique_index);
552 OUT("%d, %d,\t/* Root/Additions */\n", roms_count, aoms_count);
554 OUT("0, 0, 0,\t/* Optional elements (not needed) */\n");
556 OUT("%d,\t/* First extension addition */\n", first_extension);
561 * Emit asn_DEF_xxx table.
563 emit_type_DEF(arg, expr, tv_mode, tags_count, all_tags_count, elements,
568 if(tag2el) free(tag2el);
571 } /* _SEQUENCE_def() */
574 asn1c_lang_C_type_SET(arg_t *arg) {
575 asn1p_expr_t *expr = arg->expr;
579 int comp_mode = 0; /* {root,ext=1,root,root,...} */
580 int saved_target = arg->target->target;
589 OUT(" * Method of determining the components presence\n");
592 OUT("typedef %s {\n", c_name(arg).presence_enum);
593 TQ_FOR(v, &(expr->members), next) {
594 if(v->expr_type == A1TC_EXTENSIBLE) continue;
596 OUT("%s,", c_presence_name(arg, v));
597 OUT("\t/* Member %s is present */\n", MKID(v));
601 OUT("} %s;\n", c_name(arg).presence_name);
606 if (expr->_anonymous_type) {
610 OUT("%s {\n", c_name(arg).full_name);
612 REDIR(OT_TYPE_DECLS);
613 OUT("typedef %s {\n", c_name(arg).full_name);
616 TQ_FOR(v, &(expr->members), next) {
619 if(v->expr_type == A1TC_EXTENSIBLE)
620 if(comp_mode < 3) comp_mode++;
622 v->marker.flags |= EM_OMITABLE | EM_INDIRECT;
623 try_inline_default(arg, v, 1);
625 if((v->expr_type == ASN_CONSTR_SEQUENCE) &&
626 (v->marker.flags & EM_OPTIONAL) &&
627 (v->Identifier == NULL)) {
628 sprintf(ext_name, "ext%d", ext_num++);
629 v->Identifier = strdup(ext_name);
637 OUT("/* Presence bitmask: ASN_SET_ISPRESENT(p%s, %s_PR_x) */\n",
639 OUT("unsigned int _presence_map\n");
640 OUT("\t[((%ld+(8*sizeof(unsigned int))-1)/(8*sizeof(unsigned int)))];\n", mcount);
645 if (arg->embed && expr->_anonymous_type) {
646 OUT("} %s%s;\n", (expr->marker.flags & EM_INDIRECT)?"*":"",
647 c_name(arg).base_name);
651 OUT("%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
652 c_name(arg).base_name);
654 OUT("} %s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
655 arg->embed ? c_name(arg).as_member : c_name(arg).short_name);
656 if(!expr->_anonymous_type) OUT(";\n");
659 return asn1c_lang_C_type_SET_def(arg);
663 asn1c_lang_C_type_SET_def(arg_t *arg) {
664 asn1p_expr_t *expr = arg->expr;
667 tag2el_t *tag2el = NULL;
668 int tag2el_count = 0;
669 tag2el_t *tag2el_cxer = NULL;
670 int tag2el_cxer_count = 0;
673 enum tvm_compat tv_mode;
675 int saved_target = arg->target->target;
678 * Fetch every inner tag from the tag to elements map.
680 if(_fill_tag2el_map(arg, &tag2el, &tag2el_count, -1, FTE_ALLTAGS)) {
681 if(tag2el) free(tag2el);
684 if(_fill_tag2el_map(arg, &tag2el_cxer, &tag2el_cxer_count, -1, FTE_CANONICAL_XER)) {
685 if(tag2el) free(tag2el);
686 if(tag2el_cxer) free(tag2el_cxer);
689 if(tag2el_cxer_count == tag2el_count
690 && memcmp(tag2el, tag2el_cxer, tag2el_count) == 0) {
695 GEN_INCLUDE_STD("constr_SET");
697 GEN_DECLARE("SET", expr); /* asn_DEF_xxx */
702 * Print out the table according to which parsing is performed.
704 if(expr_elements_count(arg, expr)) {
705 int comp_mode = 0; /* {root,ext=1,root,root,...} */
707 if(!(expr->_type_referenced)) OUT("static ");
708 OUT("asn_TYPE_member_t asn_MBR_%s_%d[] = {\n",
709 c_name(arg).part_name, expr->_type_unique_index);
712 INDENTED(TQ_FOR(v, &(expr->members), next) {
713 if(v->expr_type == A1TC_EXTENSIBLE) {
714 if(comp_mode < 3) comp_mode++;
716 emit_member_table(arg, v, NULL);
726 * Print out asn_DEF_<type>_[all_]tags[] vectors.
728 tv_mode = emit_tags_vectors(arg, expr, &tags_count, &all_tags_count);
731 * Tags to elements map.
733 emit_tag2member_map(arg, tag2el, tag2el_count, 0);
735 emit_tag2member_map(arg, tag2el_cxer, tag2el_cxer_count, "_cxer");
738 * Emit a map of mandatory elements.
740 OUT("static const uint8_t asn_MAP_%s_mmap_%d",
741 MKID(expr), expr->_type_unique_index);
743 OUT("[(%d + (8 * sizeof(unsigned int)) - 1) / 8]", elements);
748 TQ_FOR(v, &(expr->members), next) {
749 if(v->expr_type == A1TC_EXTENSIBLE) continue;
757 (v->marker.flags & EM_OMITABLE) != EM_OMITABLE,
768 if(!(expr->_type_referenced)) OUT("static \n");
769 OUT("asn_SET_specifics_t asn_SPC_%s_specs_%d = {\n",
770 MKID(expr), expr->_type_unique_index);
772 OUT("sizeof(%s),\n", c_name(arg).full_name);
773 OUT("offsetof(%s, _asn_ctx),\n", c_name(arg).full_name);
774 OUT("offsetof(%s, _presence_map),\n", c_name(arg).full_name);
775 emit_tag2member_reference(arg, expr, tag2el_count);
778 OUT("asn_MAP_%s_tag2el_cxer_%d,\n",
779 p, expr->_type_unique_index);
781 OUT("asn_MAP_%s_tag2el_%d,\t/* Same as above */\n",
782 p, expr->_type_unique_index);
783 OUT("%d,\t/* Count of tags in the CXER map */\n",
785 OUT("%d,\t/* Whether extensible */\n",
786 compute_extensions_start(expr) == -1 ? 0 : 1);
787 OUT("(const unsigned int *)asn_MAP_%s_mmap_%d\t/* Mandatory elements map */\n",
788 p, expr->_type_unique_index);
793 * Emit asn_DEF_xxx table.
795 emit_type_DEF(arg, expr, tv_mode, tags_count, all_tags_count, elements,
800 if (tag2el) free(tag2el);
801 if (tag2el_cxer) free(tag2el_cxer);
807 asn1c_lang_C_type_SEx_OF(arg_t *arg) {
808 asn1p_expr_t *expr = arg->expr;
809 asn1p_expr_t *memb = TQ_FIRST(&expr->members);
810 int saved_target = arg->target->target;
815 if (expr->_anonymous_type) {
819 OUT("%s {\n", c_name(arg).full_name);
821 OUT("typedef %s {\n", c_name(arg).full_name);
826 (arg->expr->expr_type == ASN_CONSTR_SET_OF)
827 ? "SET" : "SEQUENCE");
831 * The implementation of the A_SET_OF() macro is already indirect.
833 memb->marker.flags |= EM_INDIRECT;
835 if(memb->expr_type & ASN_CONSTR_MASK
836 || ((memb->expr_type == ASN_BASIC_ENUMERATED
837 || (0 /* -- prohibited by X.693:8.3.4 */
838 && memb->expr_type == ASN_BASIC_INTEGER))
839 && expr_elements_count(arg, memb))) {
841 asn1p_expr_t *tmp_memb = memb;
842 enum asn1p_expr_marker_e flags = memb->marker.flags;
846 tmp_memb->marker.flags &= ~EM_INDIRECT;
847 tmp_memb->_anonymous_type = 1;
848 if(tmp_memb->Identifier == 0) {
849 tmp_memb->Identifier = strdup("Member");
851 tmp_memb->Identifier = strdup(
852 asn1c_make_identifier(0,
854 assert(tmp_memb->Identifier);
856 tmp.default_cb(&tmp, NULL);
857 tmp_memb->marker.flags = flags;
859 assert(arg->target->target == OT_TYPE_DECLS ||
860 arg->target->target == OT_FWD_DEFS);
862 OUT("%s", asn1c_type_name(arg, memb,
863 (memb->marker.flags & EM_UNRECURSE)
864 ? TNF_RSAFE : TNF_CTYPE));
866 /* README README (above) */
867 if(0 && (memb->marker.flags & EM_INDIRECT))
874 if (arg->embed && expr->_anonymous_type) {
875 OUT("} %s%s;\n", (expr->marker.flags & EM_INDIRECT)?"*":"",
876 c_name(arg).base_name);
880 OUT("%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
881 c_name(arg).base_name);
883 OUT("} %s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
884 arg->embed ? c_name(arg).as_member : c_name(arg).short_name);
885 if(!expr->_anonymous_type) OUT(";\n");
889 * SET OF/SEQUENCE OF definition
891 return asn1c_lang_C_type_SEx_OF_def(arg,
892 (arg->expr->expr_type == ASN_CONSTR_SEQUENCE_OF));
896 asn1c_lang_C_type_SEx_OF_def(arg_t *arg, int seq_of) {
897 asn1p_expr_t *expr = arg->expr;
901 enum tvm_compat tv_mode;
902 int saved_target = arg->target->target;
905 * Print out the table according to which parsing is performed.
908 GEN_INCLUDE_STD("constr_SEQUENCE_OF");
910 GEN_INCLUDE_STD("constr_SET_OF");
913 GEN_DECLARE("SET_OF", expr); /* asn_DEF_xxx */
918 * Print out the table according to which parsing is performed.
920 if(!(expr->_type_referenced)) OUT("static ");
921 OUT("asn_TYPE_member_t asn_MBR_%s_%d[] = {\n",
922 c_name(arg).part_name, expr->_type_unique_index);
924 v = TQ_FIRST(&(expr->members));
926 v->Identifier = strdup("Member");
927 assert(v->Identifier);
929 v->_anonymous_type = 1;
931 emit_member_table(arg, v, NULL);
934 v->Identifier = (char *)NULL;
939 * Print out asn_DEF_<type>_[all_]tags[] vectors.
941 tv_mode = emit_tags_vectors(arg, expr, &tags_count, &all_tags_count);
943 if(!(expr->_type_referenced)) OUT("static ");
944 OUT("asn_SET_OF_specifics_t asn_SPC_%s_specs_%d = {\n",
945 MKID(expr), expr->_type_unique_index);
947 OUT("sizeof(%s),\n", c_name(arg).full_name);
948 OUT("offsetof(%s, _asn_ctx),\n", c_name(arg).full_name);
950 int as_xvl = expr_as_xmlvaluelist(arg, v);
951 OUT("%d,\t/* XER encoding is %s */\n",
953 as_xvl ? "XMLValueList" : "XMLDelimitedItemList");
959 * Emit asn_DEF_xxx table.
961 emit_type_DEF(arg, expr, tv_mode, tags_count, all_tags_count, 1,
967 } /* _SEx_OF_def() */
970 asn1c_lang_C_type_CHOICE(arg_t *arg) {
971 asn1p_expr_t *expr = arg->expr;
973 int saved_target = arg->target->target;
979 OUT("typedef %s {\n", c_name(arg).presence_enum);
982 OUT("%s", c_presence_name(arg, 0));
983 OUT("%s\t/* No components present */\n", !TQ_FIRST(&(expr->members)) ? "" : ",");
984 TQ_FOR(v, &(expr->members), next) {
985 if(skipComma) skipComma = 0;
986 else if (v->expr_type == A1TC_EXTENSIBLE && !TQ_NEXT(v, next)) OUT("\n");
988 if(v->expr_type == A1TC_EXTENSIBLE) {
989 OUT("/* Extensions may appear below */\n");
993 OUT("%s", c_presence_name(arg, v));
997 OUT("} %s;\n", c_name(arg).presence_name);
1002 if (expr->_anonymous_type) {
1006 OUT("%s {\n", c_name(arg).full_name);
1008 REDIR(OT_TYPE_DECLS);
1009 OUT("typedef %s {\n", c_name(arg).full_name);
1013 OUT("%s present;\n", c_name(arg).presence_name);
1015 if(UNNAMED_UNIONS == 0) {
1016 out_name_chain(arg, ONC_force_compound_name);
1020 TQ_FOR(v, &(expr->members), next) {
1023 if(UNNAMED_UNIONS) OUT("};\n");
1024 else OUT("} choice;\n");
1029 if (arg->embed && expr->_anonymous_type) {
1030 OUT("} %s%s;\n", (expr->marker.flags & EM_INDIRECT)?"*":"",
1031 c_name(arg).base_name);
1033 REDIR(saved_target);
1035 OUT("%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
1036 c_name(arg).base_name);
1038 OUT("} %s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
1039 arg->embed ? c_name(arg).as_member : c_name(arg).short_name);
1041 if(!expr->_anonymous_type) OUT(";\n");
1043 return asn1c_lang_C_type_CHOICE_def(arg);
1047 find_column_index(arg_t *arg, asn1c_ioc_table_and_objset_t *opt_ioc, const char *column_name) {
1050 if(!opt_ioc || !opt_ioc->ioct || !column_name) {
1054 if(opt_ioc->ioct->rows == 0) {
1055 return 0; /* No big deal. Just no data */
1057 for(size_t clmn = 0; clmn < opt_ioc->ioct->row[0]->columns; clmn++) {
1058 if(strcmp(opt_ioc->ioct->row[0]->column[clmn].field->Identifier,
1059 column_name) == 0) {
1069 asn1c_lang_C_OpenType(arg_t *arg, asn1c_ioc_table_and_objset_t *opt_ioc,
1070 const char *column_name) {
1071 arg_t tmp_arg = *arg;
1073 ssize_t column_index = find_column_index(arg, opt_ioc, column_name);
1074 if(column_index < 0) {
1075 FATAL("Open type generation attempted for %s, incomplete", column_name);
1079 asn1p_expr_t *open_type_choice =
1080 asn1p_expr_new(arg->expr->_lineno, arg->expr->module);
1082 open_type_choice->Identifier = strdup(arg->expr->Identifier);
1083 open_type_choice->meta_type = AMT_TYPE;
1084 open_type_choice->expr_type = ASN_CONSTR_OPEN_TYPE;
1085 open_type_choice->_type_unique_index = arg->expr->_type_unique_index;
1086 open_type_choice->parent_expr = arg->expr->parent_expr;
1088 for(size_t row = 0; row < opt_ioc->ioct->rows; row++) {
1089 struct asn1p_ioc_cell_s *cell =
1090 &opt_ioc->ioct->row[row]->column[column_index];
1092 if(!cell->value) continue;
1094 if(asn1p_lookup_child(open_type_choice, cell->value->Identifier))
1097 asn1p_expr_t *m = asn1p_expr_clone(cell->value, 0);
1098 asn1p_expr_add(open_type_choice, m);
1101 tmp_arg.expr = open_type_choice;
1102 GEN_INCLUDE_STD("OPEN_TYPE");
1103 asn1c_lang_C_type_CHOICE(&tmp_arg);
1104 asn1p_expr_free(tmp_arg.expr);
1109 asn1c_lang_C_type_CHOICE_def(arg_t *arg) {
1110 asn1p_expr_t *expr = arg->expr;
1112 int elements; /* Number of elements */
1113 tag2el_t *tag2el = NULL;
1114 int tag2el_count = 0;
1117 enum tvm_compat tv_mode;
1119 int saved_target = arg->target->target;
1122 * Fetch every inner tag from the tag to elements map.
1124 if(_fill_tag2el_map(arg, &tag2el, &tag2el_count, -1, FTE_ALLTAGS)) {
1125 if(tag2el) free(tag2el);
1129 GEN_INCLUDE_STD("constr_CHOICE");
1131 GEN_DECLARE("CHOICE", expr); /* asn_DEF_xxx */
1133 REDIR(OT_STAT_DEFS);
1136 * Print out the table according to which parsing is performed.
1138 if(expr_elements_count(arg, expr)) {
1140 if(!(expr->_type_referenced)) OUT("static ");
1141 OUT("asn_TYPE_member_t asn_MBR_%s_%d[] = {\n",
1142 c_name(arg).part_name, expr->_type_unique_index);
1145 INDENTED(TQ_FOR(v, &(expr->members), next) {
1146 if(v->expr_type == A1TC_EXTENSIBLE)
1148 emit_member_table(arg, v, NULL);
1156 /* Create a canonical elements map */
1157 if(elements && (arg->flags & A1C_GEN_PER)) {
1158 cmap = compute_canonical_members_order(arg, elements);
1160 OUT("static const unsigned asn_MAP_%s_to_canonical_%d[] = {",
1161 MKID(expr), expr->_type_unique_index);
1162 for(int i = 0; i < elements; i++) {
1164 OUT(" %d", cmap[i]);
1167 OUT("static const unsigned asn_MAP_%s_from_canonical_%d[] = {",
1168 MKID(expr), expr->_type_unique_index);
1169 for(int i = 0; i < elements; i++) {
1172 for(j = 0; j < elements; j++) {
1178 assert(j < elements);
1187 * Our parent structure has already taken this into account.
1189 tv_mode = _TVM_SAME;
1190 tags_count = all_tags_count = 0;
1192 tv_mode = emit_tags_vectors(arg, expr,
1193 &tags_count, &all_tags_count);
1197 * Tags to elements map.
1199 emit_tag2member_map(arg, tag2el, tag2el_count, 0);
1201 if(!(expr->_type_referenced)) OUT("static ");
1202 OUT("asn_CHOICE_specifics_t asn_SPC_%s_specs_%d = {\n", MKID(expr),
1203 expr->_type_unique_index);
1205 OUT("sizeof(%s),\n", c_name(arg).full_name);
1206 OUT("offsetof(%s, _asn_ctx),\n", c_name(arg).full_name);
1207 OUT("offsetof(%s, present),\n", c_name(arg).full_name);
1208 OUT("sizeof(((%s *)0)->present),\n", c_name(arg).full_name);
1209 emit_tag2member_reference(arg, expr, tag2el_count);
1211 if(C99_MODE) OUT(".to_canonical_order = ");
1212 OUT("asn_MAP_%s_to_canonical_%d,\n", MKID(expr),
1213 expr->_type_unique_index);
1214 if(C99_MODE) OUT(".from_canonical_order = ");
1215 OUT("asn_MAP_%s_from_canonical_%d,\n", MKID(expr),
1216 expr->_type_unique_index);
1217 } else { OUT("0, 0,\n"); }
1218 if(C99_MODE) OUT(".first_extension = ");
1219 OUT("%d\t/* Extensions start */\n", compute_extensions_start(expr));
1224 * Emit asn_DEF_xxx table.
1226 emit_type_DEF(arg, expr, tv_mode, tags_count, all_tags_count, elements,
1229 REDIR(saved_target);
1231 if (tag2el) free(tag2el);
1234 } /* _CHOICE_def() */
1237 asn1c_lang_C_type_REFERENCE_Value(arg_t *arg) {
1239 asn1p_expr_t *expr, *ref_type;
1243 ref_type = WITH_MODULE_NAMESPACE(
1244 tmp.expr->module, expr_ns,
1245 asn1f_lookup_symbol_ex(tmp.asn, expr_ns, tmp.expr,
1246 arg->expr->reference));
1251 asn1c_attach_streams(ref_type);
1253 arg->target = ref_type->data;
1254 saved_target = arg->target->target;
1255 REDIR(OT_FUNC_DECLS);
1257 if((ref_type->expr_type == ASN_BASIC_INTEGER) ||
1258 (ref_type->expr_type == ASN_BASIC_ENUMERATED)) {
1259 OUT("#define %s_", MKID(ref_type));
1260 OUT("%s\t", c_name(arg).base_name);
1261 OUT("((%s)", asn1c_type_name(arg, expr, TNF_CTYPE));
1262 OUT("%s)\n", asn1p_itoa(expr->value->value.v_integer));
1265 REDIR(saved_target);
1266 arg->target = tmp.target;
1271 asn1c_lang_C_type_REFERENCE(arg_t *arg) {
1274 ref = arg->expr->reference;
1275 if(ref->components[ref->comp_count-1].name[0] == '&') {
1276 asn1p_expr_t *extract;
1280 extract = WITH_MODULE_NAMESPACE(
1281 arg->expr->module, expr_ns,
1282 asn1f_class_access_ex(arg->asn, arg->expr->module, expr_ns,
1283 arg->expr, arg->expr->rhs_pspecs, ref));
1287 extract = asn1p_expr_clone(extract, 0);
1289 free(extract->Identifier);
1290 extract->Identifier = strdup(arg->expr->Identifier);
1291 if(extract->Identifier == NULL) {
1292 asn1p_expr_free(extract);
1303 ret = arg->default_cb(&tmp, NULL);
1305 asn1p_expr_free(extract);
1311 return asn1c_lang_C_type_SIMPLE_TYPE(arg);
1315 asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
1316 asn1p_expr_t *expr = arg->expr;
1319 enum tvm_compat tv_mode;
1320 enum etd_spec etd_spec;
1322 int saved_target = arg->target->target;
1325 enum tnfmt tnfmt = TNF_CTYPE;
1328 * If this is an optional compound type,
1329 * refer it using "struct X" convention,
1330 * as it may recursively include the current structure.
1332 if(expr->marker.flags & (EM_INDIRECT | EM_UNRECURSE)) {
1333 if(terminal_structable(arg, expr)) {
1335 if(saved_target != OT_FWD_DECLS) {
1336 REDIR(OT_FWD_DECLS);
1338 asn1c_type_name(arg, arg->expr, tnfmt));
1340 REDIR(saved_target);
1344 OUT("%s", asn1c_type_name(arg, arg->expr, tnfmt));
1346 if(!expr->_anonymous_type) {
1347 OUT("%s", (expr->marker.flags&EM_INDIRECT)?"\t*":"\t ");
1348 OUT("%s;", MKID_safe(expr));
1349 if((expr->marker.flags & (EM_DEFAULT & ~EM_INDIRECT))
1350 == (EM_DEFAULT & ~EM_INDIRECT))
1351 OUT("\t/* DEFAULT %s */",
1352 asn1f_printable_value(
1353 expr->marker.default_value));
1354 else if((expr->marker.flags & EM_OPTIONAL)
1356 OUT("\t/* OPTIONAL */");
1361 GEN_POS_INCLUDE_BASE(OT_INCLUDES, expr);
1363 REDIR(OT_TYPE_DECLS);
1366 asn1c_type_name(arg, arg->expr, TNF_CTYPE));
1368 (expr->marker.flags & EM_INDIRECT)?"*":" ",
1370 expr->_anonymous_type ? "":";\n");
1373 if((expr->expr_type == ASN_BASIC_ENUMERATED)
1374 || (0 /* -- prohibited by X.693:8.3.4 */
1375 && expr->expr_type == ASN_BASIC_INTEGER
1376 && expr_elements_count(arg, expr))
1377 || (expr->expr_type == ASN_BASIC_INTEGER
1378 && asn1c_type_fits_long(arg, expr) == FL_FITS_UNSIGN)
1379 || asn1c_REAL_fits(arg, expr) == RL_FITS_FLOAT32
1381 etd_spec = ETD_HAS_SPECIFICS;
1383 etd_spec = ETD_NO_SPECIFICS;
1386 * If this type just blindly refers the other type, alias it.
1389 if(arg->embed && etd_spec == ETD_NO_SPECIFICS) {
1390 REDIR(saved_target);
1397 * Constraint checking.
1399 if(!(arg->flags & A1C_NO_CONSTRAINTS) && expr->combined_constraints) {
1401 if(HIDE_INNER_DEFS) OUT("static ");
1404 if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index);
1405 OUT("_constraint(const asn_TYPE_descriptor_t *td, const void *sptr,\n");
1407 OUT("\t\tasn_app_constraint_failed_f *ctfailcb, void *app_key) {");
1409 DEBUG("expr constraint checking code for %s", p);
1410 if(asn1c_emit_constraint_checking_code(arg) == 1) {
1411 OUT("return td->encoding_constraints.general_constraints"
1412 "(td, sptr, ctfailcb, app_key);\n");
1419 REDIR(OT_STAT_DEFS);
1422 * By default, NativeReal is double. We only override this if
1423 * (OER) constraints suggested that we may use float.
1425 if(asn1c_REAL_fits(arg, expr) == RL_FITS_FLOAT32) {
1426 if(!(expr->_type_referenced)) OUT("static ");
1427 OUT("const asn_NativeReal_specifics_t asn_SPC_%s_specs_%d = {\n",
1428 MKID(expr), expr->_type_unique_index);
1430 OUT("4\t/* Use 'float' type. */\n");
1436 * Print out asn_DEF_<type>_[all_]tags[] vectors.
1438 tv_mode = emit_tags_vectors(arg, expr, &tags_count, &all_tags_count);
1439 DEBUG("emit tag vectors for %s %d, %d, %d", expr->Identifier,
1440 tv_mode, tags_count, all_tags_count);
1442 emit_type_DEF(arg, expr, tv_mode, tags_count, all_tags_count,
1448 * Emit suicidal functions.
1452 * This function replaces certain fields from the definition
1453 * of a type with the corresponding fields from the basic type
1454 * (from which the current type is inherited).
1457 OUT(" * This type is implemented using %s,\n", c_name(arg).type.base_name);
1458 OUT(" * so here we adjust the DEF accordingly.\n");
1461 REDIR(OT_FUNC_DECLS);
1464 if(HIDE_INNER_DEFS) {
1465 OUT("/* extern asn_TYPE_descriptor_t asn_DEF_%s_%d;"
1466 "\t// (Use -fall-defs-global to expose) */\n",
1467 p, expr->_type_unique_index);
1469 OUT("extern asn_TYPE_descriptor_t asn_DEF_%s;\n", p);
1470 if(etd_spec == ETD_HAS_SPECIFICS && expr->_type_referenced) {
1471 if((expr->expr_type == ASN_BASIC_ENUMERATED)
1472 || (expr->expr_type == ASN_BASIC_INTEGER)) {
1473 OUT("extern const asn_INTEGER_specifics_t "
1474 "asn_SPC_%s_specs_%d;\n",
1475 c_name(arg).base_name, expr->_type_unique_index);
1477 asn1p_expr_t *terminal = WITH_MODULE_NAMESPACE(
1478 expr->module, expr_ns,
1479 asn1f_find_terminal_type_ex(arg->asn, expr_ns, expr));
1480 OUT("extern const asn_%s_specifics_t ",
1481 asn1c_type_name(arg, terminal, TNF_SAFE));
1482 OUT("asn_SPC_%s_specs_%d;\n", MKID(expr),
1483 expr->_type_unique_index);
1486 OUT("asn_struct_free_f %s_free;\n", p);
1487 OUT("asn_struct_print_f %s_print;\n", p);
1488 OUT("asn_constr_check_f %s_constraint;\n", p);
1489 OUT("ber_type_decoder_f %s_decode_ber;\n", p);
1490 OUT("der_type_encoder_f %s_encode_der;\n", p);
1491 OUT("xer_type_decoder_f %s_decode_xer;\n", p);
1492 OUT("xer_type_encoder_f %s_encode_xer;\n", p);
1493 if(arg->flags & A1C_GEN_OER) {
1494 OUT("oer_type_decoder_f %s_decode_oer;\n", p);
1495 OUT("oer_type_encoder_f %s_encode_oer;\n", p);
1497 if(arg->flags & A1C_GEN_PER) {
1498 OUT("per_type_decoder_f %s_decode_uper;\n", p);
1499 OUT("per_type_encoder_f %s_encode_uper;\n", p);
1500 OUT("per_type_decoder_f %s_decode_aper;\n", p);
1501 OUT("per_type_encoder_f %s_encode_aper;\n", p);
1505 REDIR(saved_target);
1511 asn1c_lang_C_type_EXTENSIBLE(arg_t *arg) {
1514 OUT(" * This type is extensible,\n");
1515 OUT(" * possible extensions are below.\n");
1522 compute_extensions_start(asn1p_expr_t *expr) {
1525 TQ_FOR(v, &(expr->members), next) {
1526 if(v->expr_type == A1TC_EXTENSIBLE)
1534 _print_tag(arg_t *arg, struct asn1p_type_tag_s *tag) {
1537 switch(tag->tag_class) {
1538 case TC_UNIVERSAL: OUT("ASN_TAG_CLASS_UNIVERSAL"); break;
1539 case TC_APPLICATION: OUT("ASN_TAG_CLASS_APPLICATION"); break;
1540 case TC_CONTEXT_SPECIFIC: OUT("ASN_TAG_CLASS_CONTEXT"); break;
1541 case TC_PRIVATE: OUT("ASN_TAG_CLASS_PRIVATE"); break;
1545 OUT(" | (%s << 2))", asn1p_itoa(tag->tag_value));
1552 _tag2el_cmp(const void *ap, const void *bp) {
1553 const tag2el_t *a = ap;
1554 const tag2el_t *b = bp;
1555 const struct asn1p_type_tag_s *ta = &a->el_tag;
1556 const struct asn1p_type_tag_s *tb = &b->el_tag;
1558 if(ta->tag_class == tb->tag_class) {
1559 if(ta->tag_value == tb->tag_value) {
1561 * Sort by their respective positions.
1563 if(a->el_no < b->el_no)
1565 else if(a->el_no > b->el_no)
1568 } else if(ta->tag_value < tb->tag_value)
1572 } else if(ta->tag_class < tb->tag_class) {
1580 * For constructed types, number of external tags may be greater than
1581 * number of elements in the type because of CHOICE type.
1582 * T ::= SET { -- Three possible tags:
1583 * a INTEGER, -- One tag is here...
1584 * b Choice1 -- ... and two more tags are there.
1586 * Choice1 ::= CHOICE {
1588 * s2 ObjectDescriptor
1592 _fill_tag2el_map(arg_t *arg, tag2el_t **tag2el, int *count, int el_no, fte_e flags) {
1593 asn1p_expr_t *expr = arg->expr;
1594 arg_t tmparg = *arg;
1597 int original_count = *count;
1598 int sort_until = -1;
1600 TQ_FOR(v, &(expr->members), next) {
1601 if(v->expr_type == A1TC_EXTENSIBLE) {
1603 * CXER mandates sorting
1604 * only for the root part.
1606 if(flags == FTE_CANONICAL_XER
1607 && sort_until == -1)
1608 sort_until = *count;
1614 if(_add_tag2el_member(&tmparg, tag2el, count,
1615 (el_no==-1)?element:el_no, flags)) {
1623 if(flags == FTE_CANONICAL_XER) {
1624 if(sort_until == -1) sort_until = *count;
1625 qsort((*tag2el) + original_count,
1626 sort_until - original_count,
1627 sizeof(**tag2el), _tag2el_cmp);
1628 if(arg->expr->expr_type == ASN_CONSTR_CHOICE
1629 && (sort_until - original_count) >= 1) {
1630 /* Only take in account the root component */
1631 *count = original_count + 1;
1635 * Sort the map according to canonical order of their
1636 * tags and element numbers.
1638 qsort(*tag2el, *count, sizeof(**tag2el), _tag2el_cmp);
1642 * Initialize .toff_{first|last} members.
1645 struct asn1p_type_tag_s *cur_tag = 0;
1646 tag2el_t *cur = *tag2el;
1647 tag2el_t *end = cur + *count;
1649 for(occur = 0; cur < end; cur++) {
1651 || cur_tag->tag_value != cur->el_tag.tag_value
1652 || cur_tag->tag_class != cur->el_tag.tag_class) {
1653 cur_tag = &cur->el_tag;
1658 cur->toff_first = -occur;
1659 for(i = 0; i >= -occur; i--)
1660 cur[i].toff_last = -i;
1668 _add_tag2el_member(arg_t *arg, tag2el_t **tag2el, int *count, int el_no, fte_e flags) {
1669 struct asn1p_type_tag_s tag;
1674 ret = WITH_MODULE_NAMESPACE(
1675 arg->expr->module, expr_ns,
1676 asn1f_fetch_outmost_tag(arg->asn, expr_ns, arg->expr->module, arg->expr,
1677 &tag, AFT_IMAGINARY_ANY));
1680 int new_count = (*count) + 1;
1683 if(tag.tag_value == -1) {
1685 * This is an untagged ANY type,
1686 * proceed without adding a tag
1691 p = realloc(*tag2el, new_count * sizeof(tag2el_t));
1695 if(0) DEBUG("Found tag for %s: %ld",
1696 arg->expr->Identifier,
1697 (long)tag.tag_value);
1699 te = &((*tag2el)[*count]);
1702 te->from_expr = arg->expr;
1707 DEBUG("Searching tag in complex expression %s:%x at line %d",
1708 arg->expr->Identifier,
1709 arg->expr->expr_type,
1710 arg->expr->_lineno);
1713 * Iterate over members of CHOICE type.
1715 if(arg->expr->expr_type == ASN_CONSTR_CHOICE) {
1716 return _fill_tag2el_map(arg, tag2el, count, el_no, flags);
1719 if(arg->expr->expr_type == A1TC_REFERENCE) {
1722 expr = WITH_MODULE_NAMESPACE(
1723 tmp.expr->module, expr_ns,
1724 asn1f_lookup_symbol_ex(tmp.asn, expr_ns, tmp.expr,
1725 arg->expr->reference));
1728 return _add_tag2el_member(&tmp, tag2el, count, el_no, flags);
1730 FATAL("Cannot dereference %s at line %d",
1731 arg->expr->Identifier,
1732 arg->expr->_lineno);
1737 DEBUG("No tag for %s at line %d",
1738 arg->expr->Identifier,
1739 arg->expr->_lineno);
1745 emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count, const char *opt_modifier) {
1746 asn1p_expr_t *expr = arg->expr;
1749 if(!tag2el_count) return 0; /* No top level tags */
1751 OUT("static const asn_TYPE_tag2member_t asn_MAP_%s_tag2el%s_%d[] = {\n",
1752 MKID(expr), opt_modifier?opt_modifier:"",
1753 expr->_type_unique_index);
1754 for(i = 0; i < tag2el_count; i++) {
1756 _print_tag(arg, &tag2el[i].el_tag);
1758 OUT("%d, ", tag2el[i].el_no);
1759 OUT("%d, ", tag2el[i].toff_first);
1760 OUT("%d ", tag2el[i].toff_last);
1762 (i + 1 < tag2el_count) ? "," : "",
1763 tag2el[i].from_expr->Identifier);
1764 if(arg->flags & A1C_LINE_REFS)
1765 OUT("at %d", tag2el[i].from_expr->_lineno);
1773 static enum tvm_compat
1774 emit_tags_vectors(arg_t *arg, asn1p_expr_t *expr, int *tags_count_r, int *all_tags_count_r) {
1775 struct asn1p_type_tag_s *tags = 0; /* Effective tags */
1776 struct asn1p_type_tag_s *all_tags = 0; /* The full array */
1778 int all_tags_count = 0;
1779 enum tvm_compat tv_mode = _TVM_SAME;
1782 /* Cleanup before proceeding. */
1784 *all_tags_count_r = 0;
1786 /* Fetch a chain of tags */
1787 tags_count = WITH_MODULE_NAMESPACE(
1788 expr->module, expr_ns,
1789 asn1f_fetch_tags(arg->asn, expr_ns, expr->module, expr, &tags, 0));
1790 if(tags_count < 0) {
1791 DEBUG("fail to fetch tags for %s", expr->Identifier);
1795 /* Fetch a chain of tags */
1796 all_tags_count = WITH_MODULE_NAMESPACE(
1797 expr->module, expr_ns,
1798 asn1f_fetch_tags(arg->asn, expr_ns, expr->module, expr, &all_tags,
1800 if(all_tags_count < 0) {
1802 DEBUG("fail to fetch tags chain for %s", expr->Identifier);
1806 assert(tags_count <= all_tags_count);
1807 assert((tags_count?0:1) == (all_tags_count?0:1));
1809 if(tags_count <= all_tags_count) {
1810 for(i = 0; i < tags_count; i++) {
1811 if(tags[i].tag_value != all_tags[i].tag_value
1812 || tags[i].tag_class != all_tags[i].tag_class) {
1813 tv_mode = _TVM_DIFFERENT;
1817 if(i == tags_count && tags_count < all_tags_count)
1818 tv_mode = _TVM_SUBSET;
1820 tv_mode = _TVM_DIFFERENT;
1823 #define EMIT_TAGS_TABLE(name, tags, tags_count) do { \
1824 OUT("static const ber_tlv_tag_t asn_DEF_%s%s_tags_%d[] = {\n",\
1826 expr->_type_unique_index); \
1828 /* Print the array of collected tags */ \
1829 for(i = 0; i < tags_count; i++) { \
1831 _print_tag(arg, &tags[i]); \
1839 if(tv_mode == _TVM_SUBSET)
1840 EMIT_TAGS_TABLE("", all_tags, all_tags_count);
1842 EMIT_TAGS_TABLE("", tags, tags_count);
1845 if(all_tags_count) {
1846 if(tv_mode == _TVM_DIFFERENT)
1847 EMIT_TAGS_TABLE("_all", all_tags, all_tags_count);
1853 *tags_count_r = tags_count;
1854 *all_tags_count_r = all_tags_count;
1860 expr_elements_count(arg_t *arg, asn1p_expr_t *expr) {
1861 asn1p_expr_t *topmost_parent;
1865 topmost_parent = WITH_MODULE_NAMESPACE(
1866 expr->module, expr_ns,
1867 asn1f_find_terminal_type_ex(arg->asn, expr_ns, expr));
1868 if(!topmost_parent) return 0;
1870 if(!(topmost_parent->expr_type & ASN_CONSTR_MASK)
1871 && !(topmost_parent->expr_type == ASN_BASIC_INTEGER)
1872 && !(topmost_parent->expr_type == ASN_BASIC_ENUMERATED)
1873 && !(topmost_parent->expr_type == ASN_BASIC_BIT_STRING))
1876 TQ_FOR(v, &(topmost_parent->members), next) {
1877 if(v->expr_type != A1TC_EXTENSIBLE)
1884 static asn1p_expr_type_e
1885 expr_get_type(arg_t *arg, asn1p_expr_t *expr) {
1886 asn1p_expr_t *terminal;
1887 terminal = asn1f_find_terminal_type_ex(arg->asn, arg->ns, expr);
1888 if(terminal) return terminal->expr_type;
1889 return A1TC_INVALID;
1892 static asn1c_integer_t
1893 PER_FROM_alphabet_characters(asn1cnst_range_t *range) {
1894 asn1c_integer_t numchars = 0;
1895 if(range->el_count) {
1897 for(i = 0; i < range->el_count; i++)
1899 += PER_FROM_alphabet_characters(range->elements[i]);
1901 assert(range->left.type == ARE_VALUE);
1902 assert(range->right.type == ARE_VALUE);
1903 numchars = 1 + (range->right.value - range->left.value);
1909 emit_single_member_OER_constraint_comment(arg_t *arg, asn1cnst_range_t *range, char *type) {
1912 * Print some courtesy debug information.
1915 && (range->left.type == ARE_VALUE || range->right.type == ARE_VALUE)) {
1917 if(type) OUT("(%s", type);
1919 if(range->left.type == ARE_VALUE)
1920 OUT("%s", asn1p_itoa(range->left.value));
1924 if(range->right.type == ARE_VALUE)
1925 OUT("%s", asn1p_itoa(range->right.value));
1928 if(range->extensible) OUT(",...");
1935 emit_single_member_OER_constraint_value(arg_t *arg, asn1cnst_range_t *range) {
1937 /* oer_support.h: asn_oer_constraint_s */
1942 if(range->incompatible || range->not_OER_visible) {
1944 } else if(expr_get_type(arg, arg->expr) == ASN_BASIC_REAL) {
1945 if(range->narrowing == NARROW_FLOAT32) {
1946 OUT("{ sizeof(float), 0 }");
1947 } else if(range->narrowing == NARROW_DOUBLE64) {
1948 OUT("{ sizeof(double), 0 }");
1952 } else if(range->left.type == ARE_VALUE && range->left.value >= 0
1953 && range->right.type == ARE_MAX) {
1955 } else if(range->left.type == ARE_VALUE &&
1956 range->right.type == ARE_VALUE) {
1957 asn1c_integer_t lb = range->left.value;
1958 asn1c_integer_t ub = range->right.value;
1960 unsigned positive = 0;
1964 /* X.969 08/2015 10.2(a) */
1967 } else if(ub <= 65535) {
1969 } else if((unsigned long long)ub <= 4294967295UL) {
1971 } else if((unsigned long long)ub <= 18446744073709551615ULL) {
1977 /* X.969 08/2015 10.2(b) - no lower bound or negative lower bound */
1978 if(lb >= -128 && ub <= 127) {
1980 } else if(lb >= -32768 && ub <= 32767) {
1982 } else if(lb >= -2147483648L && ub <= 2147483647L) {
1984 } else if(lb >= (-9223372036854775807LL-1)
1985 && ub <= 9223372036854775807LL) {
1989 OUT("{ %u, %u }", width, positive);
1998 emit_single_member_OER_constraint_size(arg_t *arg, asn1cnst_range_t *range) {
2000 /* oer_support.h: asn_oer_constraint_s */
2005 if(range->incompatible || range->not_OER_visible) {
2008 if(range->left.type == ARE_VALUE && range->right.type == ARE_VALUE
2009 && range->left.value == range->right.value
2010 && range->left.value >= 0) {
2011 OUT("%s", asn1p_itoa(range->left.value));
2021 emit_single_member_PER_constraint(arg_t *arg, asn1cnst_range_t *range, int alphabetsize, const char *type) {
2022 if(!range || range->incompatible || range->not_PER_visible) {
2023 OUT("{ APC_UNCONSTRAINED,\t-1, -1, 0, 0 }");
2027 if(expr_get_type(arg, arg->expr) == ASN_BASIC_REAL) {
2029 OUT("{ APC_UNCONSTRAINED,\t-1, -1, 0, 0 }");
2033 if(range->left.type == ARE_VALUE) {
2034 if(range->right.type == ARE_VALUE) {
2035 asn1c_integer_t cover = 1;
2036 asn1c_integer_t r = 1 + range->right.value
2037 - range->left.value;
2038 size_t rbits; /* Value range bits */
2039 ssize_t ebits; /* Value effective range bits */
2041 if(range->empty_constraint)
2046 r = PER_FROM_alphabet_characters(range);
2049 /* Compute real constraint */
2050 for(rbits = 0; rbits < (8 * sizeof(r)); rbits++) {
2053 cover *= 2; /* Can't do shifting */
2055 FATAL("Constraint at line %d too wide "
2056 "for %d-bits integer type",
2067 /* X.691, #10.9.4.1 */
2068 for(ebits = 0; ebits <= 16; ebits++)
2069 if(r <= 1 << ebits) break;
2071 || range->right.value >= 65536)
2074 /* X.691, #10.5.7.1 */
2075 for(ebits = 0; ebits <= 8; ebits++)
2076 if(r <= 1 << ebits) break;
2086 OUT("{ APC_CONSTRAINED%s,%s% d, % d, ",
2088 ? " | APC_EXTENSIBLE" : "",
2089 range->extensible ? " " : "\t", (int)rbits, (int)ebits);
2092 asn1c_integer_t lv = range->left.value;
2093 asn1c_integer_t rv = range->right.value;
2095 if(lv > 0x7fffffff) { lv = 0x7fffffff; gcmt++; }
2096 if(rv > 0x7fffffff) { rv = 0x7fffffff; gcmt++; }
2098 OINTS(lv); OUT(", "); OINTS(rv); OUT(" }");
2103 if(range->extensible) {
2104 OUT("{ APC_SEMI_CONSTRAINED | APC_EXTENSIBLE, "
2107 OUT("{ APC_SEMI_CONSTRAINED,\t-1, -1, ");
2110 OINTS(range->left.value); OUT(", ");
2111 OINTS(range->right.value); OUT(" }");
2113 OUT("{ APC_UNCONSTRAINED,\t-1, -1, 0, 0 }");
2119 * Print some courtesy debug information.
2121 if(range->left.type == ARE_VALUE
2122 || range->right.type == ARE_VALUE) {
2124 if(type) OUT("(%s", type);
2126 if(range->left.type == ARE_VALUE)
2127 OUT("%s", asn1p_itoa(range->left.value));
2131 if(range->right.type == ARE_VALUE)
2132 OUT("%s", asn1p_itoa(range->right.value));
2135 if(range->extensible) OUT(",...");
2144 emit_member_OER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx) {
2145 int save_target = arg->target->target;
2146 asn1cnst_range_t *range;
2147 asn1p_expr_type_e etype;
2149 etype = expr_get_type(arg, expr);
2151 if((arg->flags & A1C_GEN_OER)
2152 && (expr->combined_constraints || etype == ASN_BASIC_ENUMERATED
2153 || etype == ASN_CONSTR_CHOICE)) {
2161 OUT("static asn_oer_constraints_t "
2162 "asn_OER_%s_%s_constr_%d CC_NOTUSED = {\n",
2163 pfx, MKID(expr), expr->_type_unique_index);
2167 /* .value{.width,.positive} */
2168 range = asn1constraint_compute_OER_range(expr->Identifier, etype,
2169 expr->combined_constraints,
2170 ACT_EL_RANGE, 0, 0, 0);
2171 if(emit_single_member_OER_constraint_value(arg, range)) {
2174 emit_single_member_OER_constraint_comment(arg, range, 0);
2175 asn1constraint_range_free(range);
2180 range = asn1constraint_compute_OER_range(expr->Identifier, etype,
2181 expr->combined_constraints,
2182 ACT_CT_SIZE, 0, 0, 0);
2183 if(emit_single_member_OER_constraint_size(arg, range)) {
2186 emit_single_member_OER_constraint_comment(arg, range, "SIZE");
2187 asn1constraint_range_free(range);
2199 emit_member_PER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx) {
2200 int save_target = arg->target->target;
2201 asn1cnst_range_t *range;
2202 asn1p_expr_type_e etype;
2204 etype = expr_get_type(arg, expr);
2206 if((arg->flags & A1C_GEN_PER)
2207 && (expr->combined_constraints
2208 || etype == ASN_BASIC_ENUMERATED
2209 || etype == ASN_CONSTR_CHOICE
2210 || (etype & ASN_STRING_KM_MASK)
2218 if(expr->_type_referenced) {
2219 REDIR(OT_FUNC_DECLS);
2221 OUT("extern asn_per_constraints_t "
2222 "asn_PER_%s_%s_constr_%d;\n",
2223 pfx, MKID(expr), expr->_type_unique_index);
2228 if(!(expr->_type_referenced)) OUT("static ");
2229 OUT("asn_per_constraints_t "
2230 "asn_PER_%s_%s_constr_%d CC_NOTUSED = {\n",
2231 pfx, MKID(expr), expr->_type_unique_index);
2236 * ENUMERATED and CHOICE are special.
2238 if(etype == ASN_BASIC_ENUMERATED
2239 || etype == ASN_CONSTR_CHOICE) {
2240 asn1cnst_range_t tmprng;
2245 expr = asn1f_find_terminal_type_ex(arg->asn, arg->ns, expr);
2248 TQ_FOR(v, &(expr->members), next) {
2249 if(v->expr_type == A1TC_EXTENSIBLE) {
2256 memset(&tmprng, 0, sizeof (tmprng));
2257 tmprng.extensible = extensible;
2258 if(eidx < 0) tmprng.empty_constraint = 1;
2259 tmprng.left.type = ARE_VALUE;
2260 tmprng.left.value = 0;
2261 tmprng.right.type = ARE_VALUE;
2262 tmprng.right.value = eidx < 0 ? 0 : eidx;
2263 if(emit_single_member_PER_constraint(arg, &tmprng, 0, 0))
2265 } else if(etype & ASN_STRING_KM_MASK) {
2266 range = asn1constraint_compute_PER_range(expr->Identifier, etype,
2267 expr->combined_constraints, ACT_CT_FROM,
2269 DEBUG("Emitting FROM constraint for %s", expr->Identifier);
2271 if((range->left.type == ARE_MIN && range->right.type == ARE_MAX)
2272 || range->not_PER_visible) {
2274 case ASN_STRING_BMPString:
2275 range->left.type = ARE_VALUE;
2276 range->left.value = 0;
2277 range->right.type = ARE_VALUE;
2278 range->right.value = 65535;
2279 range->not_PER_visible = 0;
2280 range->extensible = 0;
2282 case ASN_STRING_UniversalString:
2283 OUT("{ APC_CONSTRAINED,\t32, 32,"
2285 " /* special case 1 */\n");
2291 if(emit_single_member_PER_constraint(arg, range, 1, 0))
2294 asn1constraint_range_free(range);
2296 range = asn1constraint_compute_PER_range(expr->Identifier, etype,
2297 expr->combined_constraints, ACT_EL_RANGE,
2299 if(emit_single_member_PER_constraint(arg, range, 0, 0))
2301 asn1constraint_range_free(range);
2305 range = asn1constraint_compute_PER_range(expr->Identifier, etype,
2306 expr->combined_constraints, ACT_CT_SIZE, 0, 0, 0);
2307 if(emit_single_member_PER_constraint(arg, range, 0, "SIZE"))
2309 asn1constraint_range_free(range);
2312 if((etype & ASN_STRING_KM_MASK) && (expr->_mark & TM_PERFROMCT)) {
2313 int old_target = arg->target->target;
2316 OUT("static int asn_PER_MAP_%s_%d_v2c(unsigned int value) {\n",
2317 MKID(expr), expr->_type_unique_index);
2318 OUT("\tif(value >= sizeof(permitted_alphabet_table_%d)/"
2319 "sizeof(permitted_alphabet_table_%d[0]))\n",
2320 expr->_type_unique_index,
2321 expr->_type_unique_index);
2322 OUT("\t\treturn -1;\n");
2323 OUT("\treturn permitted_alphabet_table_%d[value] - 1;\n",
2324 expr->_type_unique_index);
2327 OUT("static int asn_PER_MAP_%s_%d_c2v(unsigned int code) {\n",
2328 MKID(expr), expr->_type_unique_index);
2329 OUT("\tif(code >= sizeof(permitted_alphabet_code2value_%d)/"
2330 "sizeof(permitted_alphabet_code2value_%d[0]))\n",
2331 expr->_type_unique_index,
2332 expr->_type_unique_index);
2333 OUT("\t\treturn -1;\n");
2334 OUT("\treturn permitted_alphabet_code2value_%d[code];\n",
2335 expr->_type_unique_index);
2340 OUT("asn_PER_MAP_%s_%d_v2c,\t/* Value to PER code map */\n",
2341 MKID(expr), expr->_type_unique_index);
2342 OUT("asn_PER_MAP_%s_%d_c2v\t/* PER code to value map */\n",
2343 MKID(expr), expr->_type_unique_index);
2344 } else if(etype & ASN_STRING_KM_MASK) {
2345 DEBUG("No PER value map necessary for %s", MKID(expr));
2346 OUT("0, 0\t/* No PER character map necessary */\n");
2348 OUT("0, 0\t/* No PER value map */\n");
2361 safe_string(const uint8_t *buf, int size) {
2362 const uint8_t *end = buf + size;
2363 for(; buf < end; buf++) {
2365 if((ch < 0x20 || ch > 0x7e) || ch == '"')
2372 emit_default_string_value(arg_t *arg, asn1p_value_t *v) {
2374 OUT("static const uint8_t defv[] = ");
2375 assert(v->type == ATV_STRING);
2377 if(safe_string(v->value.string.buf, v->value.string.size)) {
2378 OUT("\"%s\";\n", v->value.string.buf);
2380 uint8_t *b = v->value.string.buf;
2381 uint8_t *e = v->value.string.size + b;
2384 OUT("0x%02x, ", *b);
2390 try_inline_default(arg_t *arg, asn1p_expr_t *expr, int out) {
2391 int save_target = arg->target->target;
2392 asn1p_expr_type_e etype = expr_get_type(arg, expr);
2396 case ASN_BASIC_BOOLEAN:
2399 case ASN_BASIC_INTEGER:
2400 case ASN_BASIC_ENUMERATED:
2401 if(expr->marker.default_value == NULL
2402 || (expr->marker.default_value->type != ATV_INTEGER &&
2403 expr->marker.default_value->type != ATV_TRUE &&
2404 expr->marker.default_value->type != ATV_FALSE))
2407 fits_long = asn1c_type_fits_long(arg, expr)!=FL_NOTFIT;
2408 if(fits_long && !expr->marker.default_value->value.v_integer)
2409 expr->marker.flags &= ~EM_INDIRECT;
2411 if(C99_MODE) OUT(".default_value_cmp = ");
2412 OUT("&asn_DFL_%d_cmp_%s,",
2413 expr->_type_unique_index,
2414 asn1p_itoa(expr->marker.default_value->value.v_integer));
2415 OUT("\t/* Compare DEFAULT %s */\n",
2416 asn1p_itoa(expr->marker.default_value->value.v_integer));
2417 if(C99_MODE) OUT(".default_value_set = ");
2418 OUT("&asn_DFL_%d_set_%s,",
2419 expr->_type_unique_index,
2420 asn1p_itoa(expr->marker.default_value->value.v_integer));
2421 OUT("\t/* Set DEFAULT %s */\n",
2422 asn1p_itoa(expr->marker.default_value->value.v_integer));
2425 REDIR(OT_STAT_DEFS);
2427 OUT("static int asn_DFL_%d_cmp_%s(const void *sptr) {\n",
2428 expr->_type_unique_index,
2429 asn1p_itoa(expr->marker.default_value->value.v_integer));
2431 OUT("const %s *st = sptr;\n", asn1c_type_name(arg, expr, TNF_CTYPE));
2434 OUT("\treturn -1; /* No value is not a default value */\n");
2437 OUT("/* Test default value %s */\n",
2438 asn1p_itoa(expr->marker.default_value->value.v_integer));
2440 OUT("return (*st != %s);\n",
2441 asn1p_itoa(expr->marker.default_value->value.v_integer));
2443 OUT("long value;\n");
2444 OUT("if(asn_INTEGER2long(st, &value))\n");
2445 OUT("\treturn -1;\n");
2446 OUT("return (value != %s);\n",
2447 asn1p_itoa(expr->marker.default_value->value.v_integer));
2452 OUT("static int asn_DFL_%d_set_%s(void **sptr) {\n",
2453 expr->_type_unique_index,
2454 asn1p_itoa(expr->marker.default_value->value.v_integer));
2456 OUT("%s *st = *sptr;\n", asn1c_type_name(arg, expr, TNF_CTYPE));
2459 OUT("\tst = (*sptr = CALLOC(1, sizeof(*st)));\n");
2460 OUT("\tif(!st) return -1;\n");
2463 OUT("/* Install default value %s */\n",
2464 asn1p_itoa(expr->marker.default_value->value.v_integer));
2467 OINT(expr->marker.default_value->value.v_integer);
2471 OUT("return asn_long2INTEGER(st, ");
2472 OINT(expr->marker.default_value->value.v_integer);
2480 case ASN_BASIC_NULL:
2481 //expr->marker.flags &= ~EM_INDIRECT;
2484 if(etype & ASN_STRING_KM_MASK) {
2485 if(expr->marker.default_value == NULL
2486 || expr->marker.default_value->type != ATV_STRING)
2489 if(C99_MODE) OUT(".default_value_cmp = ");
2490 OUT("&asn_DFL_%d_cmp,\t/* Compare DEFAULT \"%s\" */\n",
2491 expr->_type_unique_index,
2492 expr->marker.default_value->value.string.buf);
2493 if(C99_MODE) OUT(".default_value_set = ");
2494 OUT("&asn_DFL_%d_set,\t/* Set DEFAULT \"%s\" */\n",
2495 expr->_type_unique_index,
2496 expr->marker.default_value->value.string.buf);
2499 REDIR(OT_STAT_DEFS);
2501 OUT("static int asn_DFL_%d_cmp(const void *sptr) {\n",
2502 expr->_type_unique_index);
2504 emit_default_string_value(arg, expr->marker.default_value);
2505 OUT("const %s *st = sptr;\n", asn1c_type_name(arg, expr, TNF_CTYPE));
2508 OUT("\treturn -1; /* No value is not a default value */\n");
2511 OUT("if(st->size == (sizeof(defv) - 1)\n");
2512 OUT("&& memcmp(st->buf, &defv, sizeof(defv) - 1) == 0)\n");
2513 OUT("\treturn 0;\n");
2518 OUT("static int asn_DFL_%d_set(void **sptr) {\n",
2519 expr->_type_unique_index);
2521 emit_default_string_value(arg, expr->marker.default_value);
2522 OUT("%s *st = *sptr;\n", asn1c_type_name(arg, expr, TNF_CTYPE));
2523 OUT("uint8_t *nstr = MALLOC(sizeof(defv));\n");
2525 OUT("if(!nstr) return -1;\n");
2526 OUT("memcpy(nstr, defv, sizeof(defv));\n");
2529 OUT("\tFREEMEM(st->buf);\n");
2531 OUT("\tst = (*sptr = CALLOC(1, sizeof(*st)));\n");
2532 OUT("\tif(!st) { FREEMEM(nstr); return -1; }\n");
2534 OUT("st->buf = nstr;\n");
2535 OUT("st->size = sizeof(defv) - 1;\n");
2550 emit_member_type_selector(arg_t *arg, asn1p_expr_t *expr, asn1c_ioc_table_and_objset_t *opt_ioc) {
2551 int save_target = arg->target->target;
2552 asn1p_expr_t *parent_expr = arg->expr;
2554 const asn1p_constraint_t *crc =
2555 asn1p_get_component_relation_constraint(expr->combined_constraints);
2556 if(!crc || crc->el_count <= 1) {
2557 /* Not an Open Type, it seems. */
2562 const asn1p_ref_t *objset_ref =
2563 asn1c_get_information_object_set_reference_from_constraint(arg, crc);
2566 FATAL("Constraint %s does not look like it referst to a set type %s",
2567 asn1p_constraint_string(crc),
2568 opt_ioc->objset->Identifier);
2572 const char *objset_name;
2573 if(objset_ref->comp_count == 1) {
2574 objset_name = objset_ref->components[0].name;
2575 } else if(objset_ref->comp_count == 2) {
2576 if(strcmp(objset_ref->components[0].name,
2577 opt_ioc->objset->module->ModuleName)
2580 "Composite reference %s (from %s) does not look like it refers "
2581 "to the same module as %s from an object set type %s",
2582 asn1p_ref_string(objset_ref), asn1p_constraint_string(crc),
2583 opt_ioc->objset->module->ModuleName,
2584 opt_ioc->objset->Identifier);
2587 objset_name = objset_ref->components[1].name;
2589 FATAL("Reference %s (from %s) does not look like an object set type %s",
2590 asn1p_ref_string(objset_ref), asn1p_constraint_string(crc),
2591 opt_ioc->objset->Identifier);
2594 if(strcmp(objset_name, opt_ioc->objset->Identifier) != 0) {
2595 FATAL("Object Set references do not match: %s != %s", objset_name,
2596 opt_ioc->objset->Identifier);
2600 if(crc->el_count != 2 || crc->elements[1]->type != ACT_EL_VALUE
2601 || crc->elements[1]->value->type != ATV_REFERENCED
2602 || crc->elements[1]->value->value.reference->comp_count != 1) {
2604 "Do not know how to handle complex IoS constraints (%d components "
2605 "of constraint, %d components of reference %s) for %s at line "
2608 crc->el_count >= 2 && crc->elements[1]->type == ACT_EL_VALUE
2609 && crc->elements[1]->value->type == ATV_REFERENCED
2610 ? (signed)crc->elements[1]->value->value.reference->comp_count
2612 crc->el_count >= 2 && crc->elements[1]->type == ACT_EL_VALUE
2613 && crc->elements[1]->value->type == ATV_REFERENCED
2614 ? asn1p_ref_string(crc->elements[1]->value->value.reference)
2616 MKID(parent_expr), parent_expr->_lineno);
2621 const asn1p_ref_t *cref = crc->elements[1]->value->value.reference;
2622 const char *cname = cref->components[0].name;
2623 if(cname[0] == '@' && cname[1] != '.') {
2625 } else if(cname[0] == '@' && cname[1] == '.' && cname[2] != '.') {
2628 FATAL("Complex IoS reference %s can not be processed",
2629 asn1p_ref_string(cref));
2634 assert(opt_ioc != NULL);
2636 asn1p_expr_t *constraining_memb = NULL;
2637 TQ_FOR(constraining_memb, &(parent_expr->members), next) {
2638 if(strcmp(constraining_memb->Identifier, cname) == 0) {
2642 if(!constraining_memb) {
2643 FATAL("Can not find \"%s\" in %s at line %d", cname, MKID(parent_expr),
2644 parent_expr->_lineno);
2648 if(constraining_memb->meta_type != AMT_TYPEREF
2649 || constraining_memb->expr_type != A1TC_REFERENCE
2650 || constraining_memb->reference->comp_count != 2
2651 || constraining_memb->reference->components[1].lex_type
2652 != RLT_Amplowercase) {
2654 "Does not look like %s is a CLASS field reference (%s) on line "
2656 MKID(constraining_memb),
2657 constraining_memb->reference
2658 ? asn1p_ref_string(constraining_memb->reference)
2660 constraining_memb->_lineno);
2663 const char *cfield = constraining_memb->reference->components[1].name;
2665 ssize_t constraining_column = -1;
2666 for(size_t cn = 0; cn < opt_ioc->ioct->rows ? opt_ioc->ioct->row[0]->columns : 0;
2668 if(strcmp(cfield, opt_ioc->ioct->row[0]->column[cn].field->Identifier)
2670 constraining_column = cn;
2674 if(constraining_column < 0) {
2675 if(opt_ioc->ioct->rows == 0) {
2679 FATAL("Can not find referenced object class %s column %s\n",
2680 asn1p_ref_string(objset_ref), cfield);
2685 if(expr->meta_type != AMT_TYPEREF
2686 || expr->expr_type != A1TC_REFERENCE
2687 || expr->reference->comp_count != 2
2688 || ((expr->reference->components[1].lex_type
2689 != RLT_AmpUppercase)
2690 && (expr->reference->components[1].lex_type
2691 != RLT_Amplowercase))) {
2693 "Does not look like %s is a CLASS field reference (%s) denoting a type on line "
2697 ? asn1p_ref_string(expr->reference)
2702 const char *for_field = expr->reference->components[1].name;
2704 ssize_t for_column = -1;
2705 for(size_t cn = 0; cn < (opt_ioc->ioct->rows ? opt_ioc->ioct->row[0]->columns : 0);
2707 if(strcmp(for_field,
2708 opt_ioc->ioct->row[0]->column[cn].field->Identifier)
2714 if(for_column < 0) {
2715 FATAL("Can not find referenced object class column %s\n", for_field);
2720 OUT("static asn_type_selector_result_t\n");
2721 OUT("select_%s_", c_name(arg).compound_name);
2722 OUT("%s_type(const asn_TYPE_descriptor_t *parent_type, const void *parent_sptr) {\n", MKID(expr));
2725 OUT("asn_type_selector_result_t result = {0, 0};\n");
2726 OUT("const asn_ioc_set_t *itable = asn_IOS_%s_%d;\n", MKID(opt_ioc->objset),
2727 opt_ioc->objset->_type_unique_index);
2728 OUT("size_t constraining_column = %zu; /* %s */\n", constraining_column, cfield);
2729 OUT("size_t for_column = %zu; /* %s */\n", for_column, for_field);
2730 OUT("size_t row, presence_index = 0;\n");
2732 const char *tname = asn1c_type_name(arg, constraining_memb, TNF_SAFE);
2733 if(constraining_memb->marker.flags & EM_INDIRECT) {
2734 OUT("const void *memb_ptr = *(const void **)");
2735 OUT("((const char *)parent_sptr + offsetof(%s", c_name(arg).full_name);
2736 OUT(", %s));", MKID_safe(constraining_memb));
2737 OUT("if(!memb_ptr) return result;\n");
2741 switch(asn1c_type_fits_long(arg, constraining_memb)) {
2743 OUT("const %s_t *constraining_value = (const %s_t *)", tname, tname);
2746 case FL_FITS_SIGNED:
2747 OUT("const long *constraining_value = (const long *)");
2749 case FL_FITS_UNSIGN:
2750 OUT("const unsigned long *constraining_value = (const unsigned long *)");
2753 if(constraining_memb->marker.flags & EM_INDIRECT) {
2756 OUT("((const char *)parent_sptr + offsetof(%s", c_name(arg).full_name);
2757 OUT(", %s));\n", MKID_safe(constraining_memb));
2761 OUT("for(row=0; row < itable->rows_count; row++) {\n");
2762 OUT(" const asn_ioc_cell_t *constraining_cell = &itable->rows[row * itable->columns_count + constraining_column];\n");
2763 OUT(" const asn_ioc_cell_t *type_cell = &itable->rows[row * itable->columns_count + for_column];\n");
2765 OUT(" if(type_cell->cell_kind == aioc__undefined)\n");
2766 OUT(" continue;\n");
2768 OUT(" presence_index++;\n");
2769 OUT(" if(constraining_cell->type_descriptor->op->compare_struct(constraining_cell->type_descriptor, constraining_value, constraining_cell->value_sptr) == 0) {\n");
2770 OUT(" result.type_descriptor = type_cell->type_descriptor;\n");
2771 OUT(" result.presence_index = presence_index;\n");
2778 OUT("return result;\n");
2784 OUT("select_%s_", c_name(arg).compound_name);
2785 OUT("%s_type", MKID(expr));
2791 emit_member_table(arg_t *arg, asn1p_expr_t *expr, asn1c_ioc_table_and_objset_t *opt_ioc) {
2794 struct asn1p_type_tag_s outmost_tag_s;
2795 struct asn1p_type_tag_s *outmost_tag;
2796 int complex_contents;
2799 if(WITH_MODULE_NAMESPACE(
2800 expr->module, expr_ns,
2801 asn1f_fetch_outmost_tag(arg->asn, expr_ns, expr->module, expr,
2802 &outmost_tag_s, AFT_IMAGINARY_ANY))) {
2805 outmost_tag = &outmost_tag_s;
2810 if(is_open_type(arg, expr, opt_ioc)) {
2811 OUT("ATF_OPEN_TYPE | ");
2812 } else if(outmost_tag && outmost_tag->tag_value == -1) {
2813 OUT("ATF_ANY_TYPE | ");
2816 (expr->marker.flags & EM_INDIRECT)?"ATF_POINTER":"ATF_NOFLAGS");
2817 if((expr->marker.flags & EM_OMITABLE) == EM_OMITABLE) {
2821 tv && (tv->marker.flags & EM_OMITABLE) == EM_OMITABLE;
2822 tv = TQ_NEXT(tv, next), opts++) {
2823 if(tv->expr_type == A1TC_EXTENSIBLE)
2830 if(expr->_anonymous_type) {
2831 assert(arg->expr->expr_type == ASN_CONSTR_SET_OF
2832 || arg->expr->expr_type == ASN_CONSTR_SEQUENCE_OF);
2835 OUT("offsetof(%s, ", c_name(arg).full_name);
2836 if((arg->expr->expr_type == ASN_CONSTR_CHOICE
2837 || arg->expr->expr_type == ASN_CONSTR_OPEN_TYPE)
2838 && (!UNNAMED_UNIONS))
2840 OUT("%s),\n", MKID_safe(expr));
2844 if(C99_MODE) OUT(".tag = ");
2846 if(outmost_tag->tag_value == -1)
2847 OUT("-1 /* Ambiguous tag (ANY?) */");
2849 _print_tag(arg, outmost_tag);
2851 OUT("-1 /* Ambiguous tag (CHOICE?) */");
2855 if(C99_MODE) OUT(".tag_mode = ");
2856 if((!(expr->expr_type & ASN_CONSTR_MASK)
2857 || expr->expr_type == ASN_CONSTR_CHOICE)
2858 && expr->tag.tag_class) {
2859 if(expr->tag.tag_mode == TM_IMPLICIT)
2860 OUT("-1,\t/* IMPLICIT tag at current level */\n");
2862 OUT("+1,\t/* EXPLICIT tag at current level */\n");
2868 is_open_type(arg, expr, opt_ioc)
2869 || (expr->expr_type & ASN_CONSTR_MASK)
2870 || expr->expr_type == ASN_BASIC_ENUMERATED
2871 || (0 /* -- prohibited by X.693:8.3.4 */
2872 && expr->expr_type == ASN_BASIC_INTEGER
2873 && expr_elements_count(arg, expr))
2874 || (expr->expr_type == ASN_BASIC_INTEGER
2875 && asn1c_type_fits_long(arg, expr) == FL_FITS_UNSIGN);
2876 if(C99_MODE) OUT(".type = ");
2879 if(complex_contents) {
2880 OUT("%s", MKID(expr));
2881 if(!(arg->flags & A1C_ALL_DEFS_GLOBAL))
2882 OUT("_%d", expr->_type_unique_index);
2884 OUT("%s", asn1c_type_name(arg, expr, TNF_SAFE));
2889 if(C99_MODE) OUT(".type_selector = ");
2891 if(emit_member_type_selector(arg, expr, opt_ioc) < 0)
2899 if(C99_MODE) OUT(".oer_constraints = ");
2900 if(arg->flags & A1C_GEN_OER) {
2901 if(expr->constraints) {
2902 OUT("&asn_OER_memb_%s_constr_%d",
2904 expr->_type_unique_index);
2912 if(C99_MODE) OUT(".per_constraints = ");
2913 if(arg->flags & A1C_GEN_PER) {
2914 if(expr->constraints) {
2915 OUT("&asn_PER_memb_%s_constr_%d",
2917 expr->_type_unique_index);
2925 if(C99_MODE) OUT(".general_constraints = ");
2926 if(expr->constraints) {
2927 if(arg->flags & A1C_NO_CONSTRAINTS) {
2930 const char *id = MKID(expr);
2931 if(expr->_anonymous_type
2932 && !strcmp(expr->Identifier, "Member"))
2933 id = asn1c_type_name(arg, expr, TNF_SAFE);
2934 OUT(" memb_%s_constraint_%d", id,
2935 arg->expr->_type_unique_index);
2942 if(try_inline_default(arg, expr, 0)) {
2944 OUT("0, 0, /* No default value */\n");
2946 if(C99_MODE) OUT(".name = ");
2947 if(expr->_anonymous_type && !strcmp(expr->Identifier, "Member")) {
2950 OUT("\"%s\"\n", expr->Identifier);
2955 if(!expr->constraints || (arg->flags & A1C_NO_CONSTRAINTS))
2958 save_target = arg->target->target;
2961 if(expr->_anonymous_type && !strcmp(expr->Identifier, "Member"))
2962 p = asn1c_type_name(arg, expr, TNF_SAFE);
2965 OUT("static int\n");
2966 OUT("memb_%s_constraint_%d(const asn_TYPE_descriptor_t *td, const void *sptr,\n", p, arg->expr->_type_unique_index);
2968 OUT("\t\tasn_app_constraint_failed_f *ctfailcb, void *app_key) {\n");
2970 tmp_arg.expr = expr;
2971 DEBUG("member constraint checking code for %s", p);
2972 if(asn1c_emit_constraint_checking_code(&tmp_arg) == 1) {
2973 OUT("return td->encoding_constraints.general_constraints"
2974 "(td, sptr, ctfailcb, app_key);\n");
2980 if(emit_member_OER_constraints(arg, expr, "memb"))
2983 if(emit_member_PER_constraints(arg, expr, "memb"))
2992 * Generate "asn_DEF_XXX" type definition.
2995 emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, enum tvm_compat tv_mode, int tags_count, int all_tags_count, int elements_count, enum etd_spec spec) {
2996 asn1p_expr_t *terminal;
2997 int using_type_name = 0;
2998 char *expr_id = strdup(MKID(expr));
3000 char *p2 = (char *)0;
3002 terminal = asn1f_find_terminal_type_ex(arg->asn, arg->ns, expr);
3004 if(emit_member_OER_constraints(arg, expr, "type"))
3007 if(emit_member_PER_constraints(arg, expr, "type"))
3011 OUT("static /* Use -fall-defs-global to expose */\n");
3012 OUT("asn_TYPE_descriptor_t asn_DEF_%s", p);
3013 if(HIDE_INNER_DEFS || (arg->flags & A1C_ALL_DEFS_GLOBAL))
3014 OUT("_%d", expr->_type_unique_index);
3018 if(expr->_anonymous_type) {
3019 p = strdup(ASN_EXPR_TYPE2STR(expr->expr_type));
3020 OUT("\"%s\",\n", p?p:"");
3022 p ? asn1c_make_identifier(AMI_CHECK_RESERVED,
3025 OUT("\"%s\",\n", expr->Identifier);
3026 OUT("\"%s\",\n", expr->Identifier);
3029 if(expr->expr_type & ASN_CONSTR_MASK) {
3030 using_type_name = 1;
3031 p = strdup(asn1c_type_name(arg, arg->expr, TNF_SAFE));
3033 if (expr->expr_type == A1TC_REFERENCE) {
3034 p2 = strdup(asn1c_type_name(arg, terminal, TNF_SAFE));
3036 p2 = strdup(asn1c_type_name(arg, expr, TNF_SAFE));
3038 p = strdup(expr_id);
3043 OUT("&asn_OP_%s,\n", p2);
3046 OUT("asn_DEF_%s_tags_%d,\n",
3047 expr_id, expr->_type_unique_index);
3048 OUT("sizeof(asn_DEF_%s_tags_%d)\n",
3049 expr_id, expr->_type_unique_index);
3050 OUT("\t/sizeof(asn_DEF_%s_tags_%d[0])",
3051 expr_id, expr->_type_unique_index);
3052 if(tv_mode == _TVM_SUBSET
3053 && tags_count != all_tags_count)
3054 OUT(" - %d", all_tags_count - tags_count);
3055 OUT(", /* %d */\n", tags_count);
3057 OUT("0,\t/* No effective tags (pointer) */\n");
3058 OUT("0,\t/* No effective tags (count) */\n");
3061 if(all_tags_count && tv_mode == _TVM_DIFFERENT) {
3062 OUT("asn_DEF_%s_all_tags_%d,\n",
3063 expr_id, expr->_type_unique_index);
3064 OUT("sizeof(asn_DEF_%s_all_tags_%d)\n",
3065 expr_id, expr->_type_unique_index);
3066 OUT("\t/sizeof(asn_DEF_%s_all_tags_%d[0]), /* %d */\n",
3067 expr_id, expr->_type_unique_index, all_tags_count);
3068 } else if(all_tags_count) {
3069 OUT("asn_DEF_%s_tags_%d,\t/* Same as above */\n",
3070 expr_id, expr->_type_unique_index);
3071 OUT("sizeof(asn_DEF_%s_tags_%d)\n",
3072 expr_id, expr->_type_unique_index);
3073 OUT("\t/sizeof(asn_DEF_%s_tags_%d[0]), /* %d */\n",
3074 expr_id, expr->_type_unique_index, all_tags_count);
3076 OUT("0,\t/* No tags (pointer) */\n");
3077 OUT("0,\t/* No tags (count) */\n");
3081 if(arg->flags & A1C_GEN_OER) {
3082 if(expr->combined_constraints
3083 || expr->expr_type == ASN_BASIC_ENUMERATED
3084 || expr->expr_type == ASN_CONSTR_CHOICE) {
3085 OUT("&asn_OER_type_%s_constr_%d",
3086 expr_id, expr->_type_unique_index);
3095 if(arg->flags & A1C_GEN_PER) {
3096 if(expr->combined_constraints
3097 || expr->expr_type == ASN_BASIC_ENUMERATED
3098 || expr->expr_type == ASN_CONSTR_CHOICE
3099 || (expr->expr_type & ASN_STRING_KM_MASK)) {
3100 OUT("&asn_PER_type_%s_constr_%d",
3101 expr_id, expr->_type_unique_index);
3109 #define FUNCREF(foo) \
3112 if(HIDE_INNER_DEFS && !using_type_name) \
3113 OUT("_%d", expr->_type_unique_index); \
3117 #define FUNCREF2(foo) \
3123 if (arg->flags & A1C_NO_CONSTRAINTS) {
3126 if (!expr->combined_constraints)
3127 FUNCREF2(constraint);
3129 FUNCREF(constraint);
3140 if(elements_count ||
3141 ((expr->expr_type == A1TC_REFERENCE) &&
3142 (terminal->expr_type & ASN_CONSTR_MASK) &&
3143 expr_elements_count(arg, terminal))) {
3145 if (expr->expr_type == A1TC_REFERENCE) {
3146 OUT("asn_MBR_%s_%d,\n", MKID(terminal), terminal->_type_unique_index);
3148 if(terminal->expr_type == ASN_CONSTR_SEQUENCE_OF
3149 || terminal->expr_type == ASN_CONSTR_SET_OF) {
3150 OUT("%d,\t/* Single element */\n",
3151 expr_elements_count(arg, terminal));
3152 assert(expr_elements_count(arg, terminal) == 1);
3154 OUT("%d,\t/* Elements count */\n",
3155 expr_elements_count(arg, terminal));
3158 OUT("asn_MBR_%s_%d,\n", c_name(arg).part_name,
3159 expr->_type_unique_index);
3161 if(expr->expr_type == ASN_CONSTR_SEQUENCE_OF
3162 || expr->expr_type == ASN_CONSTR_SET_OF) {
3163 OUT("%d,\t/* Single element */\n",
3165 assert(elements_count == 1);
3167 OUT("%d,\t/* Elements count */\n",
3172 if(expr_elements_count(arg, expr))
3173 OUT("0, 0,\t/* Defined elsewhere */\n");
3175 OUT("0, 0,\t/* No members */\n");
3179 case ETD_NO_SPECIFICS:
3180 if ((expr->expr_type == A1TC_REFERENCE) &&
3181 ((terminal->expr_type & ASN_CONSTR_MASK) ||
3182 (terminal->expr_type == ASN_BASIC_ENUMERATED) ||
3183 ((terminal->expr_type == ASN_BASIC_INTEGER) &&
3184 (asn1c_type_fits_long(arg, terminal) == FL_FITS_UNSIGN)))) {
3185 OUT("&asn_SPC_%s_specs_%d\t/* Additional specs */\n",
3186 c_expr_name(arg, terminal).part_name,
3187 terminal->_type_unique_index);
3188 } else if ((expr->expr_type == ASN_TYPE_ANY) ||
3189 (expr->expr_type == ASN_BASIC_BIT_STRING) ||
3190 (expr->expr_type == ASN_STRING_BMPString) ||
3191 (expr->expr_type == ASN_BASIC_OCTET_STRING) ||
3192 (expr->expr_type == ASN_STRING_UniversalString)) {
3193 OUT("&asn_SPC_%s_specs\t/* Additional specs */\n",
3194 c_name(arg).type.part_name);
3195 } else if ((expr->expr_type == A1TC_REFERENCE) &&
3196 ((terminal->expr_type == ASN_TYPE_ANY) ||
3197 (terminal->expr_type == ASN_BASIC_BIT_STRING) ||
3198 (terminal->expr_type == ASN_STRING_BMPString) ||
3199 (terminal->expr_type == ASN_BASIC_OCTET_STRING) ||
3200 (terminal->expr_type == ASN_STRING_UniversalString))) {
3201 OUT("&asn_SPC_%s_specs\t/* Additional specs */\n",
3202 c_expr_name(arg, terminal).type.part_name);
3204 OUT("0\t/* No specifics */\n");
3207 case ETD_HAS_SPECIFICS:
3208 OUT("&asn_SPC_%s_specs_%d\t/* Additional specs */\n",
3209 c_name(arg).part_name, expr->_type_unique_index);
3219 expr_as_xmlvaluelist(arg_t *arg, asn1p_expr_t *expr) {
3221 * X.680, 25.5, Table 5
3223 switch(expr_get_type(arg, expr)) {
3224 case ASN_BASIC_BOOLEAN:
3225 case ASN_BASIC_ENUMERATED:
3226 case ASN_BASIC_NULL:
3228 case ASN_CONSTR_CHOICE:
3236 out_name_chain(arg_t *arg, enum onc_flags onc_flags) {
3237 asn1p_expr_t *expr = arg->expr;
3240 if((arg->flags & A1C_COMPOUND_NAMES
3241 || onc_flags & ONC_force_compound_name
3242 || (0 && arg->embed /* Not yet */))
3243 && ((expr->expr_type & ASN_CONSTR_MASK)
3244 || expr->expr_type == ASN_BASIC_ENUMERATED
3245 || ((expr->expr_type == ASN_BASIC_INTEGER
3246 || expr->expr_type == ASN_BASIC_BIT_STRING)
3247 && expr_elements_count(arg, expr))
3249 && expr->parent_expr) {
3251 arg_t tmparg = *arg;
3253 tmparg.expr = expr->parent_expr;
3254 if(0) tmparg.flags &= ~A1C_COMPOUND_NAMES;
3256 out_name_chain(&tmparg, onc_flags);
3258 if(expr->parent_expr->Identifier) OUT("__"); /* a separator between id components */
3263 if(onc_flags & ONC_avoid_keywords)
3264 id = MKID_safe(expr);
3273 emit_include_dependencies(arg_t *arg) {
3274 asn1p_expr_t *expr = arg->expr;
3277 /* Avoid recursive definitions. */
3278 TQ_FOR(memb, &(expr->members), next) {
3279 expr_break_recursion(arg, memb);
3282 TQ_FOR(memb, &(expr->members), next) {
3284 if(memb->marker.flags & (EM_INDIRECT | EM_UNRECURSE)) {
3285 if(terminal_structable(arg, memb)) {
3286 int saved_target = arg->target->target;
3287 if(saved_target != OT_FWD_DECLS) {
3288 REDIR(OT_FWD_DECLS);
3290 asn1c_type_name(arg, memb, TNF_RSAFE));
3292 REDIR(saved_target);
3296 if((!(memb->expr_type & ASN_CONSTR_MASK)
3297 && memb->expr_type > ASN_CONSTR_MASK)
3298 || memb->meta_type == AMT_TYPEREF) {
3299 GEN_POS_INCLUDE_BASE((memb->marker.flags & EM_UNRECURSE) ?
3300 OT_POST_INCLUDE : OT_INCLUDES, memb);
3308 * Check if it is better to make this type indirectly accessed via
3310 * This may be the case for the following recursive definition:
3311 * Type ::= CHOICE { member Type };
3314 expr_break_recursion(arg_t *arg, asn1p_expr_t *expr) {
3317 if(expr->marker.flags & EM_UNRECURSE)
3318 return 1; /* Already broken */
3320 /* -findirect-choice compiles members of CHOICE as indirect pointers */
3321 if((arg->flags & A1C_INDIRECT_CHOICE)
3322 && arg->expr->expr_type == ASN_CONSTR_CHOICE
3323 && (expr_get_type(arg, expr) & ASN_CONSTR_MASK)
3325 /* Break cross-reference */
3326 expr->marker.flags |= EM_INDIRECT | EM_UNRECURSE;
3330 if((expr->marker.flags & EM_INDIRECT)
3331 || arg->expr->expr_type == ASN_CONSTR_SET_OF
3332 || arg->expr->expr_type == ASN_CONSTR_SEQUENCE_OF) {
3333 if(terminal_structable(arg, expr)) {
3334 expr->marker.flags |= EM_UNRECURSE;
3336 if(arg->expr->expr_type == ASN_CONSTR_SET_OF
3337 || arg->expr->expr_type == ASN_CONSTR_SEQUENCE_OF) {
3338 /* Don't put EM_INDIRECT even if recursion */
3346 /* Look for recursive back-references */
3347 ret = expr_defined_recursively(arg, expr);
3349 case 2: /* Explicitly break the recursion */
3350 case 1: /* Use safer typing */
3351 expr->marker.flags |= EM_INDIRECT;
3352 expr->marker.flags |= EM_UNRECURSE;
3360 * Check if the type can be represented using simple `struct TYPE`.
3362 static asn1p_expr_t *
3363 terminal_structable(arg_t *arg, asn1p_expr_t *expr) {
3364 asn1p_expr_t *terminal =
3365 asn1f_find_terminal_type_ex(arg->asn, arg->ns, expr);
3367 && !terminal->parent_expr
3368 && (terminal->expr_type & ASN_CONSTR_MASK)) {
3375 asn1c_recurse(arg_t *arg, asn1p_expr_t *expr, int (*callback)(arg_t *arg, void *key), void *key) {
3380 if(expr->_mark & TM_RECURSION) return 0;
3381 expr->_mark |= TM_RECURSION;
3383 /* Invoke callback for every type going into recursion */
3385 maxret = callback(&tmp, key);
3388 * Recursively invoke myself and the callbacks.
3390 TQ_FOR(tmp.expr, &(expr->members), next) {
3391 ret = asn1c_recurse(&tmp, tmp.expr, callback, key);
3394 if(maxret > 1) break;
3398 expr->_mark &= ~TM_RECURSION;
3403 check_is_refer_to(arg_t *arg, void *key) {
3404 asn1p_expr_t *terminal = terminal_structable(arg, arg->expr);
3405 if(terminal == key) {
3406 if(arg->expr->marker.flags & EM_INDIRECT)
3407 return 1; /* This is almost safe indirection */
3409 } else if(terminal) {
3410 /* This might be N-step circular loop. Dive into it. */
3411 return asn1c_recurse(arg, terminal, check_is_refer_to, key);
3417 * Check if the possibly inner expression defined recursively.
3420 expr_defined_recursively(arg_t *arg, asn1p_expr_t *expr) {
3421 asn1p_expr_t *terminal;
3422 asn1p_expr_t *topmost;
3424 /* If expression is top-level, there's no way it can be recursive. */
3425 if(expr->parent_expr == 0) return 0;
3426 if(expr->expr_type != A1TC_REFERENCE)
3427 return 0; /* Basic types are never recursive */
3429 terminal = terminal_structable(arg, expr);
3430 if(!terminal) return 0; /* Terminal cannot be indirected */
3432 /* Search for the parent container for the given expression */
3434 while(topmost->parent_expr)
3435 topmost = topmost->parent_expr;
3437 /* Look inside the terminal type if it mentions the parent expression */
3438 return asn1c_recurse(arg, terminal, check_is_refer_to, topmost);
3441 struct canonical_map_element {
3445 static int compar_cameo(const void *ap, const void *bp);
3446 static arg_t *cameo_arg;
3448 compute_canonical_members_order(arg_t *arg, int el_count) {
3449 struct canonical_map_element *cmap;
3453 int first_extension = -1;
3455 int already_sorted = 1;
3457 cmap = calloc(el_count, sizeof *cmap);
3460 TQ_FOR(v, &(arg->expr->members), next) {
3461 if(v->expr_type != A1TC_EXTENSIBLE) {
3462 cmap[eidx].eidx = eidx;
3463 cmap[eidx].expr = v;
3465 } else if(first_extension == -1)
3466 first_extension = eidx;
3470 if(first_extension == -1) {
3471 /* Sort the whole thing */
3472 qsort(cmap, el_count, sizeof(*cmap), compar_cameo);
3474 /* Sort root and extensions independently */
3475 qsort(cmap, first_extension, sizeof(*cmap), compar_cameo);
3476 qsort(cmap + first_extension, el_count - first_extension,
3477 sizeof(*cmap), compar_cameo);
3480 /* move data back to a simpler map */
3481 rmap = calloc(el_count, sizeof *rmap);
3483 for(eidx = 0; eidx < el_count; eidx++) {
3484 rmap[eidx] = cmap[eidx].eidx;
3485 if(rmap[eidx] <= nextmax)
3488 nextmax = rmap[eidx];
3492 if(already_sorted) { free(rmap); rmap = 0; }
3495 static int compar_cameo(const void *ap, const void *bp) {
3496 const struct canonical_map_element *a = (const void *)ap;
3497 const struct canonical_map_element *b = (const void *)bp;
3498 struct asn1p_type_tag_s atag, btag;
3499 arg_t *arg = cameo_arg;
3501 if(WITH_MODULE_NAMESPACE(a->expr->module, expr_ns,
3502 asn1f_fetch_outmost_tag(
3503 arg->asn, expr_ns, a->expr->module, a->expr,
3504 &atag, AFT_IMAGINARY_ANY | AFT_CANON_CHOICE)))
3507 if(WITH_MODULE_NAMESPACE(
3508 b->expr->module, expr_ns,
3509 asn1f_fetch_outmost_tag(arg->asn, expr_ns, b->expr->module, b->expr,
3511 AFT_IMAGINARY_ANY | AFT_CANON_CHOICE))) {
3515 if(atag.tag_class < btag.tag_class)
3517 if(atag.tag_class > btag.tag_class)
3519 if(atag.tag_value < btag.tag_value)
3521 if(atag.tag_value > btag.tag_value)