 fa8cbd4607
			
		
	
	fa8cbd4607
	
	
	
		
			
			git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@21393 ec53bebd-3082-4978-b11e-865c3cabbd6b
		
			
				
	
	
		
			1014 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			1014 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
 | |
|  * (Royal Institute of Technology, Stockholm, Sweden). 
 | |
|  * All rights reserved. 
 | |
|  *
 | |
|  * Redistribution and use in source and binary forms, with or without 
 | |
|  * modification, are permitted provided that the following conditions 
 | |
|  * are met: 
 | |
|  *
 | |
|  * 1. Redistributions of source code must retain the above copyright 
 | |
|  *    notice, this list of conditions and the following disclaimer. 
 | |
|  *
 | |
|  * 2. Redistributions in binary form must reproduce the above copyright 
 | |
|  *    notice, this list of conditions and the following disclaimer in the 
 | |
|  *    documentation and/or other materials provided with the distribution. 
 | |
|  *
 | |
|  * 3. Neither the name of the Institute nor the names of its contributors 
 | |
|  *    may be used to endorse or promote products derived from this software 
 | |
|  *    without specific prior written permission. 
 | |
|  *
 | |
|  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
 | |
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 | |
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 | |
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
 | |
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
 | |
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
 | |
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 | |
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
 | |
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
 | |
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
 | |
|  * SUCH DAMAGE. 
 | |
|  */
 | |
| 
 | |
| /* $Id$ */
 | |
| 
 | |
| %{
 | |
| #ifdef HAVE_CONFIG_H
 | |
| #include <config.h>
 | |
| #endif
 | |
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| #include "symbol.h"
 | |
| #include "lex.h"
 | |
| #include "gen_locl.h"
 | |
| #include "der.h"
 | |
| 
 | |
| 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);
 | |
| static void add_oid_to_tail(struct objid *, struct objid *);
 | |
| static void fix_labels(Symbol *s);
 | |
| 
 | |
| struct string_list {
 | |
|     char *string;
 | |
|     struct string_list *next;
 | |
| };
 | |
| 
 | |
| %}
 | |
| 
 | |
| %union {
 | |
|     int constant;
 | |
|     struct value *value;
 | |
|     struct range *range;
 | |
|     char *name;
 | |
|     Type *type;
 | |
|     Member *member;
 | |
|     struct objid *objid;
 | |
|     char *defval;
 | |
|     struct string_list *sl;
 | |
|     struct tagtype tag;
 | |
|     struct memhead *members;
 | |
|     struct constraint_spec *constraint_spec;
 | |
| }
 | |
| 
 | |
| %token kw_ABSENT
 | |
| %token kw_ABSTRACT_SYNTAX
 | |
| %token kw_ALL
 | |
| %token kw_APPLICATION
 | |
| %token kw_AUTOMATIC
 | |
| %token kw_BEGIN
 | |
| %token kw_BIT
 | |
| %token kw_BMPString
 | |
| %token kw_BOOLEAN
 | |
| %token kw_BY
 | |
| %token kw_CHARACTER
 | |
| %token kw_CHOICE
 | |
| %token kw_CLASS
 | |
| %token kw_COMPONENT
 | |
| %token kw_COMPONENTS
 | |
| %token kw_CONSTRAINED
 | |
| %token kw_CONTAINING
 | |
| %token kw_DEFAULT
 | |
| %token kw_DEFINITIONS
 | |
| %token kw_EMBEDDED
 | |
| %token kw_ENCODED
 | |
| %token kw_END
 | |
| %token kw_ENUMERATED
 | |
| %token kw_EXCEPT
 | |
| %token kw_EXPLICIT
 | |
| %token kw_EXPORTS
 | |
| %token kw_EXTENSIBILITY
 | |
| %token kw_EXTERNAL
 | |
| %token kw_FALSE
 | |
| %token kw_FROM
 | |
| %token kw_GeneralString
 | |
| %token kw_GeneralizedTime
 | |
| %token kw_GraphicString
 | |
| %token kw_IA5String
 | |
| %token kw_IDENTIFIER
 | |
| %token kw_IMPLICIT
 | |
| %token kw_IMPLIED
 | |
| %token kw_IMPORTS
 | |
| %token kw_INCLUDES
 | |
| %token kw_INSTANCE
 | |
| %token kw_INTEGER
 | |
| %token kw_INTERSECTION
 | |
| %token kw_ISO646String
 | |
| %token kw_MAX
 | |
| %token kw_MIN
 | |
| %token kw_MINUS_INFINITY
 | |
| %token kw_NULL
 | |
| %token kw_NumericString
 | |
| %token kw_OBJECT
 | |
| %token kw_OCTET
 | |
| %token kw_OF
 | |
| %token kw_OPTIONAL
 | |
| %token kw_ObjectDescriptor
 | |
| %token kw_PATTERN
 | |
| %token kw_PDV
 | |
| %token kw_PLUS_INFINITY
 | |
| %token kw_PRESENT
 | |
| %token kw_PRIVATE
 | |
| %token kw_PrintableString
 | |
| %token kw_REAL
 | |
| %token kw_RELATIVE_OID
 | |
| %token kw_SEQUENCE
 | |
| %token kw_SET
 | |
| %token kw_SIZE
 | |
| %token kw_STRING
 | |
| %token kw_SYNTAX
 | |
| %token kw_T61String
 | |
| %token kw_TAGS
 | |
| %token kw_TRUE
 | |
| %token kw_TYPE_IDENTIFIER
 | |
| %token kw_TeletexString
 | |
| %token kw_UNION
 | |
| %token kw_UNIQUE
 | |
| %token kw_UNIVERSAL
 | |
| %token kw_UTCTime
 | |
| %token kw_UTF8String
 | |
| %token kw_UniversalString
 | |
| %token kw_VideotexString
 | |
| %token kw_VisibleString
 | |
| %token kw_WITH
 | |
| 
 | |
| %token RANGE
 | |
| %token EEQUAL
 | |
| %token ELLIPSIS
 | |
| 
 | |
| %token <name> IDENTIFIER  referencename
 | |
| %token <name> STRING
 | |
| 
 | |
| %token <constant> NUMBER
 | |
| %type <constant> SignedNumber
 | |
| %type <constant> Class tagenv
 | |
| 
 | |
| %type <value> Value
 | |
| %type <value> BuiltinValue
 | |
| %type <value> IntegerValue
 | |
| %type <value> BooleanValue
 | |
| %type <value> ObjectIdentifierValue
 | |
| %type <value> CharacterStringValue
 | |
| %type <value> NullValue
 | |
| %type <value> DefinedValue
 | |
| %type <value> ReferencedValue
 | |
| %type <value> Valuereference
 | |
| 
 | |
| %type <type> Type
 | |
| %type <type> BuiltinType
 | |
| %type <type> BitStringType
 | |
| %type <type> BooleanType
 | |
| %type <type> ChoiceType
 | |
| %type <type> ConstrainedType
 | |
| %type <type> EnumeratedType
 | |
| %type <type> IntegerType
 | |
| %type <type> NullType
 | |
| %type <type> OctetStringType
 | |
| %type <type> SequenceType
 | |
| %type <type> SequenceOfType
 | |
| %type <type> SetType
 | |
| %type <type> SetOfType
 | |
| %type <type> TaggedType
 | |
| %type <type> ReferencedType
 | |
| %type <type> DefinedType
 | |
| %type <type> UsefulType
 | |
| %type <type> ObjectIdentifierType
 | |
| %type <type> CharacterStringType
 | |
| %type <type> RestrictedCharactedStringType
 | |
| 
 | |
| %type <tag> Tag
 | |
| 
 | |
| %type <member> ComponentType
 | |
| %type <member> NamedBit
 | |
| %type <member> NamedNumber
 | |
| %type <member> NamedType
 | |
| %type <members> ComponentTypeList 
 | |
| %type <members> Enumerations
 | |
| %type <members> NamedBitList
 | |
| %type <members> NamedNumberList
 | |
| 
 | |
| %type <objid> objid objid_list objid_element objid_opt
 | |
| %type <range> range size
 | |
| 
 | |
| %type <sl> referencenames
 | |
| 
 | |
| %type <constraint_spec> Constraint
 | |
| %type <constraint_spec> ConstraintSpec
 | |
| %type <constraint_spec> GeneralConstraint
 | |
| %type <constraint_spec> ContentsConstraint
 | |
| %type <constraint_spec> UserDefinedConstraint
 | |
| 
 | |
| 
 | |
| 
 | |
| %start ModuleDefinition
 | |
| 
 | |
| %%
 | |
| 
 | |
| ModuleDefinition: IDENTIFIER kw_DEFINITIONS TagDefault ExtensionDefault
 | |
| 			EEQUAL kw_BEGIN ModuleBody kw_END
 | |
| 		{
 | |
| 			checkundefined();
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| TagDefault	: kw_EXPLICIT kw_TAGS
 | |
| 		| kw_IMPLICIT kw_TAGS
 | |
| 		      { error_message("implicit tagging is not supported"); }
 | |
| 		| kw_AUTOMATIC kw_TAGS
 | |
| 		      { error_message("automatic tagging is not supported"); }
 | |
| 		| /* empty */
 | |
| 		;
 | |
| 
 | |
| ExtensionDefault: kw_EXTENSIBILITY kw_IMPLIED
 | |
| 		      { error_message("no extensibility options supported"); }
 | |
| 		| /* empty */
 | |
| 		;
 | |
| 
 | |
| ModuleBody	: /* Exports */ Imports AssignmentList
 | |
| 		| /* empty */
 | |
| 		;
 | |
| 
 | |
| Imports		: kw_IMPORTS SymbolsImported ';'
 | |
| 		| /* empty */
 | |
| 		;
 | |
| 
 | |
| SymbolsImported	: SymbolsFromModuleList
 | |
| 		| /* empty */
 | |
| 		;
 | |
| 
 | |
| SymbolsFromModuleList: SymbolsFromModule
 | |
| 		| SymbolsFromModuleList SymbolsFromModule
 | |
| 		;
 | |
| 
 | |
| SymbolsFromModule: referencenames kw_FROM IDENTIFIER objid_opt
 | |
| 		{ 
 | |
| 		    struct string_list *sl;
 | |
| 		    for(sl = $1; sl != NULL; sl = sl->next) {
 | |
| 			Symbol *s = addsym(sl->string);
 | |
| 			s->stype = Stype;
 | |
| 		    }
 | |
| 		    add_import($3);
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| AssignmentList	: Assignment
 | |
| 		| Assignment AssignmentList
 | |
| 		;
 | |
| 
 | |
| Assignment	: TypeAssignment
 | |
| 		| ValueAssignment
 | |
| 		;
 | |
| 
 | |
| referencenames	: IDENTIFIER ',' referencenames
 | |
| 		{
 | |
| 		    $$ = emalloc(sizeof(*$$));
 | |
| 		    $$->string = $1;
 | |
| 		    $$->next = $3;
 | |
| 		}
 | |
| 		| IDENTIFIER
 | |
| 		{
 | |
| 		    $$ = emalloc(sizeof(*$$));
 | |
| 		    $$->string = $1;
 | |
| 		    $$->next = NULL;
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| TypeAssignment	: IDENTIFIER EEQUAL Type
 | |
| 		{
 | |
| 		    Symbol *s = addsym ($1);
 | |
| 		    s->stype = Stype;
 | |
| 		    s->type = $3;
 | |
| 		    fix_labels(s);
 | |
| 		    generate_type (s);
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| Type		: BuiltinType
 | |
| 		| ReferencedType
 | |
| 		| ConstrainedType
 | |
| 		;
 | |
| 
 | |
| BuiltinType	: BitStringType
 | |
| 		| BooleanType
 | |
| 		| CharacterStringType
 | |
| 		| ChoiceType
 | |
| 		| EnumeratedType
 | |
| 		| IntegerType
 | |
| 		| NullType
 | |
| 		| ObjectIdentifierType
 | |
| 		| OctetStringType
 | |
| 		| SequenceType
 | |
| 		| SequenceOfType
 | |
| 		| SetType
 | |
| 		| SetOfType
 | |
| 		| TaggedType
 | |
| 		;
 | |
| 
 | |
| BooleanType	: kw_BOOLEAN
 | |
| 		{
 | |
| 			$$ = new_tag(ASN1_C_UNIV, UT_Boolean, 
 | |
| 				     TE_EXPLICIT, new_type(TBoolean));
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| range		: '(' Value RANGE Value ')'
 | |
| 		{
 | |
| 		    if($2->type != integervalue)
 | |
| 			error_message("Non-integer used in first part of range");
 | |
| 		    if($2->type != integervalue)
 | |
| 			error_message("Non-integer in second part of range");
 | |
| 		    $$ = ecalloc(1, sizeof(*$$));
 | |
| 		    $$->min = $2->u.integervalue;
 | |
| 		    $$->max = $4->u.integervalue;
 | |
| 		}
 | |
| 		| '(' Value RANGE kw_MAX ')'
 | |
| 		{		
 | |
| 		    if($2->type != integervalue)
 | |
| 			error_message("Non-integer in first part of range");
 | |
| 		    $$ = ecalloc(1, sizeof(*$$));
 | |
| 		    $$->min = $2->u.integervalue;
 | |
| 		    $$->max = $2->u.integervalue - 1;
 | |
| 		}
 | |
| 		| '(' kw_MIN RANGE Value ')'
 | |
| 		{		
 | |
| 		    if($4->type != integervalue)
 | |
| 			error_message("Non-integer in second part of range");
 | |
| 		    $$ = ecalloc(1, sizeof(*$$));
 | |
| 		    $$->min = $4->u.integervalue + 2;
 | |
| 		    $$->max = $4->u.integervalue;
 | |
| 		}
 | |
| 		| '(' Value ')'
 | |
| 		{
 | |
| 		    if($2->type != integervalue)
 | |
| 			error_message("Non-integer used in limit");
 | |
| 		    $$ = ecalloc(1, sizeof(*$$));
 | |
| 		    $$->min = $2->u.integervalue;
 | |
| 		    $$->max = $2->u.integervalue;
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| 
 | |
| IntegerType	: kw_INTEGER
 | |
| 		{
 | |
| 			$$ = new_tag(ASN1_C_UNIV, UT_Integer, 
 | |
| 				     TE_EXPLICIT, new_type(TInteger));
 | |
| 		}
 | |
| 		| kw_INTEGER range
 | |
| 		{
 | |
| 			$$ = new_type(TInteger);
 | |
| 			$$->range = $2;
 | |
| 			$$ = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, $$);
 | |
| 		}
 | |
| 		| kw_INTEGER '{' NamedNumberList '}'
 | |
| 		{
 | |
| 		  $$ = new_type(TInteger);
 | |
| 		  $$->members = $3;
 | |
| 		  $$ = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, $$);
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| NamedNumberList	: NamedNumber
 | |
| 		{
 | |
| 			$$ = emalloc(sizeof(*$$));
 | |
| 			ASN1_TAILQ_INIT($$);
 | |
| 			ASN1_TAILQ_INSERT_HEAD($$, $1, members);
 | |
| 		}
 | |
| 		| NamedNumberList ',' NamedNumber
 | |
| 		{
 | |
| 			ASN1_TAILQ_INSERT_TAIL($1, $3, members);
 | |
| 			$$ = $1;
 | |
| 		}
 | |
| 		| NamedNumberList ',' ELLIPSIS
 | |
| 			{ $$ = $1; } /* XXX used for Enumerations */
 | |
| 		;
 | |
| 
 | |
| NamedNumber	: IDENTIFIER '(' SignedNumber ')'
 | |
| 		{
 | |
| 			$$ = emalloc(sizeof(*$$));
 | |
| 			$$->name = $1;
 | |
| 			$$->gen_name = estrdup($1);
 | |
| 			output_name ($$->gen_name);
 | |
| 			$$->val = $3;
 | |
| 			$$->optional = 0;
 | |
| 			$$->ellipsis = 0;
 | |
| 			$$->type = NULL;
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| EnumeratedType	: kw_ENUMERATED '{' Enumerations '}'
 | |
| 		{
 | |
| 		  $$ = new_type(TInteger);
 | |
| 		  $$->members = $3;
 | |
| 		  $$ = new_tag(ASN1_C_UNIV, UT_Enumerated, TE_EXPLICIT, $$);
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| Enumerations	: NamedNumberList /* XXX */
 | |
| 		;
 | |
| 
 | |
| BitStringType	: kw_BIT kw_STRING
 | |
| 		{
 | |
| 		  $$ = new_type(TBitString);
 | |
| 		  $$->members = emalloc(sizeof(*$$->members));
 | |
| 		  ASN1_TAILQ_INIT($$->members);
 | |
| 		  $$ = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, $$);
 | |
| 		}
 | |
| 		| kw_BIT kw_STRING '{' NamedBitList '}'
 | |
| 		{
 | |
| 		  $$ = new_type(TBitString);
 | |
| 		  $$->members = $4;
 | |
| 		  $$ = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, $$);
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| ObjectIdentifierType: kw_OBJECT kw_IDENTIFIER
 | |
| 		{
 | |
| 			$$ = new_tag(ASN1_C_UNIV, UT_OID, 
 | |
| 				     TE_EXPLICIT, new_type(TOID));
 | |
| 		}
 | |
| 		;
 | |
| OctetStringType	: kw_OCTET kw_STRING
 | |
| 		{
 | |
| 			$$ = new_tag(ASN1_C_UNIV, UT_OctetString, 
 | |
| 				     TE_EXPLICIT, new_type(TOctetString));
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| NullType	: kw_NULL
 | |
| 		{
 | |
| 			$$ = new_tag(ASN1_C_UNIV, UT_Null, 
 | |
| 				     TE_EXPLICIT, new_type(TNull));
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| size		:
 | |
| 		{ $$ = NULL; }
 | |
| 		| kw_SIZE range
 | |
| 		{ $$ = $2; }
 | |
| 		;
 | |
| 
 | |
| 
 | |
| SequenceType	: kw_SEQUENCE '{' /* ComponentTypeLists */ ComponentTypeList '}'
 | |
| 		{
 | |
| 		  $$ = new_type(TSequence);
 | |
| 		  $$->members = $3;
 | |
| 		  $$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
 | |
| 		}
 | |
| 		| kw_SEQUENCE '{' '}'
 | |
| 		{
 | |
| 		  $$ = new_type(TSequence);
 | |
| 		  $$->members = NULL;
 | |
| 		  $$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| SequenceOfType	: kw_SEQUENCE size kw_OF Type
 | |
| 		{
 | |
| 		  $$ = new_type(TSequenceOf);
 | |
| 		  $$->range = $2;
 | |
| 		  $$->subtype = $4;
 | |
| 		  $$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| SetType		: kw_SET '{' /* ComponentTypeLists */ ComponentTypeList '}'
 | |
| 		{
 | |
| 		  $$ = new_type(TSet);
 | |
| 		  $$->members = $3;
 | |
| 		  $$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
 | |
| 		}
 | |
| 		| kw_SET '{' '}'
 | |
| 		{
 | |
| 		  $$ = new_type(TSet);
 | |
| 		  $$->members = NULL;
 | |
| 		  $$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| SetOfType	: kw_SET kw_OF Type
 | |
| 		{
 | |
| 		  $$ = new_type(TSetOf);
 | |
| 		  $$->subtype = $3;
 | |
| 		  $$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| ChoiceType	: kw_CHOICE '{' /* AlternativeTypeLists */ ComponentTypeList '}'
 | |
| 		{
 | |
| 		  $$ = new_type(TChoice);
 | |
| 		  $$->members = $3;
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| ReferencedType	: DefinedType
 | |
| 		| UsefulType
 | |
| 		;
 | |
| 
 | |
| DefinedType	: IDENTIFIER
 | |
| 		{
 | |
| 		  Symbol *s = addsym($1);
 | |
| 		  $$ = new_type(TType);
 | |
| 		  if(s->stype != Stype && s->stype != SUndefined)
 | |
| 		    error_message ("%s is not a type\n", $1);
 | |
| 		  else
 | |
| 		    $$->symbol = s;
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| UsefulType	: kw_GeneralizedTime
 | |
| 		{
 | |
| 			$$ = new_tag(ASN1_C_UNIV, UT_GeneralizedTime, 
 | |
| 				     TE_EXPLICIT, new_type(TGeneralizedTime));
 | |
| 		}
 | |
| 		| kw_UTCTime
 | |
| 		{
 | |
| 			$$ = new_tag(ASN1_C_UNIV, UT_UTCTime, 
 | |
| 				     TE_EXPLICIT, new_type(TUTCTime));
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| 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 ')'
 | |
| 		{
 | |
| 		    $$ = $2;
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| 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);
 | |
| 			$$->tag = $1;
 | |
| 			$$->tag.tagenv = $2;
 | |
| 			if($3->type == TTag && $2 == TE_IMPLICIT) {
 | |
| 				$$->subtype = $3->subtype;
 | |
| 				free($3);
 | |
| 			} else
 | |
| 				$$->subtype = $3;
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| Tag		: '[' Class NUMBER ']'
 | |
| 		{
 | |
| 			$$.tagclass = $2;
 | |
| 			$$.tagvalue = $3;
 | |
| 			$$.tagenv = TE_EXPLICIT;
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| Class		: /* */
 | |
| 		{
 | |
| 			$$ = ASN1_C_CONTEXT;
 | |
| 		}
 | |
| 		| kw_UNIVERSAL
 | |
| 		{
 | |
| 			$$ = ASN1_C_UNIV;
 | |
| 		}
 | |
| 		| kw_APPLICATION
 | |
| 		{
 | |
| 			$$ = ASN1_C_APPL;
 | |
| 		}
 | |
| 		| kw_PRIVATE
 | |
| 		{
 | |
| 			$$ = ASN1_C_PRIVATE;
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| tagenv		: /* */
 | |
| 		{
 | |
| 			$$ = TE_EXPLICIT;
 | |
| 		}
 | |
| 		| kw_EXPLICIT
 | |
| 		{
 | |
| 			$$ = TE_EXPLICIT;
 | |
| 		}
 | |
| 		| kw_IMPLICIT
 | |
| 		{
 | |
| 			$$ = TE_IMPLICIT;
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| 
 | |
| ValueAssignment	: IDENTIFIER Type EEQUAL Value
 | |
| 		{
 | |
| 			Symbol *s;
 | |
| 			s = addsym ($1);
 | |
| 
 | |
| 			s->stype = SValue;
 | |
| 			s->value = $4;
 | |
| 			generate_constant (s);
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| CharacterStringType: RestrictedCharactedStringType
 | |
| 		;
 | |
| 
 | |
| RestrictedCharactedStringType: kw_GeneralString
 | |
| 		{
 | |
| 			$$ = new_tag(ASN1_C_UNIV, UT_GeneralString, 
 | |
| 				     TE_EXPLICIT, new_type(TGeneralString));
 | |
| 		}
 | |
| 		| kw_UTF8String
 | |
| 		{
 | |
| 			$$ = new_tag(ASN1_C_UNIV, UT_UTF8String, 
 | |
| 				     TE_EXPLICIT, new_type(TUTF8String));
 | |
| 		}
 | |
| 		| kw_PrintableString
 | |
| 		{
 | |
| 			$$ = new_tag(ASN1_C_UNIV, UT_PrintableString, 
 | |
| 				     TE_EXPLICIT, new_type(TPrintableString));
 | |
| 		}
 | |
| 		| kw_VisibleString
 | |
| 		{
 | |
| 			$$ = new_tag(ASN1_C_UNIV, UT_VisibleString, 
 | |
| 				     TE_EXPLICIT, new_type(TVisibleString));
 | |
| 		}
 | |
| 		| kw_IA5String
 | |
| 		{
 | |
| 			$$ = new_tag(ASN1_C_UNIV, UT_IA5String, 
 | |
| 				     TE_EXPLICIT, new_type(TIA5String));
 | |
| 		}
 | |
| 		| kw_BMPString
 | |
| 		{
 | |
| 			$$ = new_tag(ASN1_C_UNIV, UT_BMPString, 
 | |
| 				     TE_EXPLICIT, new_type(TBMPString));
 | |
| 		}
 | |
| 		| kw_UniversalString
 | |
| 		{
 | |
| 			$$ = new_tag(ASN1_C_UNIV, UT_UniversalString, 
 | |
| 				     TE_EXPLICIT, new_type(TUniversalString));
 | |
| 		}
 | |
| 
 | |
| 		;
 | |
| 
 | |
| ComponentTypeList: ComponentType
 | |
| 		{
 | |
| 			$$ = emalloc(sizeof(*$$));
 | |
| 			ASN1_TAILQ_INIT($$);
 | |
| 			ASN1_TAILQ_INSERT_HEAD($$, $1, members);
 | |
| 		}
 | |
| 		| ComponentTypeList ',' ComponentType
 | |
| 		{
 | |
| 			ASN1_TAILQ_INSERT_TAIL($1, $3, members);
 | |
| 			$$ = $1;
 | |
| 		}
 | |
| 		| ComponentTypeList ',' ELLIPSIS
 | |
| 		{
 | |
| 		        struct member *m = ecalloc(1, sizeof(*m));
 | |
| 			m->name = estrdup("...");
 | |
| 			m->gen_name = estrdup("asn1_ellipsis");
 | |
| 			m->ellipsis = 1;
 | |
| 			ASN1_TAILQ_INSERT_TAIL($1, m, members);
 | |
| 			$$ = $1;
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| NamedType	: IDENTIFIER Type
 | |
| 		{
 | |
| 		  $$ = emalloc(sizeof(*$$));
 | |
| 		  $$->name = $1;
 | |
| 		  $$->gen_name = estrdup($1);
 | |
| 		  output_name ($$->gen_name);
 | |
| 		  $$->type = $2;
 | |
| 		  $$->ellipsis = 0;
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| ComponentType	: NamedType
 | |
| 		{
 | |
| 			$$ = $1;
 | |
| 			$$->optional = 0;
 | |
| 			$$->defval = NULL;
 | |
| 		}
 | |
| 		| NamedType kw_OPTIONAL
 | |
| 		{
 | |
| 			$$ = $1;
 | |
| 			$$->optional = 1;
 | |
| 			$$->defval = NULL;
 | |
| 		}
 | |
| 		| NamedType kw_DEFAULT Value
 | |
| 		{
 | |
| 			$$ = $1;
 | |
| 			$$->optional = 0;
 | |
| 			$$->defval = $3;
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| NamedBitList	: NamedBit
 | |
| 		{
 | |
| 			$$ = emalloc(sizeof(*$$));
 | |
| 			ASN1_TAILQ_INIT($$);
 | |
| 			ASN1_TAILQ_INSERT_HEAD($$, $1, members);
 | |
| 		}
 | |
| 		| NamedBitList ',' NamedBit
 | |
| 		{
 | |
| 			ASN1_TAILQ_INSERT_TAIL($1, $3, members);
 | |
| 			$$ = $1;
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| NamedBit	: IDENTIFIER '(' NUMBER ')'
 | |
| 		{
 | |
| 		  $$ = emalloc(sizeof(*$$));
 | |
| 		  $$->name = $1;
 | |
| 		  $$->gen_name = estrdup($1);
 | |
| 		  output_name ($$->gen_name);
 | |
| 		  $$->val = $3;
 | |
| 		  $$->optional = 0;
 | |
| 		  $$->ellipsis = 0;
 | |
| 		  $$->type = NULL;
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| objid_opt	: objid
 | |
| 		| /* empty */ { $$ = NULL; }
 | |
| 		;
 | |
| 
 | |
| objid		: '{' objid_list '}'
 | |
| 		{
 | |
| 			$$ = $2;
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| objid_list	:  /* empty */
 | |
| 		{
 | |
| 			$$ = NULL;
 | |
| 		}
 | |
| 		| objid_element objid_list
 | |
| 		{
 | |
| 		        if ($2) {
 | |
| 				$$ = $2;
 | |
| 				add_oid_to_tail($2, $1);
 | |
| 			} else {
 | |
| 				$$ = $1;
 | |
| 			}
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| objid_element	: IDENTIFIER '(' NUMBER ')'
 | |
| 		{
 | |
| 			$$ = new_objid($1, $3);
 | |
| 		}
 | |
| 		| IDENTIFIER
 | |
| 		{
 | |
| 		    Symbol *s = addsym($1);
 | |
| 		    if(s->stype != SValue ||
 | |
| 		       s->value->type != objectidentifiervalue) {
 | |
| 			error_message("%s is not an object identifier\n", 
 | |
| 				      s->name);
 | |
| 			exit(1);
 | |
| 		    }
 | |
| 		    $$ = s->value->u.objectidentifiervalue;
 | |
| 		}
 | |
| 		| NUMBER
 | |
| 		{
 | |
| 		    $$ = new_objid(NULL, $1);
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| Value		: BuiltinValue
 | |
| 		| ReferencedValue
 | |
| 		;
 | |
| 
 | |
| BuiltinValue	: BooleanValue
 | |
| 		| CharacterStringValue
 | |
| 		| IntegerValue
 | |
| 		| ObjectIdentifierValue
 | |
| 		| NullValue
 | |
| 		;
 | |
| 
 | |
| ReferencedValue	: DefinedValue
 | |
| 		;
 | |
| 
 | |
| DefinedValue	: Valuereference
 | |
| 		;
 | |
| 
 | |
| Valuereference	: IDENTIFIER
 | |
| 		{
 | |
| 			Symbol *s = addsym($1);
 | |
| 			if(s->stype != SValue)
 | |
| 				error_message ("%s is not a value\n",
 | |
| 						s->name);
 | |
| 			else
 | |
| 				$$ = s->value;
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| CharacterStringValue: STRING
 | |
| 		{
 | |
| 			$$ = emalloc(sizeof(*$$));
 | |
| 			$$->type = stringvalue;
 | |
| 			$$->u.stringvalue = $1;
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| BooleanValue	: kw_TRUE
 | |
| 		{
 | |
| 			$$ = emalloc(sizeof(*$$));
 | |
| 			$$->type = booleanvalue;
 | |
| 			$$->u.booleanvalue = 0;
 | |
| 		}
 | |
| 		| kw_FALSE
 | |
| 		{
 | |
| 			$$ = emalloc(sizeof(*$$));
 | |
| 			$$->type = booleanvalue;
 | |
| 			$$->u.booleanvalue = 0;
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| IntegerValue	: SignedNumber
 | |
| 		{
 | |
| 			$$ = emalloc(sizeof(*$$));
 | |
| 			$$->type = integervalue;
 | |
| 			$$->u.integervalue = $1;
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| SignedNumber	: NUMBER
 | |
| 		;
 | |
| 
 | |
| NullValue	: kw_NULL
 | |
| 		{
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| ObjectIdentifierValue: objid
 | |
| 		{
 | |
| 			$$ = emalloc(sizeof(*$$));
 | |
| 			$$->type = objectidentifiervalue;
 | |
| 			$$->u.objectidentifiervalue = $1;
 | |
| 		}
 | |
| 		;
 | |
| 
 | |
| %%
 | |
| 
 | |
| void
 | |
| yyerror (const char *s)
 | |
| {
 | |
|      error_message ("%s\n", s);
 | |
| }
 | |
| 
 | |
| static Type *
 | |
| new_tag(int tagclass, int tagvalue, int tagenv, Type *oldtype)
 | |
| {
 | |
|     Type *t;
 | |
|     if(oldtype->type == TTag && oldtype->tag.tagenv == TE_IMPLICIT) {
 | |
| 	t = oldtype;
 | |
| 	oldtype = oldtype->subtype; /* XXX */
 | |
|     } else
 | |
| 	t = new_type (TTag);
 | |
|     
 | |
|     t->tag.tagclass = tagclass;
 | |
|     t->tag.tagvalue = tagvalue;
 | |
|     t->tag.tagenv = tagenv;
 | |
|     t->subtype = oldtype;
 | |
|     return t;
 | |
| }
 | |
| 
 | |
| static struct objid *
 | |
| new_objid(const char *label, int value)
 | |
| {
 | |
|     struct objid *s;
 | |
|     s = emalloc(sizeof(*s));
 | |
|     s->label = label;
 | |
|     s->value = value;
 | |
|     s->next = NULL;
 | |
|     return s;
 | |
| }
 | |
| 
 | |
| static void
 | |
| add_oid_to_tail(struct objid *head, struct objid *tail)
 | |
| {
 | |
|     struct objid *o;
 | |
|     o = head;
 | |
|     while (o->next)
 | |
| 	o = o->next;
 | |
|     o->next = tail;
 | |
| }
 | |
| 
 | |
| static Type *
 | |
| new_type (Typetype tt)
 | |
| {
 | |
|     Type *t = ecalloc(1, sizeof(*t));
 | |
|     t->type = 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)
 | |
| {
 | |
|     Member *m;
 | |
| 
 | |
|     if(members == NULL)
 | |
| 	return;
 | |
|     ASN1_TAILQ_FOREACH(m, members, members) {
 | |
| 	asprintf(&m->label, "%s_%s", prefix, m->gen_name);
 | |
| 	if (m->label == NULL)
 | |
| 	    errx(1, "malloc");
 | |
| 	if(m->type != NULL)
 | |
| 	    fix_labels2(m->type, m->label);
 | |
|     }
 | |
| }
 | |
| 
 | |
| static void fix_labels2(Type *t, const char *prefix)
 | |
| {
 | |
|     for(; t; t = t->subtype)
 | |
| 	fix_labels1(t->members, prefix);
 | |
| }
 | |
| 
 | |
| static void
 | |
| fix_labels(Symbol *s)
 | |
| {
 | |
|     char *p;
 | |
|     asprintf(&p, "choice_%s", s->gen_name);
 | |
|     if (p == NULL)
 | |
| 	errx(1, "malloc");
 | |
|     fix_labels2(s->type, p);
 | |
|     free(p);
 | |
| }
 |