diff --git a/lib/asn1/parse.y b/lib/asn1/parse.y index 2622a7eb0..e7c5a7f51 100644 --- a/lib/asn1/parse.y +++ b/lib/asn1/parse.y @@ -48,6 +48,7 @@ RCSID("$Id$"); static Type *new_type (Typetype t); +static struct constraint_spec *new_constraint_spec(enum ctype); static Type *new_tag(int tagclass, int tagvalue, int tagenv, Type *oldtype); void yyerror (const char *); static struct objid *new_objid(const char *label, int value); @@ -73,6 +74,7 @@ struct string_list { struct string_list *sl; struct tagtype tag; struct memhead *members; + struct constraint_spec *constraint_spec; } %token kw_ABSENT @@ -183,6 +185,7 @@ struct string_list { %type BitStringType %type BooleanType %type ChoiceType +%type ConstrainedType %type EnumeratedType %type IntegerType %type NullType @@ -215,6 +218,12 @@ struct string_list { %type referencenames +%type Constraint +%type ConstraintSpec +%type GeneralConstraint +%type ContentsConstraint +%type UserDefinedConstraint + %start ModuleDefinition %% @@ -300,6 +309,7 @@ TypeAssignment : IDENTIFIER EEQUAL Type Type : BuiltinType | ReferencedType + | ConstrainedType ; BuiltinType : BitStringType @@ -507,6 +517,65 @@ UsefulType : kw_GeneralizedTime } ; +ConstrainedType : Type Constraint + { + /* if (Constraint.type == contentConstrant) { + assert(Constraint.u.constraint.type == octetstring|bitstring-w/o-NamedBitList); // remember to check type reference too + if (Constraint.u.constraint.type) { + assert((Constraint.u.constraint.type.length % 8) == 0); + } + } + if (Constraint.u.constraint.encoding) { + type == der-oid|ber-oid + } + */ + } + ; + + +Constraint : '(' ConstraintSpec ExceptionSpec ')' + { + $$ = $2; + } + +ExceptionSpec : + +ConstraintSpec : GeneralConstraint + +GeneralConstraint: ContentsConstraint + | UserDefinedConstraint + ; + +ContentsConstraint: kw_CONTAINING Type + { + $$ = new_constraint_spec(CT_CONTENTS); + $$->u.content.type = $2; + $$->u.content.encoding = NULL; + } + | kw_ENCODED kw_BY Value + { + if ($3->type != objectidentifiervalue) + error_message("Non-OID used in ENCODED BY constraint"); + $$ = new_constraint_spec(CT_CONTENTS); + $$->u.content.type = NULL; + $$->u.content.encoding = $3; + } + | kw_CONTAINING Type kw_ENCODED kw_BY Value + { + if ($5->type != objectidentifiervalue) + error_message("Non-OID used in ENCODED BY constraint"); + $$ = new_constraint_spec(CT_CONTENTS); + $$->u.content.type = $2; + $$->u.content.encoding = $5; + } + ; + +UserDefinedConstraint: kw_CONSTRAINED kw_BY '{' '}' + { + $$ = new_constraint_spec(CT_USER); + } + ; + TaggedType : Tag tagenv Type { $$ = new_type(TTag); @@ -861,6 +930,14 @@ new_type (Typetype tt) return t; } +static struct constraint_spec * +new_constraint_spec(enum ctype ct) +{ + struct constraint_spec *c = ecalloc(1, sizeof(*c)); + c->ctype = ct; + return c; +} + static void fix_labels2(Type *t, const char *prefix); static void fix_labels1(struct memhead *members, const char *prefix) {