mirror of https://gerrit.osmocom.org/asn1c
more support for parametrized type; additional ANY support
git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@246 59561ff5-6e30-0410-9f3c-9617f08c8826
This commit is contained in:
parent
55d20cff3b
commit
7614245854
|
@ -158,18 +158,24 @@ asn1f_fix_module(arg_t *arg) {
|
||||||
ret = asn1f_recurse_expr(arg, asn1f_fix_simple);
|
ret = asn1f_recurse_expr(arg, asn1f_fix_simple);
|
||||||
RET2RVAL(ret, rvalue);
|
RET2RVAL(ret, rvalue);
|
||||||
|
|
||||||
/*
|
|
||||||
* 2.[234] Process SEQUENCE/SET/CHOICE types.
|
|
||||||
*/
|
|
||||||
ret = asn1f_recurse_expr(arg, asn1f_fix_constructed);
|
|
||||||
RET2RVAL(ret, rvalue);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 2.5.4
|
* 2.5.4
|
||||||
*/
|
*/
|
||||||
ret = asn1f_recurse_expr(arg, asn1f_fix_dereference_types);
|
ret = asn1f_recurse_expr(arg, asn1f_fix_dereference_types);
|
||||||
RET2RVAL(ret, rvalue);
|
RET2RVAL(ret, rvalue);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fix tagging of top-level types.
|
||||||
|
*/
|
||||||
|
ret = asn1f_fix_constr_tag(arg, 1);
|
||||||
|
RET2RVAL(ret, rvalue);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 2.[234] Process SEQUENCE/SET/CHOICE types.
|
||||||
|
*/
|
||||||
|
ret = asn1f_recurse_expr(arg, asn1f_fix_constructed);
|
||||||
|
RET2RVAL(ret, rvalue);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 2.5.5
|
* 2.5.5
|
||||||
*/
|
*/
|
||||||
|
@ -239,6 +245,10 @@ asn1f_fix_module(arg_t *arg) {
|
||||||
TQ_FOR(expr, &(arg->mod->members), next) {
|
TQ_FOR(expr, &(arg->mod->members), next) {
|
||||||
arg->expr = expr;
|
arg->expr = expr;
|
||||||
|
|
||||||
|
if(arg->expr->meta_type == AMT_PARAMTYPE)
|
||||||
|
/* Do not process the parametrized types here */
|
||||||
|
continue;
|
||||||
|
|
||||||
ret = asn1f_recurse_expr(arg, asn1f_check_constraints);
|
ret = asn1f_recurse_expr(arg, asn1f_check_constraints);
|
||||||
RET2RVAL(ret, rvalue);
|
RET2RVAL(ret, rvalue);
|
||||||
|
|
||||||
|
@ -286,7 +296,7 @@ asn1f_fix_constructed(arg_t *arg) {
|
||||||
RET2RVAL(ret, rvalue);
|
RET2RVAL(ret, rvalue);
|
||||||
|
|
||||||
/* Fix tagging */
|
/* Fix tagging */
|
||||||
ret = asn1f_fix_constr_tag(arg);
|
ret = asn1f_fix_constr_tag(arg, 0);
|
||||||
RET2RVAL(ret, rvalue);
|
RET2RVAL(ret, rvalue);
|
||||||
|
|
||||||
/* Import COMPONENTS OF stuff */
|
/* Import COMPONENTS OF stuff */
|
||||||
|
@ -308,6 +318,8 @@ asn1f_resolve_constraints(arg_t *arg) {
|
||||||
etype = top_parent->expr_type;
|
etype = top_parent->expr_type;
|
||||||
else etype = A1TC_INVALID;
|
else etype = A1TC_INVALID;
|
||||||
|
|
||||||
|
DEBUG("asn1f_resolve_constraints(%s)", arg->expr->Identifier);
|
||||||
|
|
||||||
ret = asn1constraint_resolve(arg, arg->expr->module,
|
ret = asn1constraint_resolve(arg, arg->expr->module,
|
||||||
arg->expr->constraints, etype, 0);
|
arg->expr->constraints, etype, 0);
|
||||||
RET2RVAL(ret, rvalue);
|
RET2RVAL(ret, rvalue);
|
||||||
|
@ -326,6 +338,10 @@ asn1f_check_constraints(arg_t *arg) {
|
||||||
int rvalue = 0;
|
int rvalue = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
DEBUG("asn1f_check_constraints(%s{%d/%d})",
|
||||||
|
arg->expr->Identifier,
|
||||||
|
arg->expr->meta_type, arg->expr->expr_type);
|
||||||
|
|
||||||
top_parent = asn1f_find_terminal_type(arg, arg->expr);
|
top_parent = asn1f_find_terminal_type(arg, arg->expr);
|
||||||
if(!top_parent)
|
if(!top_parent)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -339,8 +355,13 @@ asn1f_check_constraints(arg_t *arg) {
|
||||||
etype,
|
etype,
|
||||||
arg->expr->combined_constraints,
|
arg->expr->combined_constraints,
|
||||||
test_types[i], 0, 0, 0);
|
test_types[i], 0, 0, 0);
|
||||||
if(!range && errno == EPERM)
|
if(!range && errno == EPERM) {
|
||||||
|
FATAL("This error happened for %s (%d) at line %d",
|
||||||
|
arg->expr->Identifier,
|
||||||
|
arg->expr->meta_type,
|
||||||
|
arg->expr->_lineno);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
asn1constraint_range_free(range);
|
asn1constraint_range_free(range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
#include "asn1fix_internal.h"
|
#include "asn1fix_internal.h"
|
||||||
|
|
||||||
|
#define AFT_IMAGINARY_ANY 1 /* _fetch_tag() flag */
|
||||||
|
|
||||||
static int _asn1f_check_if_tag_must_be_explicit(arg_t *arg, asn1p_expr_t *v);
|
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);
|
static int _asn1f_compare_tags(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b);
|
||||||
|
static int _asn1f_fix_type_tag(arg_t *arg, asn1p_expr_t *expr);
|
||||||
|
|
||||||
int
|
int
|
||||||
asn1f_pull_components_of(arg_t *arg) {
|
asn1f_pull_components_of(arg_t *arg) {
|
||||||
|
@ -77,6 +80,9 @@ asn1f_pull_components_of(arg_t *arg) {
|
||||||
return r_value;
|
return r_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fix extensibility parts inside constructed types (SEQUENCE, SET, CHOICE).
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
asn1f_fix_constr_ext(arg_t *arg) {
|
asn1f_fix_constr_ext(arg_t *arg) {
|
||||||
asn1p_expr_t *expr = arg->expr;
|
asn1p_expr_t *expr = arg->expr;
|
||||||
|
@ -103,6 +109,10 @@ asn1f_fix_constr_ext(arg_t *arg) {
|
||||||
TQ_INIT(&ext_list);
|
TQ_INIT(&ext_list);
|
||||||
cur_list = (void *)&root_list;
|
cur_list = (void *)&root_list;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Split the set of fields into two lists, the root list
|
||||||
|
* and the extensions list.
|
||||||
|
*/
|
||||||
while((v = TQ_REMOVE(&(expr->members), next))) {
|
while((v = TQ_REMOVE(&(expr->members), next))) {
|
||||||
if(v->expr_type == A1TC_EXTENSIBLE) {
|
if(v->expr_type == A1TC_EXTENSIBLE) {
|
||||||
ext_count++;
|
ext_count++;
|
||||||
|
@ -161,16 +171,30 @@ asn1f_fix_constr_ext(arg_t *arg) {
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
asn1f_fix_constr_tag(arg_t *arg) {
|
asn1f_fix_constr_tag(arg_t *arg, int fix_top_level) {
|
||||||
asn1p_expr_t *expr = arg->expr;
|
asn1p_expr_t *expr = arg->expr;
|
||||||
asn1p_expr_t *v;
|
asn1p_expr_t *v;
|
||||||
int fl_impl_tags = 0;
|
|
||||||
int fl_auto_tags = 0;
|
|
||||||
int root_tagged = 0; /* The root component is manually tagged */
|
int root_tagged = 0; /* The root component is manually tagged */
|
||||||
int ext_tagged = 0; /* The extensions are manually tagged */
|
int ext_tagged = 0; /* The extensions are manually tagged */
|
||||||
int component_number = 0;
|
int component_number = 0;
|
||||||
int r_value = 0;
|
int r_value = 0;
|
||||||
|
|
||||||
|
DEBUG("%s(%s) for line %d", __func__,
|
||||||
|
expr->Identifier, expr->_lineno);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fix the top-level type itself first.
|
||||||
|
*/
|
||||||
|
if(fix_top_level) {
|
||||||
|
if(expr->tag.tag_class == TC_NOCLASS)
|
||||||
|
return r_value;
|
||||||
|
|
||||||
|
if(_asn1f_fix_type_tag(arg, expr))
|
||||||
|
r_value = -1;
|
||||||
|
|
||||||
|
return r_value;
|
||||||
|
}
|
||||||
|
|
||||||
switch(expr->expr_type) {
|
switch(expr->expr_type) {
|
||||||
case ASN_CONSTR_SEQUENCE:
|
case ASN_CONSTR_SEQUENCE:
|
||||||
case ASN_CONSTR_SET:
|
case ASN_CONSTR_SET:
|
||||||
|
@ -180,14 +204,7 @@ asn1f_fix_constr_tag(arg_t *arg) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fl_impl_tags = (arg->mod->module_flags & MSF_IMPLICIT_TAGS);
|
|
||||||
fl_auto_tags = (arg->mod->module_flags & MSF_AUTOMATIC_TAGS);
|
|
||||||
|
|
||||||
DEBUG("%s(%s) {%d, %d} for line %d", __func__,
|
|
||||||
expr->Identifier, fl_impl_tags, fl_auto_tags, expr->_lineno);
|
|
||||||
|
|
||||||
TQ_FOR(v, &(expr->members), next) {
|
TQ_FOR(v, &(expr->members), next) {
|
||||||
int must_explicit = 0;
|
|
||||||
|
|
||||||
if(v->expr_type == A1TC_EXTENSIBLE) {
|
if(v->expr_type == A1TC_EXTENSIBLE) {
|
||||||
component_number++;
|
component_number++;
|
||||||
|
@ -196,43 +213,18 @@ asn1f_fix_constr_tag(arg_t *arg) {
|
||||||
|
|
||||||
if(v->tag.tag_class == TC_NOCLASS) {
|
if(v->tag.tag_class == TC_NOCLASS) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
}
|
||||||
|
|
||||||
switch(component_number) {
|
switch(component_number) {
|
||||||
case 0: case 2:
|
case 0: case 2:
|
||||||
root_tagged = 1; break;
|
root_tagged = 1; break;
|
||||||
default:
|
default:
|
||||||
ext_tagged = 1; break;
|
ext_tagged = 1; break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
must_explicit = _asn1f_check_if_tag_must_be_explicit(arg, v);
|
if(_asn1f_fix_type_tag(arg, v))
|
||||||
|
|
||||||
if(fl_impl_tags) {
|
|
||||||
if(v->tag.tag_mode != TM_EXPLICIT) {
|
|
||||||
if(must_explicit)
|
|
||||||
v->tag.tag_mode = TM_EXPLICIT;
|
|
||||||
else
|
|
||||||
v->tag.tag_mode = TM_IMPLICIT;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(v->tag.tag_mode == TM_DEFAULT) {
|
|
||||||
v->tag.tag_mode = TM_EXPLICIT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Perform a final sanity check.
|
|
||||||
*/
|
|
||||||
if(must_explicit) {
|
|
||||||
if(v->tag.tag_mode == TM_IMPLICIT) {
|
|
||||||
FATAL("%s tagged in IMPLICIT mode "
|
|
||||||
"but must be EXPLICIT at line %d",
|
|
||||||
v->Identifier, v->_lineno);
|
|
||||||
r_value = -1;
|
r_value = -1;
|
||||||
} else {
|
|
||||||
v->tag.tag_mode = TM_EXPLICIT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ext_tagged && !root_tagged) {
|
if(ext_tagged && !root_tagged) {
|
||||||
|
@ -241,13 +233,51 @@ asn1f_fix_constr_tag(arg_t *arg) {
|
||||||
"but root components are not",
|
"but root components are not",
|
||||||
expr->Identifier, expr->_lineno);
|
expr->Identifier, expr->_lineno);
|
||||||
r_value = -1;
|
r_value = -1;
|
||||||
} else if(!root_tagged && !ext_tagged && fl_auto_tags) {
|
} else if(!root_tagged && !ext_tagged
|
||||||
|
&& (arg->mod->module_flags & MSF_AUTOMATIC_TAGS)) {
|
||||||
|
/* Make a decision on automatic tagging */
|
||||||
expr->auto_tags_OK = 1;
|
expr->auto_tags_OK = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return r_value;
|
return r_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_asn1f_fix_type_tag(arg_t *arg, asn1p_expr_t *expr) {
|
||||||
|
int must_explicit = _asn1f_check_if_tag_must_be_explicit(arg, expr);
|
||||||
|
int fl_impl_tags = (arg->mod->module_flags & MSF_IMPLICIT_TAGS);
|
||||||
|
int r_value = 0;
|
||||||
|
|
||||||
|
if(fl_impl_tags) {
|
||||||
|
if(expr->tag.tag_mode != TM_EXPLICIT) {
|
||||||
|
if(must_explicit)
|
||||||
|
expr->tag.tag_mode = TM_EXPLICIT;
|
||||||
|
else
|
||||||
|
expr->tag.tag_mode = TM_IMPLICIT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(expr->tag.tag_mode == TM_DEFAULT) {
|
||||||
|
expr->tag.tag_mode = TM_EXPLICIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Perform a final sanity check.
|
||||||
|
*/
|
||||||
|
if(must_explicit) {
|
||||||
|
if(expr->tag.tag_mode == TM_IMPLICIT) {
|
||||||
|
FATAL("%s tagged in IMPLICIT mode "
|
||||||
|
"but must be EXPLICIT at line %d",
|
||||||
|
expr->Identifier, expr->_lineno);
|
||||||
|
r_value = -1;
|
||||||
|
} else {
|
||||||
|
expr->tag.tag_mode = TM_EXPLICIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r_value;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
asn1f_fix_constr_autotag(arg_t *arg) {
|
asn1f_fix_constr_autotag(arg_t *arg) {
|
||||||
asn1p_expr_t *expr = arg->expr;
|
asn1p_expr_t *expr = arg->expr;
|
||||||
|
@ -333,11 +363,25 @@ asn1f_check_constr_tags_distinct(arg_t *arg) {
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_asn1f_check_if_tag_must_be_explicit(arg_t *arg, asn1p_expr_t *v) {
|
_asn1f_check_if_tag_must_be_explicit(arg_t *arg, asn1p_expr_t *v) {
|
||||||
|
struct asn1p_type_tag_s tag;
|
||||||
|
struct asn1p_type_tag_s save_tag;
|
||||||
asn1p_expr_t *reft;
|
asn1p_expr_t *reft;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fetch the _next_ tag for this type.
|
||||||
|
*/
|
||||||
|
save_tag = v->tag; /* Save existing tag */
|
||||||
|
memset(&v->tag, 0, sizeof(v->tag)); /* Remove it temporarily */
|
||||||
|
ret = asn1f_fetch_tag(arg->asn, arg->mod, v, &tag, 0);
|
||||||
|
v->tag = save_tag; /* Restore the tag back */
|
||||||
|
|
||||||
|
if(ret == 0) return 0; /* If found tag, it's okay */
|
||||||
|
|
||||||
reft = asn1f_find_terminal_type(arg, v);
|
reft = asn1f_find_terminal_type(arg, v);
|
||||||
if(reft) {
|
if(reft) {
|
||||||
switch(reft->expr_type) {
|
switch(reft->expr_type) {
|
||||||
|
case ASN_TYPE_ANY:
|
||||||
case ASN_CONSTR_CHOICE:
|
case ASN_CONSTR_CHOICE:
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
|
@ -357,8 +401,8 @@ _asn1f_compare_tags(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) {
|
||||||
int ra, rb;
|
int ra, rb;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ra = asn1f_fetch_tag(arg->asn, arg->mod, a, &ta);
|
ra = asn1f_fetch_tag(arg->asn, arg->mod, a, &ta, AFT_IMAGINARY_ANY);
|
||||||
rb = asn1f_fetch_tag(arg->asn, arg->mod, b, &tb);
|
rb = asn1f_fetch_tag(arg->asn, arg->mod, b, &tb, AFT_IMAGINARY_ANY);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If both tags are explicitly or implicitly given, use them.
|
* If both tags are explicitly or implicitly given, use them.
|
||||||
|
@ -367,8 +411,12 @@ _asn1f_compare_tags(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) {
|
||||||
/*
|
/*
|
||||||
* Simple case: fetched both tags.
|
* Simple case: fetched both tags.
|
||||||
*/
|
*/
|
||||||
if(ta.tag_value == tb.tag_value
|
|
||||||
&& ta.tag_class == tb.tag_class) {
|
if((ta.tag_value == tb.tag_value
|
||||||
|
&& ta.tag_class == tb.tag_class)
|
||||||
|
|| ta.tag_value == -1 /* Spread IMAGINARY ANY tag... */
|
||||||
|
|| tb.tag_value == -1 /* ...it is an evil virus, fear it! */
|
||||||
|
) {
|
||||||
char *p = (a->expr_type == A1TC_EXTENSIBLE)
|
char *p = (a->expr_type == A1TC_EXTENSIBLE)
|
||||||
?"potentially ":"";
|
?"potentially ":"";
|
||||||
FATAL("Component \"%s\" at line %d %shas the same tag "
|
FATAL("Component \"%s\" at line %d %shas the same tag "
|
||||||
|
|
|
@ -14,7 +14,7 @@ int asn1f_fix_constr_ext(arg_t *);
|
||||||
/*
|
/*
|
||||||
* Fix tagging in constructed types.
|
* Fix tagging in constructed types.
|
||||||
*/
|
*/
|
||||||
int asn1f_fix_constr_tag(arg_t *);
|
int asn1f_fix_constr_tag(arg_t *, int fix_top_level);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check distinctive tagging in constructed types.
|
* Check distinctive tagging in constructed types.
|
||||||
|
|
|
@ -93,7 +93,7 @@ asn1constraint_pullup(arg_t *arg) {
|
||||||
|
|
||||||
expr->combined_constraints = ct_parent;
|
expr->combined_constraints = ct_parent;
|
||||||
if(ct_expr->type == ACT_CA_SET) {
|
if(ct_expr->type == ACT_CA_SET) {
|
||||||
int i;
|
unsigned int i;
|
||||||
for(i = 0; i < ct_expr->el_count; i++) {
|
for(i = 0; i < ct_expr->el_count; i++) {
|
||||||
if(asn1p_constraint_insert(
|
if(asn1p_constraint_insert(
|
||||||
expr->combined_constraints,
|
expr->combined_constraints,
|
||||||
|
@ -120,9 +120,9 @@ asn1constraint_pullup(arg_t *arg) {
|
||||||
|
|
||||||
int
|
int
|
||||||
asn1constraint_resolve(arg_t *arg, asn1p_module_t *mod, asn1p_constraint_t *ct, asn1p_expr_type_e etype, enum asn1p_constraint_type_e effective_type) {
|
asn1constraint_resolve(arg_t *arg, asn1p_module_t *mod, asn1p_constraint_t *ct, asn1p_expr_type_e etype, enum asn1p_constraint_type_e effective_type) {
|
||||||
|
unsigned int el;
|
||||||
int rvalue = 0;
|
int rvalue = 0;
|
||||||
int ret;
|
int ret;
|
||||||
int el;
|
|
||||||
|
|
||||||
if(!ct) return 0;
|
if(!ct) return 0;
|
||||||
|
|
||||||
|
@ -208,7 +208,7 @@ asn1constraint_resolve(arg_t *arg, asn1p_module_t *mod, asn1p_constraint_t *ct,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_remove_exceptions(arg_t *arg, asn1p_constraint_t *ct) {
|
_remove_exceptions(arg_t *arg, asn1p_constraint_t *ct) {
|
||||||
int i;
|
unsigned int i;
|
||||||
|
|
||||||
for(i = 0; i < ct->el_count; i++) {
|
for(i = 0; i < ct->el_count; i++) {
|
||||||
if(ct->elements[i]->type == ACT_EL_EXT)
|
if(ct->elements[i]->type == ACT_EL_EXT)
|
||||||
|
|
|
@ -699,8 +699,8 @@ asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type, const asn1p_constr
|
||||||
asn1p_value_t *vmin;
|
asn1p_value_t *vmin;
|
||||||
asn1p_value_t *vmax;
|
asn1p_value_t *vmax;
|
||||||
int expectation_met;
|
int expectation_met;
|
||||||
|
unsigned int i;
|
||||||
int ret;
|
int ret;
|
||||||
int i;
|
|
||||||
|
|
||||||
if(!exmet) {
|
if(!exmet) {
|
||||||
exmet = &expectation_met;
|
exmet = &expectation_met;
|
||||||
|
|
|
@ -2,7 +2,10 @@
|
||||||
|
|
||||||
static int asn1f_parametrize(arg_t *arg, asn1p_expr_t *ex, asn1p_expr_t *ptype);
|
static int asn1f_parametrize(arg_t *arg, asn1p_expr_t *ex, asn1p_expr_t *ptype);
|
||||||
static int asn1f_param_process_recursive(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_t *ptype, asn1p_expr_t *actargs);
|
static int asn1f_param_process_recursive(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_t *ptype, asn1p_expr_t *actargs);
|
||||||
|
static int asn1f_param_process_constraints(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_t *ptype, asn1p_expr_t *actargs);
|
||||||
|
|
||||||
static asn1p_expr_t *_referenced_argument(asn1p_ref_t *ref, asn1p_expr_t *ptype, asn1p_expr_t *actargs);
|
static asn1p_expr_t *_referenced_argument(asn1p_ref_t *ref, asn1p_expr_t *ptype, asn1p_expr_t *actargs);
|
||||||
|
static int _process_constraints(arg_t *arg, asn1p_constraint_t *ct, asn1p_expr_t *ptype, asn1p_expr_t *actargs);
|
||||||
|
|
||||||
int
|
int
|
||||||
asn1f_fix_parametrized_assignment(arg_t *arg) {
|
asn1f_fix_parametrized_assignment(arg_t *arg) {
|
||||||
|
@ -79,6 +82,7 @@ asn1f_parametrize(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_t *ptype) {
|
||||||
* as a child of the expression, replacing all occurences of
|
* as a child of the expression, replacing all occurences of
|
||||||
* symbols which are defined as parametrized type arguments
|
* symbols which are defined as parametrized type arguments
|
||||||
* with the actual values.
|
* with the actual values.
|
||||||
|
* 3. Don't forget to parametrize the subtype constraints.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
nex = asn1p_expr_clone(ptype, 0);
|
nex = asn1p_expr_clone(ptype, 0);
|
||||||
|
@ -117,11 +121,13 @@ asn1f_param_process_recursive(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_t *ptyp
|
||||||
|
|
||||||
TQ_FOR(child, &(expr->members), next) {
|
TQ_FOR(child, &(expr->members), next) {
|
||||||
asn1p_expr_t *ra;
|
asn1p_expr_t *ra;
|
||||||
asn1p_expr_t *ne;
|
asn1p_expr_t *ne; /* new expression (clone) */
|
||||||
|
|
||||||
|
if(asn1f_param_process_constraints(arg, child, ptype, actargs))
|
||||||
|
return -1;
|
||||||
|
|
||||||
ra = _referenced_argument(child->reference, ptype, actargs);
|
ra = _referenced_argument(child->reference, ptype, actargs);
|
||||||
if(ra == NULL) continue;
|
if(ra) {
|
||||||
|
|
||||||
DEBUG("Substituting parameter for %s %s at line %d",
|
DEBUG("Substituting parameter for %s %s at line %d",
|
||||||
child->Identifier,
|
child->Identifier,
|
||||||
asn1f_printable_reference(child->reference),
|
asn1f_printable_reference(child->reference),
|
||||||
|
@ -141,10 +147,14 @@ asn1f_param_process_recursive(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_t *ptyp
|
||||||
}
|
}
|
||||||
SUBSTITUTE(child, ne);
|
SUBSTITUTE(child, ne);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check that the given ref looks like an argument of a parametrized type.
|
||||||
|
*/
|
||||||
static asn1p_expr_t *
|
static asn1p_expr_t *
|
||||||
_referenced_argument(asn1p_ref_t *ref, asn1p_expr_t *ptype, asn1p_expr_t *actargs) {
|
_referenced_argument(asn1p_ref_t *ref, asn1p_expr_t *ptype, asn1p_expr_t *actargs) {
|
||||||
asn1p_expr_t *aa;
|
asn1p_expr_t *aa;
|
||||||
|
@ -163,3 +173,84 @@ _referenced_argument(asn1p_ref_t *ref, asn1p_expr_t *ptype, asn1p_expr_t *actarg
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Search for parameters inside constraints.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
asn1f_param_process_constraints(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_t *ptype, asn1p_expr_t *actargs) {
|
||||||
|
asn1p_constraint_t *cts;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if(!expr->constraints) return 0;
|
||||||
|
|
||||||
|
cts = asn1p_constraint_clone(expr->constraints);
|
||||||
|
assert(cts);
|
||||||
|
|
||||||
|
ret = _process_constraints(arg, cts, ptype, actargs);
|
||||||
|
if(ret == 1) {
|
||||||
|
asn1p_constraint_free(expr->constraints);
|
||||||
|
expr->constraints = cts;
|
||||||
|
ret = 0;
|
||||||
|
} else {
|
||||||
|
asn1p_constraint_free(cts);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_process_constraints(arg_t *arg, asn1p_constraint_t *ct, asn1p_expr_t *ptype, asn1p_expr_t *actargs) {
|
||||||
|
asn1p_value_t *values[3];
|
||||||
|
int rvalue = 0;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
values[0] = ct->value;
|
||||||
|
values[1] = ct->range_start;
|
||||||
|
values[2] = ct->range_stop;
|
||||||
|
|
||||||
|
for(i = 0; i < sizeof(values)/sizeof(values[0]); i++) {
|
||||||
|
asn1p_value_t *v = values[i];
|
||||||
|
asn1p_expr_t *ra;
|
||||||
|
asn1p_ref_t *ref;
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
if(!v || v->type != ATV_REFERENCED) continue;
|
||||||
|
|
||||||
|
ref = v->value.reference;
|
||||||
|
ra = _referenced_argument(ref, ptype, actargs);
|
||||||
|
if(!ra) continue;
|
||||||
|
|
||||||
|
DEBUG("_process_constraints(%s), ra=%s",
|
||||||
|
asn1f_printable_reference(ref), ra->Identifier);
|
||||||
|
|
||||||
|
str = strdup(ra->Identifier);
|
||||||
|
if(!str) return -1;
|
||||||
|
|
||||||
|
assert(ref->comp_count == 1);
|
||||||
|
ref = asn1p_ref_new(ref->_lineno);
|
||||||
|
if(!ref) { free(str); return -1; }
|
||||||
|
|
||||||
|
if(asn1p_ref_add_component(ref, str, 0)) {
|
||||||
|
free(str);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
asn1p_ref_free(v->value.reference);
|
||||||
|
v->value.reference = ref;
|
||||||
|
rvalue = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process the rest of constraints recursively */
|
||||||
|
for(i = 0; i < ct->el_count; i++) {
|
||||||
|
int ret = _process_constraints(arg, ct->elements[i],
|
||||||
|
ptype, actargs);
|
||||||
|
if(ret == -1)
|
||||||
|
rvalue = -1;
|
||||||
|
else if(ret == 1 && rvalue != -1)
|
||||||
|
rvalue = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rvalue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "asn1fix_internal.h"
|
#include "asn1fix_internal.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
asn1f_fetch_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag) {
|
asn1f_fetch_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag, int flags) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if(expr->tag.tag_class != TC_NOCLASS) {
|
if(expr->tag.tag_class != TC_NOCLASS) {
|
||||||
|
@ -19,6 +19,11 @@ asn1f_fetch_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct as
|
||||||
memset(tag, 0, sizeof(*tag));
|
memset(tag, 0, sizeof(*tag));
|
||||||
tag->tag_class = TC_UNIVERSAL;
|
tag->tag_class = TC_UNIVERSAL;
|
||||||
tag->tag_value = expr_type2uclass_value[expr->expr_type];
|
tag->tag_value = expr_type2uclass_value[expr->expr_type];
|
||||||
|
if(flags && expr->expr_type == ASN_TYPE_ANY) {
|
||||||
|
assert(tag->tag_value == 0);
|
||||||
|
tag->tag_value = -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return (tag->tag_value == 0) ? -1 : 0;
|
return (tag->tag_value == 0) ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +42,8 @@ asn1f_fetch_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct as
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
expr->_mark |= TM_RECURSION;
|
expr->_mark |= TM_RECURSION;
|
||||||
ret = asn1f_fetch_tag(asn, expr->module, expr, tag);
|
ret = asn1f_fetch_tag(asn, expr->module, expr, tag,
|
||||||
|
flags);
|
||||||
expr->_mark &= ~TM_RECURSION;
|
expr->_mark &= ~TM_RECURSION;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#ifndef _ASN1FIX_TAGS_H_
|
#ifndef _ASN1FIX_TAGS_H_
|
||||||
#define _ASN1FIX_TAGS_H_
|
#define _ASN1FIX_TAGS_H_
|
||||||
|
|
||||||
int asn1f_fetch_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag);
|
int asn1f_fetch_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct asn1p_type_tag_s *tag, int special_ANY_handling);
|
||||||
|
|
||||||
#endif /* _ASN1FIX_TAGS_H_ */
|
#endif /* _ASN1FIX_TAGS_H_ */
|
||||||
|
|
Loading…
Reference in New Issue