diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c index c51f9982..e3669fd2 100644 --- a/libasn1compiler/asn1c_C.c +++ b/libasn1compiler/asn1c_C.c @@ -410,6 +410,20 @@ asn1c_lang_C_type_SEQUENCE(arg_t *arg) { return asn1c_lang_C_type_SEQUENCE_def(arg, ioc_tao.ioct ? &ioc_tao : 0); } +static void +emit_tag2member_reference(arg_t *arg, asn1p_expr_t *expr, + unsigned tag2el_count) { + if(tag2el_count) { + if(C99_MODE) OUT(".tag2el = "); + OUT("asn_MAP_%s_tag2el_%d,\n", MKID(expr), expr->_type_unique_index); + if(C99_MODE) OUT(".tag2el_count = "); + OUT("%d,\t/* Count of tags in the map */\n", tag2el_count); + } else { + OUT("0,\t/* No top level tags */\n"); + OUT("0,\t/* No tags in the map */\n"); + } +} + static int asn1c_lang_C_type_SEQUENCE_def(arg_t *arg, asn1c_ioc_table_and_objset_t *opt_ioc) { asn1p_expr_t *expr = arg->expr; @@ -540,16 +554,7 @@ asn1c_lang_C_type_SEQUENCE_def(arg_t *arg, asn1c_ioc_table_and_objset_t *opt_ioc out_name_chain(arg, ONC_avoid_keywords); OUT("),\n"); OUT("offsetof(struct "); out_name_chain(arg, ONC_avoid_keywords); OUT(", _asn_ctx),\n"); - - if(tag2el_count) { - OUT("asn_MAP_%s_tag2el_%d,\n", - MKID(expr), - expr->_type_unique_index); - OUT("%d,\t/* Count of tags in the map */\n", tag2el_count); - } else { - OUT("0,\t/* No top level tags */\n"); - OUT("0,\t/* No tags in the map */\n"); - } + emit_tag2member_reference(arg, expr, tag2el_count); if(roms_count + aoms_count) { OUT("asn_MAP_%s_oms_%d,\t/* Optional members */\n", MKID(expr), expr->_type_unique_index); @@ -784,9 +789,8 @@ asn1c_lang_C_type_SET_def(arg_t *arg) { OUT("offsetof(struct "); out_name_chain(arg, ONC_avoid_keywords); OUT(", _presence_map),\n"); + emit_tag2member_reference(arg, expr, tag2el_count); p = MKID(expr); - OUT("asn_MAP_%s_tag2el_%d,\n", p, expr->_type_unique_index); - OUT("%d,\t/* Count of tags in the map */\n", tag2el_count); if(tag2el_cxer) OUT("asn_MAP_%s_tag2el_cxer_%d,\n", p, expr->_type_unique_index); @@ -1227,9 +1231,7 @@ asn1c_lang_C_type_CHOICE_def(arg_t *arg) { OUT("sizeof(((struct "); out_name_chain(arg, ONC_avoid_keywords); OUT(" *)0)->present),\n"); - OUT("asn_MAP_%s_tag2el_%d,\n", - MKID(expr), expr->_type_unique_index); - OUT("%d,\t/* Count of tags in the map */\n", tag2el_count); + emit_tag2member_reference(arg, expr, tag2el_count); if(C99_MODE) OUT(".canonical_order = "); if(cmap) OUT("asn_MAP_%s_cmap_%d,\t/* Canonically sorted */\n", MKID(expr), expr->_type_unique_index); @@ -2715,13 +2717,35 @@ emit_member_type_selector(arg_t *arg, asn1p_expr_t *expr, asn1c_ioc_table_and_ob const asn1p_ref_t *objset_ref = asn1c_get_information_object_set_reference_from_constraint(arg, crc); - if(!objset_ref || objset_ref->comp_count != 1) { - FATAL("Reference %s does not look like an object set type %s", - asn1p_constraint_string(crc), asn1p_ref_string(objset_ref)); + if(!objset_ref) { + FATAL("Constraint %s does not look like it referst to a set type %s", + asn1p_constraint_string(crc), + opt_ioc->objset->Identifier); return -1; } - const char *objset_name = objset_ref->components[0].name; + const char *objset_name; + if(objset_ref->comp_count == 1) { + objset_name = objset_ref->components[0].name; + } else if(objset_ref->comp_count == 2) { + if(strcmp(objset_ref->components[0].name, + opt_ioc->objset->module->ModuleName) + != 0) { + FATAL( + "Composite reference %s (from %s) does not look like it refers " + "to the same module as %s from an object set type %s", + asn1p_ref_string(objset_ref), asn1p_constraint_string(crc), + opt_ioc->objset->module->ModuleName, + opt_ioc->objset->Identifier); + return -1; + } + objset_name = objset_ref->components[1].name; + } else { + FATAL("Reference %s (from %s) does not look like an object set type %s", + asn1p_ref_string(objset_ref), asn1p_constraint_string(crc), + opt_ioc->objset->Identifier); + return -1; + } if(strcmp(objset_name, opt_ioc->objset->Identifier) != 0) { FATAL("Object Set references do not match: %s != %s", objset_name, opt_ioc->objset->Identifier); diff --git a/libasn1fix/asn1fix_cws.c b/libasn1fix/asn1fix_cws.c index 8965b962..1106e555 100644 --- a/libasn1fix/asn1fix_cws.c +++ b/libasn1fix/asn1fix_cws.c @@ -1,8 +1,6 @@ #include "asn1fix_internal.h" #include "asn1fix_cws.h" -const char *asn1p_constraint_string(const asn1p_constraint_t *); - static int _asn1f_parse_class_object_data(arg_t *, asn1p_expr_t *eclass, struct asn1p_ioc_row_s *row, asn1p_wsyntx_t *syntax, const uint8_t *buf, const uint8_t *bend, @@ -181,25 +179,28 @@ static int _asn1f_foreach_unparsed(arg_t *arg, const asn1p_constraint_t *ct, int (*process)(const uint8_t *buf, size_t size, void *key), - void *key) { + void *keyp) { + struct parse_object_key *key = keyp; if(!ct) return -1; switch(ct->type) { default: - DEBUG("Constraint %s is of unknown type for CWS", - asn1p_constraint_string(ct)); + DEBUG("Constraint is of unknown type %d for CWS", ct->type); return -1; case ACT_EL_EXT: /* ... */ + if(key) { + key->expr->ioc_table->extensible = 1; + } return 0; case ACT_CA_UNI: /* | */ - return _asn1f_foreach_unparsed_union(ct, process, key); + return _asn1f_foreach_unparsed_union(ct, process, keyp); case ACT_CA_CSV: /* , */ break; } for(size_t i = 0; i < ct->el_count; i++) { const asn1p_constraint_t *ct1 = ct->elements[i]; - if(_asn1f_foreach_unparsed(arg, ct1, process, key) != 0) { + if(_asn1f_foreach_unparsed(arg, ct1, process, keyp) != 0) { return -1; } }