Commit 7ec9b4c7 authored by Lev Walkin's avatar Lev Walkin

ContainedSubtype constraints

parent 33f63f83
...@@ -381,8 +381,7 @@ asn1f_resolve_constraints(arg_t *arg) { ...@@ -381,8 +381,7 @@ asn1f_resolve_constraints(arg_t *arg) {
DEBUG("(%s)", arg->expr->Identifier); DEBUG("(%s)", arg->expr->Identifier);
ret = asn1constraint_resolve(arg, arg->expr->module, ret = asn1constraint_resolve(arg, arg->expr->constraints, etype, 0);
arg->expr->constraints, etype, 0);
RET2RVAL(ret, rvalue); RET2RVAL(ret, rvalue);
return rvalue; return rvalue;
......
...@@ -2,12 +2,14 @@ ...@@ -2,12 +2,14 @@
#include "asn1fix_constraint.h" #include "asn1fix_constraint.h"
#include "asn1fix_crange.h" #include "asn1fix_crange.h"
static void _remove_exceptions(arg_t *arg, asn1p_constraint_t *ct); static void _remove_extensions(arg_t *arg, asn1p_constraint_t *ct);
static int constraint_value_resolve(arg_t *arg, asn1p_module_t *mod, asn1p_value_t **value, enum asn1p_constraint_type_e real_ctype); static int constraint_type_resolve(arg_t *arg, asn1p_constraint_t *ct);
static int constraint_value_resolve(arg_t *arg, asn1p_value_t **value, enum asn1p_constraint_type_e real_ctype);
int int
asn1constraint_pullup(arg_t *arg) { asn1constraint_pullup(arg_t *arg) {
asn1p_expr_t *expr = arg->expr; asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *top_parent;
asn1p_constraint_t *ct_parent; asn1p_constraint_t *ct_parent;
asn1p_constraint_t *ct_expr; asn1p_constraint_t *ct_expr;
int ret; int ret;
...@@ -63,6 +65,17 @@ asn1constraint_pullup(arg_t *arg) { ...@@ -63,6 +65,17 @@ asn1constraint_pullup(arg_t *arg) {
if(!ct_parent && !ct_expr) if(!ct_parent && !ct_expr)
return 0; /* No constraints to consider */ return 0; /* No constraints to consider */
/*
* Resolve constraints, if not already resolved.
*/
top_parent = asn1f_find_terminal_type(arg, arg->expr);
ret = asn1constraint_resolve(arg, ct_expr,
top_parent ? top_parent->expr_type : A1TC_INVALID, 0);
if(ret) return ret;
/*
* Copy parent type constraints.
*/
if(ct_parent) { if(ct_parent) {
ct_parent = asn1p_constraint_clone(ct_parent); ct_parent = asn1p_constraint_clone(ct_parent);
assert(ct_parent); assert(ct_parent);
...@@ -89,7 +102,7 @@ asn1constraint_pullup(arg_t *arg) { ...@@ -89,7 +102,7 @@ asn1constraint_pullup(arg_t *arg) {
/* /*
* If we have a parent, remove all the extensions (46.4). * If we have a parent, remove all the extensions (46.4).
*/ */
_remove_exceptions(arg, ct_parent); _remove_extensions(arg, ct_parent);
expr->combined_constraints = ct_parent; expr->combined_constraints = ct_parent;
if(ct_expr->type == ACT_CA_SET) { if(ct_expr->type == ACT_CA_SET) {
...@@ -119,7 +132,7 @@ asn1constraint_pullup(arg_t *arg) { ...@@ -119,7 +132,7 @@ 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_constraint_t *ct, asn1p_expr_type_e etype, enum asn1p_constraint_type_e effective_type) {
enum asn1p_constraint_type_e real_constraint_type; enum asn1p_constraint_type_e real_constraint_type;
unsigned int el; unsigned int el;
int rvalue = 0; int rvalue = 0;
...@@ -183,18 +196,23 @@ asn1constraint_resolve(arg_t *arg, asn1p_module_t *mod, asn1p_constraint_t *ct, ...@@ -183,18 +196,23 @@ asn1constraint_resolve(arg_t *arg, asn1p_module_t *mod, asn1p_constraint_t *ct,
/* /*
* Resolve all possible references, wherever they occur. * Resolve all possible references, wherever they occur.
*/ */
if(ct->containedSubtype) {
assert(ct->containedSubtype->type == ATV_REFERENCED);
ret = constraint_type_resolve(arg, ct);
RET2RVAL(ret, rvalue);
}
if(ct->value && ct->value->type == ATV_REFERENCED) { if(ct->value && ct->value->type == ATV_REFERENCED) {
ret = constraint_value_resolve(arg, mod, ret = constraint_value_resolve(arg,
&ct->value, real_constraint_type); &ct->value, real_constraint_type);
RET2RVAL(ret, rvalue); RET2RVAL(ret, rvalue);
} }
if(ct->range_start && ct->range_start->type == ATV_REFERENCED) { if(ct->range_start && ct->range_start->type == ATV_REFERENCED) {
ret = constraint_value_resolve(arg, mod, ret = constraint_value_resolve(arg,
&ct->range_start, real_constraint_type); &ct->range_start, real_constraint_type);
RET2RVAL(ret, rvalue); RET2RVAL(ret, rvalue);
} }
if(ct->range_stop && ct->range_stop->type == ATV_REFERENCED) { if(ct->range_stop && ct->range_stop->type == ATV_REFERENCED) {
ret = constraint_value_resolve(arg, mod, ret = constraint_value_resolve(arg,
&ct->range_stop, real_constraint_type); &ct->range_stop, real_constraint_type);
RET2RVAL(ret, rvalue); RET2RVAL(ret, rvalue);
} }
...@@ -203,7 +221,7 @@ asn1constraint_resolve(arg_t *arg, asn1p_module_t *mod, asn1p_constraint_t *ct, ...@@ -203,7 +221,7 @@ asn1constraint_resolve(arg_t *arg, asn1p_module_t *mod, asn1p_constraint_t *ct,
* Proceed recursively. * Proceed recursively.
*/ */
for(el = 0; el < ct->el_count; el++) { for(el = 0; el < ct->el_count; el++) {
ret = asn1constraint_resolve(arg, mod, ct->elements[el], ret = asn1constraint_resolve(arg, ct->elements[el],
etype, effective_type); etype, effective_type);
RET2RVAL(ret, rvalue); RET2RVAL(ret, rvalue);
} }
...@@ -212,13 +230,13 @@ asn1constraint_resolve(arg_t *arg, asn1p_module_t *mod, asn1p_constraint_t *ct, ...@@ -212,13 +230,13 @@ 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_extensions(arg_t *arg, asn1p_constraint_t *ct) {
unsigned 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)
break; break;
_remove_exceptions(arg, ct->elements[i]); _remove_extensions(arg, ct->elements[i]);
} }
/* Remove the elements at and after the extensibility mark */ /* Remove the elements at and after the extensibility mark */
...@@ -232,17 +250,72 @@ _remove_exceptions(arg_t *arg, asn1p_constraint_t *ct) { ...@@ -232,17 +250,72 @@ _remove_exceptions(arg_t *arg, asn1p_constraint_t *ct) {
ct->elements[i] = 0; ct->elements[i] = 0;
} }
static int
constraint_type_resolve(arg_t *arg, asn1p_constraint_t *ct) {
asn1p_expr_t *rtype;
arg_t tmparg;
int ret;
DEBUG("(\"%s\")", asn1f_printable_value(ct->containedSubtype));
assert(ct->containedSubtype->type == ATV_REFERENCED);
rtype = asn1f_lookup_symbol(arg, arg->expr->module,
ct->containedSubtype->value.reference);
if(!rtype) {
FATAL("Cannot find type \"%s\" in constraints at line %d",
asn1f_printable_value(ct->containedSubtype),
ct->_lineno);
return -1;
}
tmparg = *arg;
tmparg.expr = rtype;
tmparg.mod = rtype->module;
ret = asn1constraint_pullup(&tmparg);
if(ret) return ret;
if(rtype->combined_constraints) {
asn1p_constraint_t *ct_expr;
ct_expr = asn1p_constraint_clone(rtype->combined_constraints);
assert(ct_expr);
_remove_extensions(arg, ct_expr);
if(ct_expr->type == ACT_CA_SET) {
unsigned int i;
for(i = 0; i < ct_expr->el_count; i++) {
if(asn1p_constraint_insert(
ct, ct_expr->elements[i])) {
asn1p_constraint_free(ct_expr);
return -1;
} else {
ct_expr->elements[i] = 0;
}
}
asn1p_constraint_free(ct_expr);
} else {
ret = asn1p_constraint_insert(ct, ct_expr);
assert(ret == 0);
}
ct->type = ACT_CA_SET;
asn1p_value_free(ct->containedSubtype);
ct->containedSubtype = NULL;
}
return 0;
}
static int static int
constraint_value_resolve(arg_t *arg, asn1p_module_t *mod, constraint_value_resolve(arg_t *arg,
asn1p_value_t **value, enum asn1p_constraint_type_e real_ctype) { asn1p_value_t **value, enum asn1p_constraint_type_e real_ctype) {
asn1p_expr_t static_expr; asn1p_expr_t static_expr;
arg_t tmp_arg; arg_t tmp_arg;
int rvalue = 0; int rvalue = 0;
int ret; int ret;
(void)mod;
DEBUG("(\"%s\", within <%s>)", DEBUG("(\"%s\", within <%s>)",
asn1f_printable_value(*value), asn1f_printable_value(*value),
asn1p_constraint_type2str(real_ctype)); asn1p_constraint_type2str(real_ctype));
...@@ -260,3 +333,4 @@ constraint_value_resolve(arg_t *arg, asn1p_module_t *mod, ...@@ -260,3 +333,4 @@ constraint_value_resolve(arg_t *arg, asn1p_module_t *mod,
return rvalue; return rvalue;
} }
...@@ -4,8 +4,7 @@ ...@@ -4,8 +4,7 @@
/* /*
* Resolve referenced values inside constraints. * Resolve referenced values inside constraints.
*/ */
int asn1constraint_resolve(arg_t *arg, asn1p_module_t *module, int asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct,
asn1p_constraint_t *ct,
asn1p_expr_type_e topmost_parent_expression_type, asn1p_expr_type_e topmost_parent_expression_type,
enum asn1p_constraint_type_e effective_constraint_type); enum asn1p_constraint_type_e effective_constraint_type);
......
...@@ -16,6 +16,8 @@ asn1constraint_compatible(asn1p_expr_type_e expr_type, ...@@ -16,6 +16,8 @@ asn1constraint_compatible(asn1p_expr_type_e expr_type,
switch(constr_type) { switch(constr_type) {
case ACT_INVALID: case ACT_INVALID:
return 0; return 0;
case ACT_EL_TYPE:
return 1;
case ACT_EL_VALUE: case ACT_EL_VALUE:
return 1; return 1;
case ACT_EL_RANGE: case ACT_EL_RANGE:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment