COMPONENTS OF support
git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@180 59561ff5-6e30-0410-9f3c-9617f08c8826
diff --git a/libasn1fix/asn1fix.c b/libasn1fix/asn1fix.c
index 2a78aa1..4810079 100644
--- a/libasn1fix/asn1fix.c
+++ b/libasn1fix/asn1fix.c
@@ -117,7 +117,9 @@
switch((arg->mod->module_flags & MSF_MASK_INSTRUCTIONS)) {
case MSF_NOFLAGS:
- //arg->mod->module_flags |= MSF_TAG_INSTRUCTIONS;
+ /*
+ * arg->mod->module_flags |= MSF_TAG_INSTRUCTIONS;
+ */
break;
case MSF_unk_INSTRUCTIONS:
WARNING("Module %s defined with unrecognized "
@@ -277,6 +279,10 @@
ret = asn1f_fix_constr_tag(arg);
RET2RVAL(ret, rvalue);
+ /* Import COMPONENTS OF stuff */
+ ret = asn1f_pull_components_of(arg);
+ RET2RVAL(ret, rvalue);
+
return rvalue;
}
@@ -287,12 +293,13 @@
int rvalue = 0;
int ret;
- top_parent = asn1f_find_terminal_type(arg, arg->expr, NULL);
+ top_parent = asn1f_find_terminal_type(arg, arg->expr);
if(top_parent)
etype = top_parent->expr_type;
else etype = A1TC_INVALID;
- ret = asn1constraint_resolve(arg, arg->expr->constraints, etype, 0);
+ ret = asn1constraint_resolve(arg, arg->expr->module,
+ arg->expr->constraints, etype, 0);
RET2RVAL(ret, rvalue);
ret = asn1constraint_pullup(arg);
diff --git a/libasn1fix/asn1fix_constr.c b/libasn1fix/asn1fix_constr.c
index 4db233f..1574c81 100644
--- a/libasn1fix/asn1fix_constr.c
+++ b/libasn1fix/asn1fix_constr.c
@@ -3,6 +3,79 @@
static int _asn1f_check_if_tag_must_be_explicit(arg_t *arg, asn1p_expr_t *v);
static int _asn1f_compare_tags(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b);
+int
+asn1f_pull_components_of(arg_t *arg) {
+ TQ_HEAD(asn1p_expr_t) list;
+ asn1p_expr_t *expr = arg->expr;
+ asn1p_expr_t *memb;
+ int r_value = 0;
+
+ switch(expr->expr_type) {
+ case ASN_CONSTR_SEQUENCE:
+ case ASN_CONSTR_SET:
+ break;
+ default:
+ return 0;
+ }
+
+ TQ_INIT(&list);
+
+ /*
+ * Look into
+ */
+ while((memb = TQ_REMOVE(&(expr->members), next))) {
+ asn1p_expr_t *coft; /* COMPONENTS OF thing itself */
+ asn1p_expr_t *terminal; /* Terminal of the referenced type */
+
+ if(memb->expr_type != A1TC_COMPONENTS_OF) {
+ TQ_ADD(&list, memb, next);
+ continue;
+ }
+
+ coft = TQ_FIRST(&memb->members);
+ assert(coft);
+ assert(!TQ_NEXT(coft, next));
+
+ /*
+ * Find the referenced type.
+ */
+ terminal = asn1f_find_terminal_type(arg, coft);
+ if(!terminal || (terminal->expr_type != expr->expr_type)) {
+ FATAL("COMPONENTS OF at line %d "
+ "must reference a %s type",
+ coft->_lineno,
+ expr->expr_type==ASN_CONSTR_SET
+ ? "SET" : "SEQUENCE"
+ );
+ TQ_ADD(&list, memb, next);
+ r_value = -1;
+ continue;
+ }
+
+ /*
+ * Clone the final structure.
+ */
+
+ coft = asn1p_expr_clone(terminal, 1 /* Skip extensions */);
+ if(!coft) return -1; /* ENOMEM */
+
+ asn1p_expr_free(memb); /* Don't need it anymore*/
+
+ /*
+ * Move all components of the cloned structure
+ * into the current one.
+ */
+ while((memb = TQ_REMOVE(&(coft->members), next)))
+ TQ_ADD(&list, memb, next);
+
+ asn1p_expr_free(coft); /* Remove wrapper */
+ }
+
+ /* Move the stuff back */
+ TQ_HEAD_COPY(&(expr->members), &list);
+
+ return r_value;
+}
int
asn1f_fix_constr_ext(arg_t *arg) {
@@ -203,7 +276,10 @@
if(v->expr_type == A1TC_EXTENSIBLE)
break;
- assert(v->tag.tag_class == TC_NOCLASS);
+ if(0) {
+ /* This may be not true in case COMPONENTS OF */
+ assert(v->tag.tag_class == TC_NOCLASS);
+ }
must_explicit = _asn1f_check_if_tag_must_be_explicit(arg, v);
@@ -259,7 +335,7 @@
_asn1f_check_if_tag_must_be_explicit(arg_t *arg, asn1p_expr_t *v) {
asn1p_expr_t *reft;
- reft = asn1f_find_terminal_type(arg, v, 0);
+ reft = asn1f_find_terminal_type(arg, v);
if(reft) {
switch(reft->expr_type) {
case ASN_CONSTR_CHOICE:
@@ -329,13 +405,12 @@
b->Identifier, b->expr_type);
if(a->meta_type == AMT_TYPEREF) {
- asn1p_module_t *mod;
DEBUG(" %s is a type reference", a->Identifier);
- a = asn1f_lookup_symbol(arg, a->reference, &mod);
+ a = asn1f_lookup_symbol(arg, a->module, a->reference);
if(!a) return 0; /* Already FATAL()'ed somewhere else */
- WITH_MODULE(mod, ret = _asn1f_compare_tags(arg, a, b));
+ WITH_MODULE(a->module, ret = _asn1f_compare_tags(arg, a, b));
return ret;
}
diff --git a/libasn1fix/asn1fix_constr.h b/libasn1fix/asn1fix_constr.h
index aeb05c0..59970ad 100644
--- a/libasn1fix/asn1fix_constr.h
+++ b/libasn1fix/asn1fix_constr.h
@@ -2,6 +2,11 @@
#define _ASN1FIX_CONSTRUCTED_H_
/*
+ * Pull in COMPONENTS OF.
+ */
+int asn1f_pull_components_of(arg_t *);
+
+/*
* Fix extensions in constructed types.
*/
int asn1f_fix_constr_ext(arg_t *);