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:
vlm 2004-09-05 10:36:22 +00:00
parent 55d20cff3b
commit 7614245854
8 changed files with 250 additions and 84 deletions

View File

@ -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);
}

View File

@ -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 "

View File

@ -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.

View File

@ -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)

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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_ */