Commit 5253da42 authored by Lev Walkin's avatar Lev Walkin

effective constraint type for walking past SIZE() or FROM() nodes

parent d2ea1de2
...@@ -54,6 +54,16 @@ asn1f_process(asn1p_t *asn, enum asn1f_flags flags, ...@@ -54,6 +54,16 @@ asn1f_process(asn1p_t *asn, enum asn1f_flags flags,
flags &= ~A1F_DEBUG; flags &= ~A1F_DEBUG;
} }
/* Allow SIZE() constraint for INTEGER and other types */
if(flags & A1F_EXTENDED_SizeConstraint) {
arg.flags |= A1F_EXTENDED_SizeConstraint;
flags &= ~A1F_EXTENDED_SizeConstraint;
if(arg.debug) {
arg.debug(-1,
"Extended SizeConstraint support enabled");
}
}
a1f_replace_me_with_proper_interface_arg = arg; a1f_replace_me_with_proper_interface_arg = arg;
/* /*
...@@ -273,16 +283,21 @@ asn1f_fix_constructed(arg_t *arg) { ...@@ -273,16 +283,21 @@ asn1f_fix_constructed(arg_t *arg) {
static int static int
asn1f_fix_constraints(arg_t *arg) { asn1f_fix_constraints(arg_t *arg) {
asn1p_expr_t *top_parent; asn1p_expr_t *top_parent;
asn1p_expr_type_e etype;
int rvalue = 0; int rvalue = 0;
int ret; int ret;
ret = asn1constraint_resolve(arg, arg->expr->constraints); top_parent = asn1f_find_terminal_type(arg, arg->expr, NULL);
if(top_parent)
etype = top_parent->expr_type;
else etype = A1TC_INVALID;
ret = asn1constraint_resolve(arg, arg->expr->constraints, etype, 0);
RET2RVAL(ret, rvalue); RET2RVAL(ret, rvalue);
ret = asn1constraint_pullup(arg); ret = asn1constraint_pullup(arg);
RET2RVAL(ret, rvalue); RET2RVAL(ret, rvalue);
top_parent = asn1f_find_terminal_type(arg, arg->expr, NULL);
if(top_parent) { if(top_parent) {
static enum asn1p_constraint_type_e test_types[] = { static enum asn1p_constraint_type_e test_types[] = {
ACT_EL_RANGE, ACT_CT_SIZE, ACT_CT_FROM }; ACT_EL_RANGE, ACT_CT_SIZE, ACT_CT_FROM };
......
...@@ -12,7 +12,8 @@ ...@@ -12,7 +12,8 @@
*/ */
enum asn1f_flags { enum asn1f_flags {
A1F_NOFLAGS, A1F_NOFLAGS,
A1F_DEBUG = 0x01, /* Print debugging output */ A1F_DEBUG = 0x01, /* Print debugging output */
A1F_EXTENDED_SizeConstraint = 0x02, /* Enable constraint gen code */
}; };
/* /*
......
...@@ -120,8 +120,7 @@ asn1constraint_pullup(arg_t *arg) { ...@@ -120,8 +120,7 @@ asn1constraint_pullup(arg_t *arg) {
} }
int int
asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct) { asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct, asn1p_expr_type_e etype, enum asn1p_constraint_type_e effective_type) {
asn1p_expr_t *top_parent;
int rvalue = 0; int rvalue = 0;
int ret; int ret;
int el; int el;
...@@ -130,6 +129,18 @@ asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct) { ...@@ -130,6 +129,18 @@ asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct) {
/* Don't touch information object classes */ /* Don't touch information object classes */
switch(ct->type) { switch(ct->type) {
case ACT_CT_SIZE:
case ACT_CT_FROM:
if(effective_type && effective_type != ct->type) {
FATAL("%s at line %d: "
"Incompatible nested %s within %s",
arg->expr->Identifier, ct->_lineno,
asn1p_constraint_type2str(ct->type),
asn1p_constraint_type2str(effective_type)
);
}
effective_type = ct->type;
break;
case ACT_CT_WCOMP: case ACT_CT_WCOMP:
case ACT_CT_WCOMPS: case ACT_CT_WCOMPS:
case ACT_CA_CRC: case ACT_CA_CRC:
...@@ -138,21 +149,26 @@ asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct) { ...@@ -138,21 +149,26 @@ asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct) {
break; break;
} }
top_parent = asn1f_find_terminal_type(arg, arg->expr, 0); if(etype != A1TC_INVALID) {
if(top_parent) { enum asn1p_constraint_type_e check_type;
ret = asn1constraint_compatible(top_parent->expr_type,
ct->type); check_type = effective_type ? effective_type : ct->type;
ret = asn1constraint_compatible(etype, check_type);
switch(ret) { switch(ret) {
case -1: /* If unknown, assume OK. */ case -1: /* If unknown, assume OK. */
case 1: case 1:
break; break;
case 0: case 0:
if(effective_type == ACT_CT_SIZE
&& (arg->flags & A1F_EXTENDED_SizeConstraint))
break;
default: default:
FATAL("%s at line %d: " FATAL("%s at line %d: "
"Constraint type %s is not applicable to %s", "Constraint type %s is not applicable to %s",
arg->expr->Identifier, ct->_lineno, arg->expr->Identifier, ct->_lineno,
asn1p_constraint_type2str(ct->type), asn1p_constraint_type2str(check_type),
ASN_EXPR_TYPE2STR(top_parent->expr_type) ASN_EXPR_TYPE2STR(etype)
); );
rvalue = -1; rvalue = -1;
break; break;
...@@ -163,6 +179,9 @@ asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct) { ...@@ -163,6 +179,9 @@ asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct) {
arg->expr->Identifier, arg->expr->_lineno); arg->expr->Identifier, arg->expr->_lineno);
} }
/*
* Resolve all possible references, wherever they occur.
*/
if(ct->value && ct->value->type == ATV_REFERENCED) { if(ct->value && ct->value->type == ATV_REFERENCED) {
ret = _constraint_value_resolve(arg, &ct->value); ret = _constraint_value_resolve(arg, &ct->value);
RET2RVAL(ret, rvalue); RET2RVAL(ret, rvalue);
...@@ -176,8 +195,12 @@ asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct) { ...@@ -176,8 +195,12 @@ asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct) {
RET2RVAL(ret, rvalue); RET2RVAL(ret, rvalue);
} }
/*
* Proceed recursively.
*/
for(el = 0; el < ct->el_count; el++) { for(el = 0; el < ct->el_count; el++) {
ret = asn1constraint_resolve(arg, ct->elements[el]); ret = asn1constraint_resolve(arg, ct->elements[el],
etype, effective_type);
RET2RVAL(ret, rvalue); RET2RVAL(ret, rvalue);
} }
......
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
/* /*
* Resolve referenced values inside constraints. * Resolve referenced values inside constraints.
*/ */
int asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct); int asn1constraint_resolve(arg_t *arg, asn1p_constraint_t *ct,
asn1p_expr_type_e topmost_parent_expression_type,
enum asn1p_constraint_type_e effective_constraint_type);
/* /*
* Collect all subtype constraints from all parents of this type and * Collect all subtype constraints from all parents of this type and
......
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