From 4ec3b4c088904c50ffc8c8ad06e11214d964e8c4 Mon Sep 17 00:00:00 2001 From: Lev Walkin <vlm@lionet.info> Date: Sun, 22 Aug 2004 03:09:24 +0000 Subject: [PATCH] COMPONENTS OF support --- libasn1fix/asn1fix.c | 13 ++++-- libasn1fix/asn1fix_constr.c | 85 ++++++++++++++++++++++++++++++++++--- libasn1fix/asn1fix_constr.h | 5 +++ 3 files changed, 95 insertions(+), 8 deletions(-) diff --git a/libasn1fix/asn1fix.c b/libasn1fix/asn1fix.c index 2a78aa13..48100791 100644 --- a/libasn1fix/asn1fix.c +++ b/libasn1fix/asn1fix.c @@ -117,7 +117,9 @@ asn1f_fix_module(arg_t *arg) { 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 @@ asn1f_fix_constructed(arg_t *arg) { 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 @@ asn1f_fix_constraints(arg_t *arg) { 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 4db233f6..1574c814 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 @@ asn1f_fix_constr_autotag(arg_t *arg) { 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 @@ static int _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 @@ _asn1f_compare_tags(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) { 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 aeb05c0a..59970adf 100644 --- a/libasn1fix/asn1fix_constr.h +++ b/libasn1fix/asn1fix_constr.h @@ -1,6 +1,11 @@ #ifndef _ASN1FIX_CONSTRUCTED_H_ #define _ASN1FIX_CONSTRUCTED_H_ +/* + * Pull in COMPONENTS OF. + */ +int asn1f_pull_components_of(arg_t *); + /* * Fix extensions in constructed types. */ -- GitLab