1226031Sstas/*
2226031Sstas * Copyright (c) 1997 - 2007 Kungliga Tekniska H��gskolan
3226031Sstas * (Royal Institute of Technology, Stockholm, Sweden).
4226031Sstas * All rights reserved.
5226031Sstas *
6226031Sstas * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
7226031Sstas *
8226031Sstas * Redistribution and use in source and binary forms, with or without
9226031Sstas * modification, are permitted provided that the following conditions
10226031Sstas * are met:
11226031Sstas *
12226031Sstas * 1. Redistributions of source code must retain the above copyright
13226031Sstas *    notice, this list of conditions and the following disclaimer.
14226031Sstas *
15226031Sstas * 2. Redistributions in binary form must reproduce the above copyright
16226031Sstas *    notice, this list of conditions and the following disclaimer in the
17226031Sstas *    documentation and/or other materials provided with the distribution.
18226031Sstas *
19226031Sstas * 3. Neither the name of the Institute nor the names of its contributors
20226031Sstas *    may be used to endorse or promote products derived from this software
21226031Sstas *    without specific prior written permission.
22226031Sstas *
23226031Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24226031Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25226031Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26226031Sstas * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27226031Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28226031Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29226031Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30226031Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31226031Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32226031Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33226031Sstas * SUCH DAMAGE.
34226031Sstas */
35226031Sstas
36226031Sstas/* $Id$ */
37226031Sstas
38226031Sstas%{
39226031Sstas
40226031Sstas#include <config.h>
41226031Sstas
42226031Sstas#include <stdio.h>
43226031Sstas#include <stdlib.h>
44226031Sstas#include <string.h>
45226031Sstas#include "symbol.h"
46226031Sstas#include "lex.h"
47226031Sstas#include "gen_locl.h"
48226031Sstas#include "der.h"
49226031Sstas
50226031SstasRCSID("$Id$");
51226031Sstas
52226031Sstasstatic Type *new_type (Typetype t);
53226031Sstasstatic struct constraint_spec *new_constraint_spec(enum ctype);
54226031Sstasstatic Type *new_tag(int tagclass, int tagvalue, int tagenv, Type *oldtype);
55226031Sstasvoid yyerror (const char *);
56226031Sstasstatic struct objid *new_objid(const char *label, int value);
57226031Sstasstatic void add_oid_to_tail(struct objid *, struct objid *);
58226031Sstasstatic void fix_labels(Symbol *s);
59226031Sstas
60226031Sstasstruct string_list {
61226031Sstas    char *string;
62226031Sstas    struct string_list *next;
63226031Sstas};
64226031Sstas
65226031Sstas/* Declarations for Bison */
66226031Sstas#define YYMALLOC malloc
67226031Sstas#define YYFREE   free
68226031Sstas
69226031Sstas%}
70226031Sstas
71226031Sstas%union {
72226031Sstas    int constant;
73226031Sstas    struct value *value;
74226031Sstas    struct range *range;
75226031Sstas    char *name;
76226031Sstas    Type *type;
77226031Sstas    Member *member;
78226031Sstas    struct objid *objid;
79226031Sstas    char *defval;
80226031Sstas    struct string_list *sl;
81226031Sstas    struct tagtype tag;
82226031Sstas    struct memhead *members;
83226031Sstas    struct constraint_spec *constraint_spec;
84226031Sstas}
85226031Sstas
86226031Sstas%token kw_ABSENT
87226031Sstas%token kw_ABSTRACT_SYNTAX
88226031Sstas%token kw_ALL
89226031Sstas%token kw_APPLICATION
90226031Sstas%token kw_AUTOMATIC
91226031Sstas%token kw_BEGIN
92226031Sstas%token kw_BIT
93226031Sstas%token kw_BMPString
94226031Sstas%token kw_BOOLEAN
95226031Sstas%token kw_BY
96226031Sstas%token kw_CHARACTER
97226031Sstas%token kw_CHOICE
98226031Sstas%token kw_CLASS
99226031Sstas%token kw_COMPONENT
100226031Sstas%token kw_COMPONENTS
101226031Sstas%token kw_CONSTRAINED
102226031Sstas%token kw_CONTAINING
103226031Sstas%token kw_DEFAULT
104226031Sstas%token kw_DEFINITIONS
105226031Sstas%token kw_EMBEDDED
106226031Sstas%token kw_ENCODED
107226031Sstas%token kw_END
108226031Sstas%token kw_ENUMERATED
109226031Sstas%token kw_EXCEPT
110226031Sstas%token kw_EXPLICIT
111226031Sstas%token kw_EXPORTS
112226031Sstas%token kw_EXTENSIBILITY
113226031Sstas%token kw_EXTERNAL
114226031Sstas%token kw_FALSE
115226031Sstas%token kw_FROM
116226031Sstas%token kw_GeneralString
117226031Sstas%token kw_GeneralizedTime
118226031Sstas%token kw_GraphicString
119226031Sstas%token kw_IA5String
120226031Sstas%token kw_IDENTIFIER
121226031Sstas%token kw_IMPLICIT
122226031Sstas%token kw_IMPLIED
123226031Sstas%token kw_IMPORTS
124226031Sstas%token kw_INCLUDES
125226031Sstas%token kw_INSTANCE
126226031Sstas%token kw_INTEGER
127226031Sstas%token kw_INTERSECTION
128226031Sstas%token kw_ISO646String
129226031Sstas%token kw_MAX
130226031Sstas%token kw_MIN
131226031Sstas%token kw_MINUS_INFINITY
132226031Sstas%token kw_NULL
133226031Sstas%token kw_NumericString
134226031Sstas%token kw_OBJECT
135226031Sstas%token kw_OCTET
136226031Sstas%token kw_OF
137226031Sstas%token kw_OPTIONAL
138226031Sstas%token kw_ObjectDescriptor
139226031Sstas%token kw_PATTERN
140226031Sstas%token kw_PDV
141226031Sstas%token kw_PLUS_INFINITY
142226031Sstas%token kw_PRESENT
143226031Sstas%token kw_PRIVATE
144226031Sstas%token kw_PrintableString
145226031Sstas%token kw_REAL
146226031Sstas%token kw_RELATIVE_OID
147226031Sstas%token kw_SEQUENCE
148226031Sstas%token kw_SET
149226031Sstas%token kw_SIZE
150226031Sstas%token kw_STRING
151226031Sstas%token kw_SYNTAX
152226031Sstas%token kw_T61String
153226031Sstas%token kw_TAGS
154226031Sstas%token kw_TRUE
155226031Sstas%token kw_TYPE_IDENTIFIER
156226031Sstas%token kw_TeletexString
157226031Sstas%token kw_UNION
158226031Sstas%token kw_UNIQUE
159226031Sstas%token kw_UNIVERSAL
160226031Sstas%token kw_UTCTime
161226031Sstas%token kw_UTF8String
162226031Sstas%token kw_UniversalString
163226031Sstas%token kw_VideotexString
164226031Sstas%token kw_VisibleString
165226031Sstas%token kw_WITH
166226031Sstas
167226031Sstas%token RANGE
168226031Sstas%token EEQUAL
169226031Sstas%token ELLIPSIS
170226031Sstas
171226031Sstas%token <name> IDENTIFIER  referencename
172226031Sstas%token <name> STRING
173226031Sstas
174226031Sstas%token <constant> NUMBER
175226031Sstas%type <constant> SignedNumber
176226031Sstas%type <constant> Class tagenv
177226031Sstas
178226031Sstas%type <value> Value
179226031Sstas%type <value> BuiltinValue
180226031Sstas%type <value> IntegerValue
181226031Sstas%type <value> BooleanValue
182226031Sstas%type <value> ObjectIdentifierValue
183226031Sstas%type <value> CharacterStringValue
184226031Sstas%type <value> NullValue
185226031Sstas%type <value> DefinedValue
186226031Sstas%type <value> ReferencedValue
187226031Sstas%type <value> Valuereference
188226031Sstas
189226031Sstas%type <type> Type
190226031Sstas%type <type> BuiltinType
191226031Sstas%type <type> BitStringType
192226031Sstas%type <type> BooleanType
193226031Sstas%type <type> ChoiceType
194226031Sstas%type <type> ConstrainedType
195226031Sstas%type <type> EnumeratedType
196226031Sstas%type <type> IntegerType
197226031Sstas%type <type> NullType
198226031Sstas%type <type> OctetStringType
199226031Sstas%type <type> SequenceType
200226031Sstas%type <type> SequenceOfType
201226031Sstas%type <type> SetType
202226031Sstas%type <type> SetOfType
203226031Sstas%type <type> TaggedType
204226031Sstas%type <type> ReferencedType
205226031Sstas%type <type> DefinedType
206226031Sstas%type <type> UsefulType
207226031Sstas%type <type> ObjectIdentifierType
208226031Sstas%type <type> CharacterStringType
209226031Sstas%type <type> RestrictedCharactedStringType
210226031Sstas
211226031Sstas%type <tag> Tag
212226031Sstas
213226031Sstas%type <member> ComponentType
214226031Sstas%type <member> NamedBit
215226031Sstas%type <member> NamedNumber
216226031Sstas%type <member> NamedType
217226031Sstas%type <members> ComponentTypeList
218226031Sstas%type <members> Enumerations
219226031Sstas%type <members> NamedBitList
220226031Sstas%type <members> NamedNumberList
221226031Sstas
222226031Sstas%type <objid> objid objid_list objid_element objid_opt
223226031Sstas%type <range> range size
224226031Sstas
225226031Sstas%type <sl> referencenames
226226031Sstas
227226031Sstas%type <constraint_spec> Constraint
228226031Sstas%type <constraint_spec> ConstraintSpec
229226031Sstas%type <constraint_spec> GeneralConstraint
230226031Sstas%type <constraint_spec> ContentsConstraint
231226031Sstas%type <constraint_spec> UserDefinedConstraint
232226031Sstas
233226031Sstas
234226031Sstas
235226031Sstas%start ModuleDefinition
236226031Sstas
237226031Sstas%%
238226031Sstas
239226031SstasModuleDefinition: IDENTIFIER objid_opt kw_DEFINITIONS TagDefault ExtensionDefault
240226031Sstas			EEQUAL kw_BEGIN ModuleBody kw_END
241226031Sstas		{
242226031Sstas			checkundefined();
243226031Sstas		}
244226031Sstas		;
245226031Sstas
246226031SstasTagDefault	: kw_EXPLICIT kw_TAGS
247226031Sstas		| kw_IMPLICIT kw_TAGS
248226031Sstas		      { lex_error_message("implicit tagging is not supported"); }
249226031Sstas		| kw_AUTOMATIC kw_TAGS
250226031Sstas		      { lex_error_message("automatic tagging is not supported"); }
251226031Sstas		| /* empty */
252226031Sstas		;
253226031Sstas
254226031SstasExtensionDefault: kw_EXTENSIBILITY kw_IMPLIED
255226031Sstas		      { lex_error_message("no extensibility options supported"); }
256226031Sstas		| /* empty */
257226031Sstas		;
258226031Sstas
259226031SstasModuleBody	: Exports Imports AssignmentList
260226031Sstas		| /* empty */
261226031Sstas		;
262226031Sstas
263226031SstasImports		: kw_IMPORTS SymbolsImported ';'
264226031Sstas		| /* empty */
265226031Sstas		;
266226031Sstas
267226031SstasSymbolsImported	: SymbolsFromModuleList
268226031Sstas		| /* empty */
269226031Sstas		;
270226031Sstas
271226031SstasSymbolsFromModuleList: SymbolsFromModule
272226031Sstas		| SymbolsFromModuleList SymbolsFromModule
273226031Sstas		;
274226031Sstas
275226031SstasSymbolsFromModule: referencenames kw_FROM IDENTIFIER objid_opt
276226031Sstas		{
277226031Sstas		    struct string_list *sl;
278226031Sstas		    for(sl = $1; sl != NULL; sl = sl->next) {
279226031Sstas			Symbol *s = addsym(sl->string);
280226031Sstas			s->stype = Stype;
281226031Sstas			gen_template_import(s);
282226031Sstas		    }
283226031Sstas		    add_import($3);
284226031Sstas		}
285226031Sstas		;
286226031Sstas
287226031SstasExports		: kw_EXPORTS referencenames ';'
288226031Sstas		{
289226031Sstas		    struct string_list *sl;
290226031Sstas		    for(sl = $2; sl != NULL; sl = sl->next)
291226031Sstas			add_export(sl->string);
292226031Sstas		}
293226031Sstas		| kw_EXPORTS kw_ALL
294226031Sstas		| /* empty */
295226031Sstas		;
296226031Sstas
297226031SstasAssignmentList	: Assignment
298226031Sstas		| Assignment AssignmentList
299226031Sstas		;
300226031Sstas
301226031SstasAssignment	: TypeAssignment
302226031Sstas		| ValueAssignment
303226031Sstas		;
304226031Sstas
305226031Sstasreferencenames	: IDENTIFIER ',' referencenames
306226031Sstas		{
307226031Sstas		    $$ = emalloc(sizeof(*$$));
308226031Sstas		    $$->string = $1;
309226031Sstas		    $$->next = $3;
310226031Sstas		}
311226031Sstas		| IDENTIFIER
312226031Sstas		{
313226031Sstas		    $$ = emalloc(sizeof(*$$));
314226031Sstas		    $$->string = $1;
315226031Sstas		    $$->next = NULL;
316226031Sstas		}
317226031Sstas		;
318226031Sstas
319226031SstasTypeAssignment	: IDENTIFIER EEQUAL Type
320226031Sstas		{
321226031Sstas		    Symbol *s = addsym ($1);
322226031Sstas		    s->stype = Stype;
323226031Sstas		    s->type = $3;
324226031Sstas		    fix_labels(s);
325226031Sstas		    generate_type (s);
326226031Sstas		}
327226031Sstas		;
328226031Sstas
329226031SstasType		: BuiltinType
330226031Sstas		| ReferencedType
331226031Sstas		| ConstrainedType
332226031Sstas		;
333226031Sstas
334226031SstasBuiltinType	: BitStringType
335226031Sstas		| BooleanType
336226031Sstas		| CharacterStringType
337226031Sstas		| ChoiceType
338226031Sstas		| EnumeratedType
339226031Sstas		| IntegerType
340226031Sstas		| NullType
341226031Sstas		| ObjectIdentifierType
342226031Sstas		| OctetStringType
343226031Sstas		| SequenceType
344226031Sstas		| SequenceOfType
345226031Sstas		| SetType
346226031Sstas		| SetOfType
347226031Sstas		| TaggedType
348226031Sstas		;
349226031Sstas
350226031SstasBooleanType	: kw_BOOLEAN
351226031Sstas		{
352226031Sstas			$$ = new_tag(ASN1_C_UNIV, UT_Boolean,
353226031Sstas				     TE_EXPLICIT, new_type(TBoolean));
354226031Sstas		}
355226031Sstas		;
356226031Sstas
357226031Sstasrange		: '(' Value RANGE Value ')'
358226031Sstas		{
359226031Sstas		    if($2->type != integervalue)
360226031Sstas			lex_error_message("Non-integer used in first part of range");
361226031Sstas		    if($2->type != integervalue)
362226031Sstas			lex_error_message("Non-integer in second part of range");
363226031Sstas		    $$ = ecalloc(1, sizeof(*$$));
364226031Sstas		    $$->min = $2->u.integervalue;
365226031Sstas		    $$->max = $4->u.integervalue;
366226031Sstas		}
367226031Sstas		| '(' Value RANGE kw_MAX ')'
368226031Sstas		{
369226031Sstas		    if($2->type != integervalue)
370226031Sstas			lex_error_message("Non-integer in first part of range");
371226031Sstas		    $$ = ecalloc(1, sizeof(*$$));
372226031Sstas		    $$->min = $2->u.integervalue;
373226031Sstas		    $$->max = $2->u.integervalue - 1;
374226031Sstas		}
375226031Sstas		| '(' kw_MIN RANGE Value ')'
376226031Sstas		{
377226031Sstas		    if($4->type != integervalue)
378226031Sstas			lex_error_message("Non-integer in second part of range");
379226031Sstas		    $$ = ecalloc(1, sizeof(*$$));
380226031Sstas		    $$->min = $4->u.integervalue + 2;
381226031Sstas		    $$->max = $4->u.integervalue;
382226031Sstas		}
383226031Sstas		| '(' Value ')'
384226031Sstas		{
385226031Sstas		    if($2->type != integervalue)
386226031Sstas			lex_error_message("Non-integer used in limit");
387226031Sstas		    $$ = ecalloc(1, sizeof(*$$));
388226031Sstas		    $$->min = $2->u.integervalue;
389226031Sstas		    $$->max = $2->u.integervalue;
390226031Sstas		}
391226031Sstas		;
392226031Sstas
393226031Sstas
394226031SstasIntegerType	: kw_INTEGER
395226031Sstas		{
396226031Sstas			$$ = new_tag(ASN1_C_UNIV, UT_Integer,
397226031Sstas				     TE_EXPLICIT, new_type(TInteger));
398226031Sstas		}
399226031Sstas		| kw_INTEGER range
400226031Sstas		{
401226031Sstas			$$ = new_type(TInteger);
402226031Sstas			$$->range = $2;
403226031Sstas			$$ = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, $$);
404226031Sstas		}
405226031Sstas		| kw_INTEGER '{' NamedNumberList '}'
406226031Sstas		{
407226031Sstas		  $$ = new_type(TInteger);
408226031Sstas		  $$->members = $3;
409226031Sstas		  $$ = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, $$);
410226031Sstas		}
411226031Sstas		;
412226031Sstas
413226031SstasNamedNumberList	: NamedNumber
414226031Sstas		{
415226031Sstas			$$ = emalloc(sizeof(*$$));
416226031Sstas			ASN1_TAILQ_INIT($$);
417226031Sstas			ASN1_TAILQ_INSERT_HEAD($$, $1, members);
418226031Sstas		}
419226031Sstas		| NamedNumberList ',' NamedNumber
420226031Sstas		{
421226031Sstas			ASN1_TAILQ_INSERT_TAIL($1, $3, members);
422226031Sstas			$$ = $1;
423226031Sstas		}
424226031Sstas		| NamedNumberList ',' ELLIPSIS
425226031Sstas			{ $$ = $1; } /* XXX used for Enumerations */
426226031Sstas		;
427226031Sstas
428226031SstasNamedNumber	: IDENTIFIER '(' SignedNumber ')'
429226031Sstas		{
430226031Sstas			$$ = emalloc(sizeof(*$$));
431226031Sstas			$$->name = $1;
432226031Sstas			$$->gen_name = estrdup($1);
433226031Sstas			output_name ($$->gen_name);
434226031Sstas			$$->val = $3;
435226031Sstas			$$->optional = 0;
436226031Sstas			$$->ellipsis = 0;
437226031Sstas			$$->type = NULL;
438226031Sstas		}
439226031Sstas		;
440226031Sstas
441226031SstasEnumeratedType	: kw_ENUMERATED '{' Enumerations '}'
442226031Sstas		{
443226031Sstas		  $$ = new_type(TInteger);
444226031Sstas		  $$->members = $3;
445226031Sstas		  $$ = new_tag(ASN1_C_UNIV, UT_Enumerated, TE_EXPLICIT, $$);
446226031Sstas		}
447226031Sstas		;
448226031Sstas
449226031SstasEnumerations	: NamedNumberList /* XXX */
450226031Sstas		;
451226031Sstas
452226031SstasBitStringType	: kw_BIT kw_STRING
453226031Sstas		{
454226031Sstas		  $$ = new_type(TBitString);
455226031Sstas		  $$->members = emalloc(sizeof(*$$->members));
456226031Sstas		  ASN1_TAILQ_INIT($$->members);
457226031Sstas		  $$ = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, $$);
458226031Sstas		}
459226031Sstas		| kw_BIT kw_STRING '{' NamedBitList '}'
460226031Sstas		{
461226031Sstas		  $$ = new_type(TBitString);
462226031Sstas		  $$->members = $4;
463226031Sstas		  $$ = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, $$);
464226031Sstas		}
465226031Sstas		;
466226031Sstas
467226031SstasObjectIdentifierType: kw_OBJECT kw_IDENTIFIER
468226031Sstas		{
469226031Sstas			$$ = new_tag(ASN1_C_UNIV, UT_OID,
470226031Sstas				     TE_EXPLICIT, new_type(TOID));
471226031Sstas		}
472226031Sstas		;
473226031SstasOctetStringType	: kw_OCTET kw_STRING size
474226031Sstas		{
475226031Sstas		    Type *t = new_type(TOctetString);
476226031Sstas		    t->range = $3;
477226031Sstas		    $$ = new_tag(ASN1_C_UNIV, UT_OctetString,
478226031Sstas				 TE_EXPLICIT, t);
479226031Sstas		}
480226031Sstas		;
481226031Sstas
482226031SstasNullType	: kw_NULL
483226031Sstas		{
484226031Sstas			$$ = new_tag(ASN1_C_UNIV, UT_Null,
485226031Sstas				     TE_EXPLICIT, new_type(TNull));
486226031Sstas		}
487226031Sstas		;
488226031Sstas
489226031Sstassize		:
490226031Sstas		{ $$ = NULL; }
491226031Sstas		| kw_SIZE range
492226031Sstas		{ $$ = $2; }
493226031Sstas		;
494226031Sstas
495226031Sstas
496226031SstasSequenceType	: kw_SEQUENCE '{' /* ComponentTypeLists */ ComponentTypeList '}'
497226031Sstas		{
498226031Sstas		  $$ = new_type(TSequence);
499226031Sstas		  $$->members = $3;
500226031Sstas		  $$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
501226031Sstas		}
502226031Sstas		| kw_SEQUENCE '{' '}'
503226031Sstas		{
504226031Sstas		  $$ = new_type(TSequence);
505226031Sstas		  $$->members = NULL;
506226031Sstas		  $$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
507226031Sstas		}
508226031Sstas		;
509226031Sstas
510226031SstasSequenceOfType	: kw_SEQUENCE size kw_OF Type
511226031Sstas		{
512226031Sstas		  $$ = new_type(TSequenceOf);
513226031Sstas		  $$->range = $2;
514226031Sstas		  $$->subtype = $4;
515226031Sstas		  $$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
516226031Sstas		}
517226031Sstas		;
518226031Sstas
519226031SstasSetType		: kw_SET '{' /* ComponentTypeLists */ ComponentTypeList '}'
520226031Sstas		{
521226031Sstas		  $$ = new_type(TSet);
522226031Sstas		  $$->members = $3;
523226031Sstas		  $$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
524226031Sstas		}
525226031Sstas		| kw_SET '{' '}'
526226031Sstas		{
527226031Sstas		  $$ = new_type(TSet);
528226031Sstas		  $$->members = NULL;
529226031Sstas		  $$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
530226031Sstas		}
531226031Sstas		;
532226031Sstas
533226031SstasSetOfType	: kw_SET kw_OF Type
534226031Sstas		{
535226031Sstas		  $$ = new_type(TSetOf);
536226031Sstas		  $$->subtype = $3;
537226031Sstas		  $$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
538226031Sstas		}
539226031Sstas		;
540226031Sstas
541226031SstasChoiceType	: kw_CHOICE '{' /* AlternativeTypeLists */ ComponentTypeList '}'
542226031Sstas		{
543226031Sstas		  $$ = new_type(TChoice);
544226031Sstas		  $$->members = $3;
545226031Sstas		}
546226031Sstas		;
547226031Sstas
548226031SstasReferencedType	: DefinedType
549226031Sstas		| UsefulType
550226031Sstas		;
551226031Sstas
552226031SstasDefinedType	: IDENTIFIER
553226031Sstas		{
554226031Sstas		  Symbol *s = addsym($1);
555226031Sstas		  $$ = new_type(TType);
556226031Sstas		  if(s->stype != Stype && s->stype != SUndefined)
557226031Sstas		    lex_error_message ("%s is not a type\n", $1);
558226031Sstas		  else
559226031Sstas		    $$->symbol = s;
560226031Sstas		}
561226031Sstas		;
562226031Sstas
563226031SstasUsefulType	: kw_GeneralizedTime
564226031Sstas		{
565226031Sstas			$$ = new_tag(ASN1_C_UNIV, UT_GeneralizedTime,
566226031Sstas				     TE_EXPLICIT, new_type(TGeneralizedTime));
567226031Sstas		}
568226031Sstas		| kw_UTCTime
569226031Sstas		{
570226031Sstas			$$ = new_tag(ASN1_C_UNIV, UT_UTCTime,
571226031Sstas				     TE_EXPLICIT, new_type(TUTCTime));
572226031Sstas		}
573226031Sstas		;
574226031Sstas
575226031SstasConstrainedType	: Type Constraint
576226031Sstas		{
577226031Sstas		    /* if (Constraint.type == contentConstrant) {
578226031Sstas		       assert(Constraint.u.constraint.type == octetstring|bitstring-w/o-NamedBitList); // remember to check type reference too
579226031Sstas		       if (Constraint.u.constraint.type) {
580226031Sstas		         assert((Constraint.u.constraint.type.length % 8) == 0);
581226031Sstas		       }
582226031Sstas		      }
583226031Sstas		      if (Constraint.u.constraint.encoding) {
584226031Sstas		        type == der-oid|ber-oid
585226031Sstas		      }
586226031Sstas		    */
587226031Sstas		}
588226031Sstas		;
589226031Sstas
590226031Sstas
591226031SstasConstraint	: '(' ConstraintSpec ')'
592226031Sstas		{
593226031Sstas		    $$ = $2;
594226031Sstas		}
595226031Sstas		;
596226031Sstas
597226031SstasConstraintSpec	: GeneralConstraint
598226031Sstas		;
599226031Sstas
600226031SstasGeneralConstraint: ContentsConstraint
601226031Sstas		| UserDefinedConstraint
602226031Sstas		;
603226031Sstas
604226031SstasContentsConstraint: kw_CONTAINING Type
605226031Sstas		{
606226031Sstas		    $$ = new_constraint_spec(CT_CONTENTS);
607226031Sstas		    $$->u.content.type = $2;
608226031Sstas		    $$->u.content.encoding = NULL;
609226031Sstas		}
610226031Sstas		| kw_ENCODED kw_BY Value
611226031Sstas		{
612226031Sstas		    if ($3->type != objectidentifiervalue)
613226031Sstas			lex_error_message("Non-OID used in ENCODED BY constraint");
614226031Sstas		    $$ = new_constraint_spec(CT_CONTENTS);
615226031Sstas		    $$->u.content.type = NULL;
616226031Sstas		    $$->u.content.encoding = $3;
617226031Sstas		}
618226031Sstas		| kw_CONTAINING Type kw_ENCODED kw_BY Value
619226031Sstas		{
620226031Sstas		    if ($5->type != objectidentifiervalue)
621226031Sstas			lex_error_message("Non-OID used in ENCODED BY constraint");
622226031Sstas		    $$ = new_constraint_spec(CT_CONTENTS);
623226031Sstas		    $$->u.content.type = $2;
624226031Sstas		    $$->u.content.encoding = $5;
625226031Sstas		}
626226031Sstas		;
627226031Sstas
628226031SstasUserDefinedConstraint: kw_CONSTRAINED kw_BY '{' '}'
629226031Sstas		{
630226031Sstas		    $$ = new_constraint_spec(CT_USER);
631226031Sstas		}
632226031Sstas		;
633226031Sstas
634226031SstasTaggedType	: Tag tagenv Type
635226031Sstas		{
636226031Sstas			$$ = new_type(TTag);
637226031Sstas			$$->tag = $1;
638226031Sstas			$$->tag.tagenv = $2;
639226031Sstas			if($3->type == TTag && $2 == TE_IMPLICIT) {
640226031Sstas				$$->subtype = $3->subtype;
641226031Sstas				free($3);
642226031Sstas			} else
643226031Sstas				$$->subtype = $3;
644226031Sstas		}
645226031Sstas		;
646226031Sstas
647226031SstasTag		: '[' Class NUMBER ']'
648226031Sstas		{
649226031Sstas			$$.tagclass = $2;
650226031Sstas			$$.tagvalue = $3;
651226031Sstas			$$.tagenv = TE_EXPLICIT;
652226031Sstas		}
653226031Sstas		;
654226031Sstas
655226031SstasClass		: /* */
656226031Sstas		{
657226031Sstas			$$ = ASN1_C_CONTEXT;
658226031Sstas		}
659226031Sstas		| kw_UNIVERSAL
660226031Sstas		{
661226031Sstas			$$ = ASN1_C_UNIV;
662226031Sstas		}
663226031Sstas		| kw_APPLICATION
664226031Sstas		{
665226031Sstas			$$ = ASN1_C_APPL;
666226031Sstas		}
667226031Sstas		| kw_PRIVATE
668226031Sstas		{
669226031Sstas			$$ = ASN1_C_PRIVATE;
670226031Sstas		}
671226031Sstas		;
672226031Sstas
673226031Sstastagenv		: /* */
674226031Sstas		{
675226031Sstas			$$ = TE_EXPLICIT;
676226031Sstas		}
677226031Sstas		| kw_EXPLICIT
678226031Sstas		{
679226031Sstas			$$ = TE_EXPLICIT;
680226031Sstas		}
681226031Sstas		| kw_IMPLICIT
682226031Sstas		{
683226031Sstas			$$ = TE_IMPLICIT;
684226031Sstas		}
685226031Sstas		;
686226031Sstas
687226031Sstas
688226031SstasValueAssignment	: IDENTIFIER Type EEQUAL Value
689226031Sstas		{
690226031Sstas			Symbol *s;
691226031Sstas			s = addsym ($1);
692226031Sstas
693226031Sstas			s->stype = SValue;
694226031Sstas			s->value = $4;
695226031Sstas			generate_constant (s);
696226031Sstas		}
697226031Sstas		;
698226031Sstas
699226031SstasCharacterStringType: RestrictedCharactedStringType
700226031Sstas		;
701226031Sstas
702226031SstasRestrictedCharactedStringType: kw_GeneralString
703226031Sstas		{
704226031Sstas			$$ = new_tag(ASN1_C_UNIV, UT_GeneralString,
705226031Sstas				     TE_EXPLICIT, new_type(TGeneralString));
706226031Sstas		}
707226031Sstas		| kw_TeletexString
708226031Sstas		{
709226031Sstas			$$ = new_tag(ASN1_C_UNIV, UT_TeletexString,
710226031Sstas				     TE_EXPLICIT, new_type(TTeletexString));
711226031Sstas		}
712226031Sstas		| kw_UTF8String
713226031Sstas		{
714226031Sstas			$$ = new_tag(ASN1_C_UNIV, UT_UTF8String,
715226031Sstas				     TE_EXPLICIT, new_type(TUTF8String));
716226031Sstas		}
717226031Sstas		| kw_PrintableString
718226031Sstas		{
719226031Sstas			$$ = new_tag(ASN1_C_UNIV, UT_PrintableString,
720226031Sstas				     TE_EXPLICIT, new_type(TPrintableString));
721226031Sstas		}
722226031Sstas		| kw_VisibleString
723226031Sstas		{
724226031Sstas			$$ = new_tag(ASN1_C_UNIV, UT_VisibleString,
725226031Sstas				     TE_EXPLICIT, new_type(TVisibleString));
726226031Sstas		}
727226031Sstas		| kw_IA5String
728226031Sstas		{
729226031Sstas			$$ = new_tag(ASN1_C_UNIV, UT_IA5String,
730226031Sstas				     TE_EXPLICIT, new_type(TIA5String));
731226031Sstas		}
732226031Sstas		| kw_BMPString
733226031Sstas		{
734226031Sstas			$$ = new_tag(ASN1_C_UNIV, UT_BMPString,
735226031Sstas				     TE_EXPLICIT, new_type(TBMPString));
736226031Sstas		}
737226031Sstas		| kw_UniversalString
738226031Sstas		{
739226031Sstas			$$ = new_tag(ASN1_C_UNIV, UT_UniversalString,
740226031Sstas				     TE_EXPLICIT, new_type(TUniversalString));
741226031Sstas		}
742226031Sstas
743226031Sstas		;
744226031Sstas
745226031SstasComponentTypeList: ComponentType
746226031Sstas		{
747226031Sstas			$$ = emalloc(sizeof(*$$));
748226031Sstas			ASN1_TAILQ_INIT($$);
749226031Sstas			ASN1_TAILQ_INSERT_HEAD($$, $1, members);
750226031Sstas		}
751226031Sstas		| ComponentTypeList ',' ComponentType
752226031Sstas		{
753226031Sstas			ASN1_TAILQ_INSERT_TAIL($1, $3, members);
754226031Sstas			$$ = $1;
755226031Sstas		}
756226031Sstas		| ComponentTypeList ',' ELLIPSIS
757226031Sstas		{
758226031Sstas		        struct member *m = ecalloc(1, sizeof(*m));
759226031Sstas			m->name = estrdup("...");
760226031Sstas			m->gen_name = estrdup("asn1_ellipsis");
761226031Sstas			m->ellipsis = 1;
762226031Sstas			ASN1_TAILQ_INSERT_TAIL($1, m, members);
763226031Sstas			$$ = $1;
764226031Sstas		}
765226031Sstas		;
766226031Sstas
767226031SstasNamedType	: IDENTIFIER Type
768226031Sstas		{
769226031Sstas		  $$ = emalloc(sizeof(*$$));
770226031Sstas		  $$->name = $1;
771226031Sstas		  $$->gen_name = estrdup($1);
772226031Sstas		  output_name ($$->gen_name);
773226031Sstas		  $$->type = $2;
774226031Sstas		  $$->ellipsis = 0;
775226031Sstas		}
776226031Sstas		;
777226031Sstas
778226031SstasComponentType	: NamedType
779226031Sstas		{
780226031Sstas			$$ = $1;
781226031Sstas			$$->optional = 0;
782226031Sstas			$$->defval = NULL;
783226031Sstas		}
784226031Sstas		| NamedType kw_OPTIONAL
785226031Sstas		{
786226031Sstas			$$ = $1;
787226031Sstas			$$->optional = 1;
788226031Sstas			$$->defval = NULL;
789226031Sstas		}
790226031Sstas		| NamedType kw_DEFAULT Value
791226031Sstas		{
792226031Sstas			$$ = $1;
793226031Sstas			$$->optional = 0;
794226031Sstas			$$->defval = $3;
795226031Sstas		}
796226031Sstas		;
797226031Sstas
798226031SstasNamedBitList	: NamedBit
799226031Sstas		{
800226031Sstas			$$ = emalloc(sizeof(*$$));
801226031Sstas			ASN1_TAILQ_INIT($$);
802226031Sstas			ASN1_TAILQ_INSERT_HEAD($$, $1, members);
803226031Sstas		}
804226031Sstas		| NamedBitList ',' NamedBit
805226031Sstas		{
806226031Sstas			ASN1_TAILQ_INSERT_TAIL($1, $3, members);
807226031Sstas			$$ = $1;
808226031Sstas		}
809226031Sstas		;
810226031Sstas
811226031SstasNamedBit	: IDENTIFIER '(' NUMBER ')'
812226031Sstas		{
813226031Sstas		  $$ = emalloc(sizeof(*$$));
814226031Sstas		  $$->name = $1;
815226031Sstas		  $$->gen_name = estrdup($1);
816226031Sstas		  output_name ($$->gen_name);
817226031Sstas		  $$->val = $3;
818226031Sstas		  $$->optional = 0;
819226031Sstas		  $$->ellipsis = 0;
820226031Sstas		  $$->type = NULL;
821226031Sstas		}
822226031Sstas		;
823226031Sstas
824226031Sstasobjid_opt	: objid
825226031Sstas		| /* empty */ { $$ = NULL; }
826226031Sstas		;
827226031Sstas
828226031Sstasobjid		: '{' objid_list '}'
829226031Sstas		{
830226031Sstas			$$ = $2;
831226031Sstas		}
832226031Sstas		;
833226031Sstas
834226031Sstasobjid_list	:  /* empty */
835226031Sstas		{
836226031Sstas			$$ = NULL;
837226031Sstas		}
838226031Sstas		| objid_element objid_list
839226031Sstas		{
840226031Sstas		        if ($2) {
841226031Sstas				$$ = $2;
842226031Sstas				add_oid_to_tail($2, $1);
843226031Sstas			} else {
844226031Sstas				$$ = $1;
845226031Sstas			}
846226031Sstas		}
847226031Sstas		;
848226031Sstas
849226031Sstasobjid_element	: IDENTIFIER '(' NUMBER ')'
850226031Sstas		{
851226031Sstas			$$ = new_objid($1, $3);
852226031Sstas		}
853226031Sstas		| IDENTIFIER
854226031Sstas		{
855226031Sstas		    Symbol *s = addsym($1);
856226031Sstas		    if(s->stype != SValue ||
857226031Sstas		       s->value->type != objectidentifiervalue) {
858226031Sstas			lex_error_message("%s is not an object identifier\n",
859226031Sstas				      s->name);
860226031Sstas			exit(1);
861226031Sstas		    }
862226031Sstas		    $$ = s->value->u.objectidentifiervalue;
863226031Sstas		}
864226031Sstas		| NUMBER
865226031Sstas		{
866226031Sstas		    $$ = new_objid(NULL, $1);
867226031Sstas		}
868226031Sstas		;
869226031Sstas
870226031SstasValue		: BuiltinValue
871226031Sstas		| ReferencedValue
872226031Sstas		;
873226031Sstas
874226031SstasBuiltinValue	: BooleanValue
875226031Sstas		| CharacterStringValue
876226031Sstas		| IntegerValue
877226031Sstas		| ObjectIdentifierValue
878226031Sstas		| NullValue
879226031Sstas		;
880226031Sstas
881226031SstasReferencedValue	: DefinedValue
882226031Sstas		;
883226031Sstas
884226031SstasDefinedValue	: Valuereference
885226031Sstas		;
886226031Sstas
887226031SstasValuereference	: IDENTIFIER
888226031Sstas		{
889226031Sstas			Symbol *s = addsym($1);
890226031Sstas			if(s->stype != SValue)
891226031Sstas				lex_error_message ("%s is not a value\n",
892226031Sstas						s->name);
893226031Sstas			else
894226031Sstas				$$ = s->value;
895226031Sstas		}
896226031Sstas		;
897226031Sstas
898226031SstasCharacterStringValue: STRING
899226031Sstas		{
900226031Sstas			$$ = emalloc(sizeof(*$$));
901226031Sstas			$$->type = stringvalue;
902226031Sstas			$$->u.stringvalue = $1;
903226031Sstas		}
904226031Sstas		;
905226031Sstas
906226031SstasBooleanValue	: kw_TRUE
907226031Sstas		{
908226031Sstas			$$ = emalloc(sizeof(*$$));
909226031Sstas			$$->type = booleanvalue;
910226031Sstas			$$->u.booleanvalue = 0;
911226031Sstas		}
912226031Sstas		| kw_FALSE
913226031Sstas		{
914226031Sstas			$$ = emalloc(sizeof(*$$));
915226031Sstas			$$->type = booleanvalue;
916226031Sstas			$$->u.booleanvalue = 0;
917226031Sstas		}
918226031Sstas		;
919226031Sstas
920226031SstasIntegerValue	: SignedNumber
921226031Sstas		{
922226031Sstas			$$ = emalloc(sizeof(*$$));
923226031Sstas			$$->type = integervalue;
924226031Sstas			$$->u.integervalue = $1;
925226031Sstas		}
926226031Sstas		;
927226031Sstas
928226031SstasSignedNumber	: NUMBER
929226031Sstas		;
930226031Sstas
931226031SstasNullValue	: kw_NULL
932226031Sstas		{
933226031Sstas		}
934226031Sstas		;
935226031Sstas
936226031SstasObjectIdentifierValue: objid
937226031Sstas		{
938226031Sstas			$$ = emalloc(sizeof(*$$));
939226031Sstas			$$->type = objectidentifiervalue;
940226031Sstas			$$->u.objectidentifiervalue = $1;
941226031Sstas		}
942226031Sstas		;
943226031Sstas
944226031Sstas%%
945226031Sstas
946226031Sstasvoid
947226031Sstasyyerror (const char *s)
948226031Sstas{
949226031Sstas     lex_error_message ("%s\n", s);
950226031Sstas}
951226031Sstas
952226031Sstasstatic Type *
953226031Sstasnew_tag(int tagclass, int tagvalue, int tagenv, Type *oldtype)
954226031Sstas{
955226031Sstas    Type *t;
956226031Sstas    if(oldtype->type == TTag && oldtype->tag.tagenv == TE_IMPLICIT) {
957226031Sstas	t = oldtype;
958226031Sstas	oldtype = oldtype->subtype; /* XXX */
959226031Sstas    } else
960226031Sstas	t = new_type (TTag);
961226031Sstas
962226031Sstas    t->tag.tagclass = tagclass;
963226031Sstas    t->tag.tagvalue = tagvalue;
964226031Sstas    t->tag.tagenv = tagenv;
965226031Sstas    t->subtype = oldtype;
966226031Sstas    return t;
967226031Sstas}
968226031Sstas
969226031Sstasstatic struct objid *
970226031Sstasnew_objid(const char *label, int value)
971226031Sstas{
972226031Sstas    struct objid *s;
973226031Sstas    s = emalloc(sizeof(*s));
974226031Sstas    s->label = label;
975226031Sstas    s->value = value;
976226031Sstas    s->next = NULL;
977226031Sstas    return s;
978226031Sstas}
979226031Sstas
980226031Sstasstatic void
981226031Sstasadd_oid_to_tail(struct objid *head, struct objid *tail)
982226031Sstas{
983226031Sstas    struct objid *o;
984226031Sstas    o = head;
985226031Sstas    while (o->next)
986226031Sstas	o = o->next;
987226031Sstas    o->next = tail;
988226031Sstas}
989226031Sstas
990226031Sstasstatic Type *
991226031Sstasnew_type (Typetype tt)
992226031Sstas{
993226031Sstas    Type *t = ecalloc(1, sizeof(*t));
994226031Sstas    t->type = tt;
995226031Sstas    return t;
996226031Sstas}
997226031Sstas
998226031Sstasstatic struct constraint_spec *
999226031Sstasnew_constraint_spec(enum ctype ct)
1000226031Sstas{
1001226031Sstas    struct constraint_spec *c = ecalloc(1, sizeof(*c));
1002226031Sstas    c->ctype = ct;
1003226031Sstas    return c;
1004226031Sstas}
1005226031Sstas
1006226031Sstasstatic void fix_labels2(Type *t, const char *prefix);
1007226031Sstasstatic void fix_labels1(struct memhead *members, const char *prefix)
1008226031Sstas{
1009226031Sstas    Member *m;
1010226031Sstas
1011226031Sstas    if(members == NULL)
1012226031Sstas	return;
1013226031Sstas    ASN1_TAILQ_FOREACH(m, members, members) {
1014226031Sstas	if (asprintf(&m->label, "%s_%s", prefix, m->gen_name) < 0)
1015226031Sstas	    errx(1, "malloc");
1016226031Sstas	if (m->label == NULL)
1017226031Sstas	    errx(1, "malloc");
1018226031Sstas	if(m->type != NULL)
1019226031Sstas	    fix_labels2(m->type, m->label);
1020226031Sstas    }
1021226031Sstas}
1022226031Sstas
1023226031Sstasstatic void fix_labels2(Type *t, const char *prefix)
1024226031Sstas{
1025226031Sstas    for(; t; t = t->subtype)
1026226031Sstas	fix_labels1(t->members, prefix);
1027226031Sstas}
1028226031Sstas
1029226031Sstasstatic void
1030226031Sstasfix_labels(Symbol *s)
1031226031Sstas{
1032226031Sstas    char *p = NULL;
1033226031Sstas    if (asprintf(&p, "choice_%s", s->gen_name) < 0 || p == NULL)
1034226031Sstas	errx(1, "malloc");
1035226031Sstas    fix_labels2(s->type, p);
1036226031Sstas    free(p);
1037226031Sstas}
1038