diff options
author | Lev Walkin <vlm@lionet.info> | 2005-03-10 11:27:13 +0000 |
---|---|---|
committer | Lev Walkin <vlm@lionet.info> | 2005-03-10 11:27:13 +0000 |
commit | 9288d1c297b59b196bb0414592032427fdee4d72 (patch) | |
tree | df4aa30197e5e40fac2613a02e1eccc6b0684db6 | |
parent | c92a74641ab7430b2584c74df18116d253292077 (diff) |
support for constraints on primitive types while they are being defined
-rw-r--r-- | libasn1fix/asn1fix.c | 3 | ||||
-rw-r--r-- | libasn1fix/asn1fix_constraint.c | 50 | ||||
-rw-r--r-- | libasn1fix/asn1fix_derefv.c | 4 | ||||
-rw-r--r-- | libasn1fix/asn1fix_integer.c | 2 | ||||
-rw-r--r-- | libasn1fix/asn1fix_value.c | 49 | ||||
-rw-r--r-- | libasn1fix/asn1fix_value.h | 3 |
6 files changed, 65 insertions, 46 deletions
diff --git a/libasn1fix/asn1fix.c b/libasn1fix/asn1fix.c index 509a0c28..2b48ce8a 100644 --- a/libasn1fix/asn1fix.c +++ b/libasn1fix/asn1fix.c @@ -385,7 +385,8 @@ asn1f_check_constraints(arg_t *arg) { arg->expr->combined_constraints, test_types[i], 0, 0, 0); if(!range && errno == EPERM) { - FATAL("This error happened for %s (%d) at line %d", + FATAL("This error happened for \"%s\" (meta %d) " + "at line %d", arg->expr->Identifier, arg->expr->meta_type, arg->expr->_lineno); diff --git a/libasn1fix/asn1fix_constraint.c b/libasn1fix/asn1fix_constraint.c index 441a9fbf..808f4e8a 100644 --- a/libasn1fix/asn1fix_constraint.c +++ b/libasn1fix/asn1fix_constraint.c @@ -3,7 +3,7 @@ #include "asn1fix_crange.h" static void _remove_exceptions(arg_t *arg, asn1p_constraint_t *ct); -static int _constraint_value_resolve(arg_t *arg, asn1p_module_t *mod, asn1p_value_t **value); +static int constraint_value_resolve(arg_t *arg, asn1p_module_t *mod, asn1p_value_t **value, enum asn1p_constraint_type_e real_ctype); int asn1constraint_pullup(arg_t *arg) { @@ -120,11 +120,12 @@ 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) { + enum asn1p_constraint_type_e real_constraint_type; unsigned int el; int rvalue = 0; int ret; - DEBUG("%s", arg->expr->Identifier); + DEBUG("(\"%s\")", arg->expr->Identifier); if(!ct) return 0; @@ -150,12 +151,11 @@ asn1constraint_resolve(arg_t *arg, asn1p_module_t *mod, asn1p_constraint_t *ct, break; } - if(etype != A1TC_INVALID) { - enum asn1p_constraint_type_e check_type; + real_constraint_type = effective_type ? effective_type : ct->type; - check_type = effective_type ? effective_type : ct->type; + if(etype != A1TC_INVALID) { - ret = asn1constraint_compatible(etype, check_type); + ret = asn1constraint_compatible(etype, real_constraint_type); switch(ret) { case -1: /* If unknown, assume OK. */ case 1: @@ -168,7 +168,7 @@ asn1constraint_resolve(arg_t *arg, asn1p_module_t *mod, asn1p_constraint_t *ct, FATAL("%s at line %d: " "Constraint type %s is not applicable to %s", arg->expr->Identifier, ct->_lineno, - asn1p_constraint_type2str(check_type), + asn1p_constraint_type2str(real_constraint_type), ASN_EXPR_TYPE2STR(etype) ); rvalue = -1; @@ -184,15 +184,18 @@ asn1constraint_resolve(arg_t *arg, asn1p_module_t *mod, asn1p_constraint_t *ct, * Resolve all possible references, wherever they occur. */ if(ct->value && ct->value->type == ATV_REFERENCED) { - ret = _constraint_value_resolve(arg, mod, &ct->value); + ret = constraint_value_resolve(arg, mod, + &ct->value, real_constraint_type); RET2RVAL(ret, rvalue); } if(ct->range_start && ct->range_start->type == ATV_REFERENCED) { - ret = _constraint_value_resolve(arg, mod, &ct->range_start); + ret = constraint_value_resolve(arg, mod, + &ct->range_start, real_constraint_type); RET2RVAL(ret, rvalue); } if(ct->range_stop && ct->range_stop->type == ATV_REFERENCED) { - ret = _constraint_value_resolve(arg, mod, &ct->range_stop); + ret = constraint_value_resolve(arg, mod, + &ct->range_stop, real_constraint_type); RET2RVAL(ret, rvalue); } @@ -231,31 +234,26 @@ _remove_exceptions(arg_t *arg, asn1p_constraint_t *ct) { static int -_constraint_value_resolve(arg_t *arg, asn1p_module_t *mod, asn1p_value_t **value) { +constraint_value_resolve(arg_t *arg, asn1p_module_t *mod, + asn1p_value_t **value, enum asn1p_constraint_type_e real_ctype) { asn1p_expr_t static_expr; - asn1p_expr_t *tmp_expr; arg_t tmp_arg; int rvalue = 0; int ret; - tmp_expr = asn1f_lookup_symbol(arg, mod, (*value)->value.reference); - if(tmp_expr == NULL) { - FATAL("Cannot find symbol %s (%s) " - "used in %s subtype constraint at line %d", - asn1f_printable_reference((*value)->value.reference), - mod->Identifier, - arg->expr->Identifier, - arg->expr->_lineno); - assert((*value)->type == ATV_REFERENCED); - return -1; - } + (void)mod; + + DEBUG("(\"%s\", within <%s>)", + asn1f_printable_value(*value), + asn1p_constraint_type2str(real_ctype)); - static_expr = *tmp_expr; + static_expr = *arg->expr; static_expr.value = *value; + static_expr.meta_type = AMT_VALUE; tmp_arg = *arg; - tmp_arg.mod = tmp_expr->module; + tmp_arg.mod = arg->expr->module; tmp_arg.expr = &static_expr; - ret = asn1f_fix_dereference_values(&tmp_arg); + ret = asn1f_value_resolve(&tmp_arg, &static_expr, &real_ctype); RET2RVAL(ret, rvalue); assert(static_expr.value); *value = static_expr.value; diff --git a/libasn1fix/asn1fix_derefv.c b/libasn1fix/asn1fix_derefv.c index 261425c8..76f49a39 100644 --- a/libasn1fix/asn1fix_derefv.c +++ b/libasn1fix/asn1fix_derefv.c @@ -9,7 +9,7 @@ asn1f_fix_dereference_values(arg_t *arg) { int r_value = 0; if(expr->value && expr->meta_type == AMT_VALUE) { - if(asn1f_value_resolve(arg, expr)) { + if(asn1f_value_resolve(arg, expr, 0)) { /* This function will emit messages */ r_value = -1; } @@ -42,7 +42,7 @@ asn1f_fix_dereference_defaults(arg_t *arg) { tmpexpr.meta_type = AMT_VALUE; tmpexpr.marker.default_value = 0; tmpexpr.value = expr->marker.default_value; - if(asn1f_value_resolve(&tmparg, &tmpexpr)) + if(asn1f_value_resolve(&tmparg, &tmpexpr, 0)) r_value = -1; expr->marker.default_value = tmpexpr.value; } diff --git a/libasn1fix/asn1fix_integer.c b/libasn1fix/asn1fix_integer.c index e0304bdc..892e9276 100644 --- a/libasn1fix/asn1fix_integer.c +++ b/libasn1fix/asn1fix_integer.c @@ -76,7 +76,7 @@ asn1f_fix_integer(arg_t *arg) { /* * Resolve the value, once and for all. */ - if(asn1f_value_resolve(arg, iv)) { + if(asn1f_value_resolve(arg, iv, 0)) { /* This function will emit messages */ rvalue = -1; continue; diff --git a/libasn1fix/asn1fix_value.c b/libasn1fix/asn1fix_value.c index c40d58a8..7a1da991 100644 --- a/libasn1fix/asn1fix_value.c +++ b/libasn1fix/asn1fix_value.c @@ -3,7 +3,7 @@ static int _asn1f_copy_value(arg_t *arg, asn1p_expr_t *to,asn1p_expr_t *from); int -asn1f_value_resolve(arg_t *arg, asn1p_expr_t *expr) { +asn1f_value_resolve(arg_t *arg, asn1p_expr_t *expr, enum asn1p_constraint_type_e *opt_constr_type) { asn1p_expr_t *val_type_expr; asn1p_expr_t *value_expr; asn1p_expr_t *type_expr; @@ -16,8 +16,12 @@ asn1f_value_resolve(arg_t *arg, asn1p_expr_t *expr) { if(expr->value->type != ATV_REFERENCED) return 0; - DEBUG("(=\"%s\", %x)", - asn1f_printable_value(expr->value), expr->expr_type); + DEBUG("(=\"%s\", %x%s%s)", + asn1f_printable_value(expr->value), expr->expr_type, + opt_constr_type ? ", " : "", + opt_constr_type + ? asn1p_constraint_type2str(*opt_constr_type) : "" + ); /* * 1. Find the terminal type for this assignment. @@ -39,7 +43,7 @@ asn1f_value_resolve(arg_t *arg, asn1p_expr_t *expr) { */ value_expr = asn1f_find_terminal_value(arg, expr); if(value_expr) { - DEBUG("\tTerminal value for %s->%s is %s at line %d", + DEBUG("Terminal value for %s->%s is %s at line %d", expr->Identifier, asn1f_printable_value(expr->value), value_expr->Identifier, value_expr->_lineno); } else { @@ -54,11 +58,11 @@ asn1f_value_resolve(arg_t *arg, asn1p_expr_t *expr) { WITH_MODULE(value_expr->module, val_type_expr = asn1f_find_terminal_type(arg, value_expr)); if(val_type_expr) { - DEBUG("\tTerminal type of value %s->%s is %s at line %d", + DEBUG("Terminal type of value %s->%s is %s at line %d", expr->Identifier, asn1f_printable_value(expr->value), val_type_expr->Identifier, val_type_expr->_lineno); } else { - FATAL("\tTerminal type of value %s->%s not found", + FATAL("Terminal type of value %s->%s not found", expr->Identifier, asn1f_printable_value(expr->value)); return -1; } @@ -67,14 +71,24 @@ asn1f_value_resolve(arg_t *arg, asn1p_expr_t *expr) { * 4. Check compatibility between the type of the current expression * and the type of the discovered value. */ - ret = asn1f_check_type_compatibility(arg, type_expr, val_type_expr); + if(opt_constr_type) + ret = asn1constraint_compatible(val_type_expr->expr_type, + *opt_constr_type); + else + ret = asn1f_check_type_compatibility(arg, + type_expr, val_type_expr); if(ret == -1) { switch(type_expr->expr_type) { case ASN_BASIC_INTEGER: case ASN_BASIC_ENUMERATED: - FATAL("Incompatible type of %s at %d with %s at %d", - type_expr->Identifier, type_expr->_lineno, - val_type_expr->Identifier, val_type_expr->_lineno); + FATAL("Incompatible type of \"%s\" (%s) at line %d " + "with \"%s\" (%s) at line %d", + type_expr->Identifier, + ASN_EXPR_TYPE2STR(type_expr->expr_type), + type_expr->_lineno, + val_type_expr->Identifier, + ASN_EXPR_TYPE2STR(val_type_expr->expr_type), + val_type_expr->_lineno); return -1; case ASN_BASIC_OBJECT_IDENTIFIER: /* @@ -85,9 +99,14 @@ asn1f_value_resolve(arg_t *arg, asn1p_expr_t *expr) { default: break; } - WARNING("\tIncompatible type of %s at %d with %s at %d", - type_expr->Identifier, type_expr->_lineno, - val_type_expr->Identifier, val_type_expr->_lineno); + WARNING("Incompatible type of \"%s\" (%s) at line %d " + "with \"%s\" (%s) at line %d", + type_expr->Identifier, + ASN_EXPR_TYPE2STR(type_expr->expr_type), + type_expr->_lineno, + val_type_expr->Identifier, + ASN_EXPR_TYPE2STR(val_type_expr->expr_type), + val_type_expr->_lineno); return 1; } @@ -105,7 +124,7 @@ asn1f_value_resolve(arg_t *arg, asn1p_expr_t *expr) { return -1; } - DEBUG("\tFinal value for \"%s\" at line %d is %s", + DEBUG("Final value for \"%s\" at line %d is %s", expr->Identifier, expr->_lineno, asn1f_printable_value(expr->value)); @@ -162,7 +181,7 @@ asn1f_look_value_in_type(arg_t *arg, identifier = value_expr->value->value.reference->components[0].name; child_expr = asn1f_lookup_child(type_expr, identifier); - DEBUG("\tLooking into a type %s at line %d for %s at line %d: %s", + DEBUG("Looking into a type %s at line %d for %s at line %d: %s", type_expr->Identifier, type_expr->_lineno, identifier, value_expr->_lineno, child_expr diff --git a/libasn1fix/asn1fix_value.h b/libasn1fix/asn1fix_value.h index 7234035e..067894a9 100644 --- a/libasn1fix/asn1fix_value.h +++ b/libasn1fix/asn1fix_value.h @@ -15,7 +15,8 @@ * -1/EEXIST: Reference is not compatible with the desired type. * -1/ESRCH: Cannot find the terminal reference. */ -int asn1f_value_resolve(arg_t *arg, asn1p_expr_t *tc); +int asn1f_value_resolve(arg_t *arg, asn1p_expr_t *tc, + const enum asn1p_constraint_type_e *opt_constr_type); /* * Check if a value in value_expr refers to the enumeration or integer element |