Commit 98eabc1c authored by Lev Walkin's avatar Lev Walkin

a pass over OER constraints

parent b2284470
...@@ -40,7 +40,9 @@ static int compute_extensions_start(asn1p_expr_t *expr); ...@@ -40,7 +40,9 @@ static int compute_extensions_start(asn1p_expr_t *expr);
static int expr_break_recursion(arg_t *arg, asn1p_expr_t *expr); static int expr_break_recursion(arg_t *arg, asn1p_expr_t *expr);
static int expr_as_xmlvaluelist(arg_t *arg, asn1p_expr_t *expr); static int expr_as_xmlvaluelist(arg_t *arg, asn1p_expr_t *expr);
static int expr_elements_count(arg_t *arg, asn1p_expr_t *expr); static int expr_elements_count(arg_t *arg, asn1p_expr_t *expr);
static int emit_single_member_OER_constraint(arg_t *arg, asn1cnst_range_t *range, char *type);
static int emit_single_member_PER_constraint(arg_t *arg, asn1cnst_range_t *range, int juscountvalues, char *type); static int emit_single_member_PER_constraint(arg_t *arg, asn1cnst_range_t *range, int juscountvalues, char *type);
static int emit_member_OER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx);
static int emit_member_PER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx); static int emit_member_PER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx);
static int emit_member_table(arg_t *arg, asn1p_expr_t *expr); static int emit_member_table(arg_t *arg, asn1p_expr_t *expr);
static int emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count, const char *opt_modifier); static int emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count, const char *opt_modifier);
...@@ -1952,6 +1954,62 @@ PER_FROM_alphabet_characters(asn1cnst_range_t *range) { ...@@ -1952,6 +1954,62 @@ PER_FROM_alphabet_characters(asn1cnst_range_t *range) {
return numchars; return numchars;
} }
static int
emit_single_member_OER_constraint(arg_t *arg, asn1cnst_range_t *range, char *type) {
if(!range) {
/* oer_support.h: asn_oer_constraint_s */
OUT("{ 0, 0, 0 }");
return 0;
}
if(range->incompatible || range->not_OER_visible) {
OUT("{ 0, 0, 0 }");
} else {
if(range->left.type == ARE_VALUE) {
if(range->right.type == ARE_VALUE) {
OUT("{ AOC_HAS_LOWER_BOUND | AOC_HAS_UPPER_BOUND, %" PRIdMAX
", %" PRIdMAX " }",
range->left.value, range->right.value);
} else {
OUT("{ AOC_HAS_LOWER_BOUND, %" PRIdMAX ", %" PRIdMAX " }",
range->left.value, range->right.value);
}
} else {
if(range->right.type == ARE_VALUE) {
OUT("{ AOC_HAS_UPPER_BOUND, %" PRIdMAX ", %" PRIdMAX " }",
range->left.value, range->right.value);
} else {
OUT("{ 0, %" PRIdMAX ", %" PRIdMAX " }", range->left.value,
range->right.value);
}
}
}
/*
* Print some courtesy debug information.
*/
if(range->left.type == ARE_VALUE
|| range->right.type == ARE_VALUE) {
OUT("\t/* ");
if(type) OUT("(%s", type);
OUT("(");
if(range->left.type == ARE_VALUE)
OUT("%" PRIdASN, range->left.value);
else
OUT("MIN");
OUT("..");
if(range->right.type == ARE_VALUE)
OUT("%" PRIdASN, range->right.value);
else
OUT("MAX");
if(range->extensible) OUT(",...");
if(type) OUT(")");
OUT(") */");
}
return 0;
}
static int static int
emit_single_member_PER_constraint(arg_t *arg, asn1cnst_range_t *range, int alphabetsize, char *type) { emit_single_member_PER_constraint(arg_t *arg, asn1cnst_range_t *range, int alphabetsize, char *type) {
if(!range || range->incompatible || range->not_PER_visible) { if(!range || range->incompatible || range->not_PER_visible) {
...@@ -2069,6 +2127,55 @@ emit_single_member_PER_constraint(arg_t *arg, asn1cnst_range_t *range, int alpha ...@@ -2069,6 +2127,55 @@ emit_single_member_PER_constraint(arg_t *arg, asn1cnst_range_t *range, int alpha
return 0; return 0;
} }
static int
emit_member_OER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx) {
int save_target = arg->target->target;
asn1cnst_range_t *range;
asn1p_expr_type_e etype;
etype = expr_get_type(arg, expr);
if((arg->flags & A1C_GEN_OER)
&& (expr->constraints || etype == ASN_BASIC_ENUMERATED
|| etype == ASN_CONSTR_CHOICE)) {
/* Fall through */
} else {
return 0;
}
REDIR(OT_CTDEFS);
OUT("static asn_oer_constraints_t "
"asn_OER_%s_%s_constr_%d GCC_NOTUSED = {\n",
pfx, MKID(expr), expr->_type_unique_index);
INDENT(+1);
range = asn1constraint_compute_OER_range(etype, expr->combined_constraints,
ACT_EL_RANGE, 0, 0, 0);
if(emit_single_member_OER_constraint(arg, range, 0)) {
return -1;
}
asn1constraint_range_free(range);
OUT(",\n");
range = asn1constraint_compute_OER_range(etype, expr->combined_constraints,
ACT_CT_SIZE, 0, 0, 0);
if(emit_single_member_OER_constraint(arg, range, "SIZE")) {
return -1;
}
asn1constraint_range_free(range);
INDENT(-1);
OUT("};\n");
REDIR(save_target);
return 0;
}
static int static int
emit_member_PER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx) { emit_member_PER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx) {
int save_target = arg->target->target; int save_target = arg->target->target;
...@@ -2545,6 +2652,9 @@ emit_member_table(arg_t *arg, asn1p_expr_t *expr) { ...@@ -2545,6 +2652,9 @@ emit_member_table(arg_t *arg, asn1p_expr_t *expr) {
OUT("}\n"); OUT("}\n");
OUT("\n"); OUT("\n");
if(emit_member_OER_constraints(arg, expr, "memb"))
return -1;
if(emit_member_PER_constraints(arg, expr, "memb")) if(emit_member_PER_constraints(arg, expr, "memb"))
return -1; return -1;
......
...@@ -698,8 +698,18 @@ _range_canonicalize(asn1cnst_range_t *range) { ...@@ -698,8 +698,18 @@ _range_canonicalize(asn1cnst_range_t *range) {
return 0; return 0;
} }
asn1cnst_range_t *
asn1constraint_compute_OER_range(asn1p_expr_type_e expr_type, const asn1p_constraint_t *ct, enum asn1p_constraint_type_e type, const asn1cnst_range_t *minmax, int *exmet, enum cpr_flags cpr_flags) {
return asn1constraint_compute_constraint_range(expr_type, ct, type, minmax, exmet, cpr_flags);
}
asn1cnst_range_t * asn1cnst_range_t *
asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type, const asn1p_constraint_t *ct, enum asn1p_constraint_type_e type, const asn1cnst_range_t *minmax, int *exmet, enum cpr_flags cpr_flags) { asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type, const asn1p_constraint_t *ct, enum asn1p_constraint_type_e type, const asn1cnst_range_t *minmax, int *exmet, enum cpr_flags cpr_flags) {
return asn1constraint_compute_constraint_range(expr_type, ct, type, minmax, exmet, cpr_flags);
}
asn1cnst_range_t *
asn1constraint_compute_constraint_range(asn1p_expr_type_e expr_type, const asn1p_constraint_t *ct, enum asn1p_constraint_type_e type, const asn1cnst_range_t *minmax, int *exmet, enum cpr_flags cpr_flags) {
asn1cnst_range_t *range; asn1cnst_range_t *range;
asn1cnst_range_t *tmp; asn1cnst_range_t *tmp;
asn1p_value_t *vmin; asn1p_value_t *vmin;
...@@ -730,6 +740,10 @@ asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type, const asn1p_constr ...@@ -730,6 +740,10 @@ asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type, const asn1p_constr
*exmet = 1; *exmet = 1;
break; break;
case ACT_CT_FROM: case ACT_CT_FROM:
if(cpr_flags & CPR_strict_OER_visibility) {
errno = EINVAL;
return 0;
}
if(!minmax) { if(!minmax) {
minmax = asn1constraint_default_alphabet(expr_type); minmax = asn1constraint_default_alphabet(expr_type);
if(minmax) { if(minmax) {
...@@ -759,15 +773,27 @@ asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type, const asn1p_constr ...@@ -759,15 +773,27 @@ asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type, const asn1p_constr
/* /*
* X.691, #9.3.6 * X.691, #9.3.6
* Constraints on restricter character string types * Constraints on restricted character string types
* which are not known-multiplier are not PER-visible. * which are not known-multiplier are not PER-visible.
*/ */
if((expr_type & ASN_STRING_NKM_MASK)) if((expr_type & ASN_STRING_NKM_MASK))
range->not_PER_visible = 1; range->not_PER_visible = 1;
if(!ct if(!ct
|| (range->not_PER_visible && (cpr_flags & CPR_strict_PER_visibility))) || (range->not_PER_visible && (cpr_flags & CPR_strict_PER_visibility)))
return range; return range;
/*
* X.696 (08/2015), #8.2.2
* SIZE constraints on restricted character string types
* which are not known-multiplier are not OER-visible.
*/
if(type == ACT_CT_SIZE && (expr_type & ASN_STRING_NKM_MASK))
range->not_OER_visible = 1;
if(!ct
|| (range->not_OER_visible && (cpr_flags & CPR_strict_OER_visibility)))
return range;
switch(ct->type) { switch(ct->type) {
case ACT_EL_VALUE: case ACT_EL_VALUE:
...@@ -798,7 +824,7 @@ asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type, const asn1p_constr ...@@ -798,7 +824,7 @@ asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type, const asn1p_constr
return range; return range;
} }
assert(ct->el_count == 1); assert(ct->el_count == 1);
tmp = asn1constraint_compute_PER_range(expr_type, tmp = asn1constraint_compute_constraint_range(expr_type,
ct->elements[0], type, minmax, exmet, cpr_flags); ct->elements[0], type, minmax, exmet, cpr_flags);
if(tmp) { if(tmp) {
_range_free(range); _range_free(range);
...@@ -817,7 +843,7 @@ asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type, const asn1p_constr ...@@ -817,7 +843,7 @@ asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type, const asn1p_constr
/* AND constraints, one after another. */ /* AND constraints, one after another. */
for(i = 0; i < ct->el_count; i++) { for(i = 0; i < ct->el_count; i++) {
tmp = asn1constraint_compute_PER_range(expr_type, tmp = asn1constraint_compute_constraint_range(expr_type,
ct->elements[i], type, ct->elements[i], type,
ct->type==ACT_CA_SET?range:minmax, exmet, ct->type==ACT_CA_SET?range:minmax, exmet,
cpr_flags); cpr_flags);
...@@ -841,6 +867,15 @@ asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type, const asn1p_constr ...@@ -841,6 +867,15 @@ asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type, const asn1p_constr
continue; continue;
} }
if(tmp->not_OER_visible
&& (cpr_flags & CPR_strict_OER_visibility)) {
/*
* Ignore not OER-visible
*/
_range_free(tmp);
continue;
}
if(tmp->not_PER_visible if(tmp->not_PER_visible
&& (cpr_flags & CPR_strict_PER_visibility)) { && (cpr_flags & CPR_strict_PER_visibility)) {
if(ct->type == ACT_CA_SET) { if(ct->type == ACT_CA_SET) {
...@@ -878,7 +913,7 @@ asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type, const asn1p_constr ...@@ -878,7 +913,7 @@ asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type, const asn1p_constr
*/ */
tmp = 0; tmp = 0;
for(i = 0; i < ct->el_count; i++) { for(i = 0; i < ct->el_count; i++) {
tmp = asn1constraint_compute_PER_range(expr_type, tmp = asn1constraint_compute_constraint_range(expr_type,
ct->elements[i], type, minmax, exmet, ct->elements[i], type, minmax, exmet,
cpr_flags); cpr_flags);
if(!tmp) { if(!tmp) {
...@@ -911,7 +946,7 @@ asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type, const asn1p_constr ...@@ -911,7 +946,7 @@ asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type, const asn1p_constr
* Canonicalizator will do the union magic. * Canonicalizator will do the union magic.
*/ */
for(; i < ct->el_count; i++) { for(; i < ct->el_count; i++) {
tmp = asn1constraint_compute_PER_range(expr_type, tmp = asn1constraint_compute_constraint_range(expr_type,
ct->elements[i], type, minmax, exmet, ct->elements[i], type, minmax, exmet,
cpr_flags); cpr_flags);
if(!tmp) { if(!tmp) {
...@@ -945,14 +980,20 @@ asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type, const asn1p_constr ...@@ -945,14 +980,20 @@ asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type, const asn1p_constr
_range_canonicalize(range); _range_canonicalize(range);
if(range->extensible && type == ACT_CT_FROM) { if(type == ACT_CT_FROM) {
/* /*
* X.691, #9.3.10: * X.696 permitted alphabet constraints are not OER-visible.
* Extensible permitted alphabet constraints */
* are not PER-visible. range->not_OER_visible = 1;
*/ if(range->extensible) {
range->not_PER_visible = 1; /*
} * X.691, #9.3.10:
* Extensible permitted alphabet constraints
* are not PER-visible.
*/
range->not_PER_visible = 1;
}
}
if(range->not_PER_visible if(range->not_PER_visible
&& (cpr_flags & CPR_strict_PER_visibility)) { && (cpr_flags & CPR_strict_PER_visibility)) {
...@@ -978,7 +1019,7 @@ asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type, const asn1p_constr ...@@ -978,7 +1019,7 @@ asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type, const asn1p_constr
*/ */
assert(ct->el_count >= 1); assert(ct->el_count >= 1);
_range_free(range); _range_free(range);
range = asn1constraint_compute_PER_range(expr_type, range = asn1constraint_compute_constraint_range(expr_type,
ct->elements[0], type, minmax, exmet, cpr_flags); ct->elements[0], type, minmax, exmet, cpr_flags);
return range; return range;
default: default:
......
...@@ -24,11 +24,12 @@ typedef struct asn1cnst_range_s { ...@@ -24,11 +24,12 @@ typedef struct asn1cnst_range_s {
int extensible; /* Extension marker (...) is in effect. */ int extensible; /* Extension marker (...) is in effect. */
int incompatible; /* Constraint incompatible with argument */ int incompatible; /* Constraint incompatible with argument */
int not_OER_visible; /* Contains not OER-visible components */
int not_PER_visible; /* Contains not PER-visible components */ int not_PER_visible; /* Contains not PER-visible components */
} asn1cnst_range_t; } asn1cnst_range_t;
/* /*
* Compute the constraint range with variable PER visibility restrictions. * Compute the constraint range with variable visibility restrictions.
* *
* (expr_type) must have the type of the top-level parent ASN.1 type. * (expr_type) must have the type of the top-level parent ASN.1 type.
* (required_type) must be one of ACT_EL_RANGE, ACT_CT_SIZE or ACT_CT_FROM. * (required_type) must be one of ACT_EL_RANGE, ACT_CT_SIZE or ACT_CT_FROM.
...@@ -40,15 +41,30 @@ typedef struct asn1cnst_range_s { ...@@ -40,15 +41,30 @@ typedef struct asn1cnst_range_s {
*/ */
enum cpr_flags { enum cpr_flags {
CPR_noflags = 0x00, CPR_noflags = 0x00,
CPR_strict_PER_visibility = 0x01, CPR_strict_OER_visibility = 0x01,
CPR_simulate_fbless_SIZE = 0x02, CPR_strict_PER_visibility = 0x02,
CPR_simulate_fbless_SIZE = 0x04,
}; };
asn1cnst_range_t *asn1constraint_compute_OER_range(asn1p_expr_type_e expr_type,
const asn1p_constraint_t *ct,
enum asn1p_constraint_type_e required_type,
const asn1cnst_range_t *minmax,
int *expectation_met,
enum cpr_flags);
asn1cnst_range_t *asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type, asn1cnst_range_t *asn1constraint_compute_PER_range(asn1p_expr_type_e expr_type,
const asn1p_constraint_t *ct, const asn1p_constraint_t *ct,
enum asn1p_constraint_type_e required_type, enum asn1p_constraint_type_e required_type,
const asn1cnst_range_t *minmax, const asn1cnst_range_t *minmax,
int *expectation_met, int *expectation_met,
enum cpr_flags); enum cpr_flags);
/* Base implementation */
asn1cnst_range_t *asn1constraint_compute_constraint_range(asn1p_expr_type_e expr_type,
const asn1p_constraint_t *ct,
enum asn1p_constraint_type_e required_type,
const asn1cnst_range_t *minmax,
int *expectation_met,
enum cpr_flags);
void asn1constraint_range_free(asn1cnst_range_t *); void asn1constraint_range_free(asn1cnst_range_t *);
/* /*
......
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