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);
|
||||
RET2RVAL(ret, rvalue);
|
||||
|
||||
/*
|
||||
* 2.[234] Process SEQUENCE/SET/CHOICE types.
|
||||
*/
|
||||
ret = asn1f_recurse_expr(arg, asn1f_fix_constructed);
|
||||
RET2RVAL(ret, rvalue);
|
||||
|
||||
/*
|
||||
* 2.5.4
|
||||
*/
|
||||
ret = asn1f_recurse_expr(arg, asn1f_fix_dereference_types);
|
||||
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
|
||||
*/
|
||||
|
@ -239,6 +245,10 @@ asn1f_fix_module(arg_t *arg) {
|
|||
TQ_FOR(expr, &(arg->mod->members), next) {
|
||||
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);
|
||||
RET2RVAL(ret, rvalue);
|
||||
|
||||
|
@ -286,7 +296,7 @@ asn1f_fix_constructed(arg_t *arg) {
|
|||
RET2RVAL(ret, rvalue);
|
||||
|
||||
/* Fix tagging */
|
||||
ret = asn1f_fix_constr_tag(arg);
|
||||
ret = asn1f_fix_constr_tag(arg, 0);
|
||||
RET2RVAL(ret, rvalue);
|
||||
|
||||
/* Import COMPONENTS OF stuff */
|
||||
|
@ -308,6 +318,8 @@ asn1f_resolve_constraints(arg_t *arg) {
|
|||
etype = top_parent->expr_type;
|
||||
else etype = A1TC_INVALID;
|
||||
|
||||
DEBUG("asn1f_resolve_constraints(%s)", arg->expr->Identifier);
|
||||
|
||||
ret = asn1constraint_resolve(arg, arg->expr->module,
|
||||
arg->expr->constraints, etype, 0);
|
||||
RET2RVAL(ret, rvalue);
|
||||
|
@ -326,6 +338,10 @@ asn1f_check_constraints(arg_t *arg) {
|
|||
int rvalue = 0;
|
||||
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);
|
||||
if(!top_parent)
|
||||
return 0;
|
||||
|
@ -339,8 +355,13 @@ asn1f_check_constraints(arg_t *arg) {
|
|||
etype,
|
||||
arg->expr->combined_constraints,
|
||||
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;
|
||||
}
|
||||
asn1constraint_range_free(range);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
#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_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
|
||||
asn1f_pull_components_of(arg_t *arg) {
|
||||
|
@ -77,6 +80,9 @@ asn1f_pull_components_of(arg_t *arg) {
|
|||
return r_value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fix extensibility parts inside constructed types (SEQUENCE, SET, CHOICE).
|
||||
*/
|
||||
int
|
||||
asn1f_fix_constr_ext(arg_t *arg) {
|
||||
asn1p_expr_t *expr = arg->expr;
|
||||
|
@ -103,6 +109,10 @@ asn1f_fix_constr_ext(arg_t *arg) {
|
|||
TQ_INIT(&ext_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))) {
|
||||
if(v->expr_type == A1TC_EXTENSIBLE) {
|
||||
ext_count++;
|
||||
|
@ -161,16 +171,30 @@ asn1f_fix_constr_ext(arg_t *arg) {
|
|||
|
||||
|
||||
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 *v;
|
||||
int fl_impl_tags = 0;
|
||||
int fl_auto_tags = 0;
|
||||
int root_tagged = 0; /* The root component is manually tagged */
|
||||
int ext_tagged = 0; /* The extensions are manually tagged */
|
||||
int component_number = 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) {
|
||||
case ASN_CONSTR_SEQUENCE:
|
||||
case ASN_CONSTR_SET:
|
||||
|
@ -180,14 +204,7 @@ asn1f_fix_constr_tag(arg_t *arg) {
|
|||
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) {
|
||||
int must_explicit = 0;
|
||||
|
||||
if(v->expr_type == A1TC_EXTENSIBLE) {
|
||||
component_number++;
|
||||
|
@ -196,43 +213,18 @@ asn1f_fix_constr_tag(arg_t *arg) {
|
|||
|
||||
if(v->tag.tag_class == TC_NOCLASS) {
|
||||
continue;
|
||||
} else {
|
||||
switch(component_number) {
|
||||
case 0: case 2:
|
||||
root_tagged = 1; break;
|
||||
default:
|
||||
ext_tagged = 1; break;
|
||||
}
|
||||
}
|
||||
|
||||
must_explicit = _asn1f_check_if_tag_must_be_explicit(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;
|
||||
}
|
||||
switch(component_number) {
|
||||
case 0: case 2:
|
||||
root_tagged = 1; break;
|
||||
default:
|
||||
ext_tagged = 1; break;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
} else {
|
||||
v->tag.tag_mode = TM_EXPLICIT;
|
||||
}
|
||||
}
|
||||
if(_asn1f_fix_type_tag(arg, v))
|
||||
r_value = -1;
|
||||
|
||||
}
|
||||
|
||||
if(ext_tagged && !root_tagged) {
|
||||
|
@ -241,13 +233,51 @@ asn1f_fix_constr_tag(arg_t *arg) {
|
|||
"but root components are not",
|
||||
expr->Identifier, expr->_lineno);
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
asn1f_fix_constr_autotag(arg_t *arg) {
|
||||
asn1p_expr_t *expr = arg->expr;
|
||||
|
@ -333,11 +363,25 @@ asn1f_check_constr_tags_distinct(arg_t *arg) {
|
|||
|
||||
static int
|
||||
_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;
|
||||
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);
|
||||
if(reft) {
|
||||
switch(reft->expr_type) {
|
||||
case ASN_TYPE_ANY:
|
||||
case ASN_CONSTR_CHOICE:
|
||||
return 1;
|
||||
default:
|
||||
|
@ -357,8 +401,8 @@ _asn1f_compare_tags(arg_t *arg, asn1p_expr_t *a, asn1p_expr_t *b) {
|
|||
int ra, rb;
|
||||
int ret;
|
||||
|
||||
ra = asn1f_fetch_tag(arg->asn, arg->mod, a, &ta);
|
||||
rb = asn1f_fetch_tag(arg->asn, arg->mod, b, &tb);
|
||||
ra = asn1f_fetch_tag(arg->asn, arg->mod, a, &ta, AFT_IMAGINARY_ANY);
|
||||
rb = asn1f_fetch_tag(arg->asn, arg->mod, b, &tb, AFT_IMAGINARY_ANY);
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
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)
|
||||
?"potentially ":"";
|
||||
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.
|
||||
*/
|
||||
int asn1f_fix_constr_tag(arg_t *);
|
||||
int asn1f_fix_constr_tag(arg_t *, int fix_top_level);
|
||||
|
||||
/*
|
||||
* Check distinctive tagging in constructed types.
|
||||
|
|
|
@ -93,7 +93,7 @@ asn1constraint_pullup(arg_t *arg) {
|
|||
|
||||
expr->combined_constraints = ct_parent;
|
||||
if(ct_expr->type == ACT_CA_SET) {
|
||||
int i;
|
||||
unsigned int i;
|
||||
for(i = 0; i < ct_expr->el_count; i++) {
|
||||
if(asn1p_constraint_insert(
|
||||
expr->combined_constraints,
|
||||
|
@ -120,9 +120,9 @@ asn1constraint_pullup(arg_t *arg) {
|
|||
|
||||
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) {
|
||||
unsigned int el;
|
||||
int rvalue = 0;
|
||||
int ret;
|
||||
int el;
|
||||
|
||||
if(!ct) return 0;
|
||||
|
||||
|
@ -208,7 +208,7 @@ asn1constraint_resolve(arg_t *arg, asn1p_module_t *mod, asn1p_constraint_t *ct,
|
|||
|
||||
static void
|
||||
_remove_exceptions(arg_t *arg, asn1p_constraint_t *ct) {
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
for(i = 0; i < ct->el_count; i++) {
|
||||
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 *vmax;
|
||||
int expectation_met;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
if(!exmet) {
|
||||
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_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 int _process_constraints(arg_t *arg, asn1p_constraint_t *ct, asn1p_expr_t *ptype, asn1p_expr_t *actargs);
|
||||
|
||||
int
|
||||
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
|
||||
* symbols which are defined as parametrized type arguments
|
||||
* with the actual values.
|
||||
* 3. Don't forget to parametrize the subtype constraints.
|
||||
*/
|
||||
|
||||
nex = asn1p_expr_clone(ptype, 0);
|
||||
|
@ -117,34 +121,40 @@ asn1f_param_process_recursive(arg_t *arg, asn1p_expr_t *expr, asn1p_expr_t *ptyp
|
|||
|
||||
TQ_FOR(child, &(expr->members), next) {
|
||||
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);
|
||||
if(ra == NULL) continue;
|
||||
|
||||
DEBUG("Substituting parameter for %s %s at line %d",
|
||||
child->Identifier,
|
||||
asn1f_printable_reference(child->reference),
|
||||
child->_lineno
|
||||
);
|
||||
|
||||
assert(child->meta_type == AMT_TYPEREF);
|
||||
assert(child->expr_type == A1TC_REFERENCE);
|
||||
|
||||
ne = asn1p_expr_clone(ra, 0);
|
||||
if(ne == NULL) return -1;
|
||||
assert(ne->Identifier == 0);
|
||||
ne->Identifier = strdup(child->Identifier);
|
||||
if(ne->Identifier == 0) {
|
||||
asn1p_expr_free(ne);
|
||||
return -1;
|
||||
if(ra) {
|
||||
DEBUG("Substituting parameter for %s %s at line %d",
|
||||
child->Identifier,
|
||||
asn1f_printable_reference(child->reference),
|
||||
child->_lineno
|
||||
);
|
||||
|
||||
assert(child->meta_type == AMT_TYPEREF);
|
||||
assert(child->expr_type == A1TC_REFERENCE);
|
||||
|
||||
ne = asn1p_expr_clone(ra, 0);
|
||||
if(ne == NULL) return -1;
|
||||
assert(ne->Identifier == 0);
|
||||
ne->Identifier = strdup(child->Identifier);
|
||||
if(ne->Identifier == 0) {
|
||||
asn1p_expr_free(ne);
|
||||
return -1;
|
||||
}
|
||||
SUBSTITUTE(child, ne);
|
||||
}
|
||||
SUBSTITUTE(child, ne);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the given ref looks like an argument of a parametrized type.
|
||||
*/
|
||||
static asn1p_expr_t *
|
||||
_referenced_argument(asn1p_ref_t *ref, asn1p_expr_t *ptype, asn1p_expr_t *actargs) {
|
||||
asn1p_expr_t *aa;
|
||||
|
@ -163,3 +173,84 @@ _referenced_argument(asn1p_ref_t *ref, asn1p_expr_t *ptype, asn1p_expr_t *actarg
|
|||
|
||||
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"
|
||||
|
||||
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;
|
||||
|
||||
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));
|
||||
tag->tag_class = TC_UNIVERSAL;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -37,7 +42,8 @@ asn1f_fetch_tag(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *expr, struct as
|
|||
return -1;
|
||||
|
||||
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;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef _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_ */
|
||||
|
|
Loading…
Reference in New Issue