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
diff --git a/libasn1fix/asn1fix_param.c b/libasn1fix/asn1fix_param.c
index c399ae4..5ce6b93 100644
--- a/libasn1fix/asn1fix_param.c
+++ b/libasn1fix/asn1fix_param.c
@@ -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 @@
* 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 @@
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 @@
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;
+}
+