1/*
2 * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * 3. Neither the name of the Institute nor the names of its contributors
20 *    may be used to endorse or promote products derived from this software
21 *    without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36/* $Id$ */
37
38%{
39
40#include <config.h>
41
42#include <stdio.h>
43#include <stdlib.h>
44#include <string.h>
45#include "symbol.h"
46#include "lex.h"
47#include "gen_locl.h"
48#include "der.h"
49
50RCSID("$Id$");
51
52static Type *new_type (Typetype t);
53static struct constraint_spec *new_constraint_spec(enum ctype);
54static Type *new_tag(int tagclass, int tagvalue, int tagenv, Type *oldtype);
55void yyerror (const char *);
56static struct objid *new_objid(const char *label, int value);
57static void add_oid_to_tail(struct objid *, struct objid *);
58static void fix_labels(Symbol *s);
59
60struct string_list {
61    char *string;
62    struct string_list *next;
63};
64
65/* Declarations for Bison */
66#define YYMALLOC malloc
67#define YYFREE   free
68
69%}
70
71%union {
72    int constant;
73    struct value *value;
74    struct range *range;
75    char *name;
76    Type *type;
77    Member *member;
78    struct objid *objid;
79    char *defval;
80    struct string_list *sl;
81    struct tagtype tag;
82    struct memhead *members;
83    struct constraint_spec *constraint_spec;
84}
85
86%token kw_ABSENT
87%token kw_ABSTRACT_SYNTAX
88%token kw_ALL
89%token kw_APPLICATION
90%token kw_AUTOMATIC
91%token kw_BEGIN
92%token kw_BIT
93%token kw_BMPString
94%token kw_BOOLEAN
95%token kw_BY
96%token kw_CHARACTER
97%token kw_CHOICE
98%token kw_CLASS
99%token kw_COMPONENT
100%token kw_COMPONENTS
101%token kw_CONSTRAINED
102%token kw_CONTAINING
103%token kw_DEFAULT
104%token kw_DEFINITIONS
105%token kw_EMBEDDED
106%token kw_ENCODED
107%token kw_END
108%token kw_ENUMERATED
109%token kw_EXCEPT
110%token kw_EXPLICIT
111%token kw_EXPORTS
112%token kw_EXTENSIBILITY
113%token kw_EXTERNAL
114%token kw_FALSE
115%token kw_FROM
116%token kw_GeneralString
117%token kw_GeneralizedTime
118%token kw_GraphicString
119%token kw_IA5String
120%token kw_IDENTIFIER
121%token kw_IMPLICIT
122%token kw_IMPLIED
123%token kw_IMPORTS
124%token kw_INCLUDES
125%token kw_INSTANCE
126%token kw_INTEGER
127%token kw_INTERSECTION
128%token kw_ISO646String
129%token kw_MAX
130%token kw_MIN
131%token kw_MINUS_INFINITY
132%token kw_NULL
133%token kw_NumericString
134%token kw_OBJECT
135%token kw_OCTET
136%token kw_OF
137%token kw_OPTIONAL
138%token kw_ObjectDescriptor
139%token kw_PATTERN
140%token kw_PDV
141%token kw_PLUS_INFINITY
142%token kw_PRESENT
143%token kw_PRIVATE
144%token kw_PrintableString
145%token kw_REAL
146%token kw_RELATIVE_OID
147%token kw_SEQUENCE
148%token kw_SET
149%token kw_SIZE
150%token kw_STRING
151%token kw_SYNTAX
152%token kw_T61String
153%token kw_TAGS
154%token kw_TRUE
155%token kw_TYPE_IDENTIFIER
156%token kw_TeletexString
157%token kw_UNION
158%token kw_UNIQUE
159%token kw_UNIVERSAL
160%token kw_UTCTime
161%token kw_UTF8String
162%token kw_UniversalString
163%token kw_VideotexString
164%token kw_VisibleString
165%token kw_WITH
166
167%token RANGE
168%token EEQUAL
169%token ELLIPSIS
170
171%token <name> IDENTIFIER  referencename
172%token <name> STRING
173
174%token <constant> NUMBER
175%type <constant> SignedNumber
176%type <constant> Class tagenv
177
178%type <value> Value
179%type <value> BuiltinValue
180%type <value> IntegerValue
181%type <value> BooleanValue
182%type <value> ObjectIdentifierValue
183%type <value> CharacterStringValue
184%type <value> NullValue
185%type <value> DefinedValue
186%type <value> ReferencedValue
187%type <value> Valuereference
188
189%type <type> Type
190%type <type> BuiltinType
191%type <type> BitStringType
192%type <type> BooleanType
193%type <type> ChoiceType
194%type <type> ConstrainedType
195%type <type> EnumeratedType
196%type <type> IntegerType
197%type <type> NullType
198%type <type> OctetStringType
199%type <type> SequenceType
200%type <type> SequenceOfType
201%type <type> SetType
202%type <type> SetOfType
203%type <type> TaggedType
204%type <type> ReferencedType
205%type <type> DefinedType
206%type <type> UsefulType
207%type <type> ObjectIdentifierType
208%type <type> CharacterStringType
209%type <type> RestrictedCharactedStringType
210
211%type <tag> Tag
212
213%type <member> ComponentType
214%type <member> NamedBit
215%type <member> NamedNumber
216%type <member> NamedType
217%type <members> ComponentTypeList
218%type <members> Enumerations
219%type <members> NamedBitList
220%type <members> NamedNumberList
221
222%type <objid> objid objid_list objid_element objid_opt
223%type <range> range size
224
225%type <sl> referencenames
226
227%type <constraint_spec> Constraint
228%type <constraint_spec> ConstraintSpec
229%type <constraint_spec> GeneralConstraint
230%type <constraint_spec> ContentsConstraint
231%type <constraint_spec> UserDefinedConstraint
232
233
234
235%start ModuleDefinition
236
237%%
238
239ModuleDefinition: IDENTIFIER objid_opt kw_DEFINITIONS TagDefault ExtensionDefault
240			EEQUAL kw_BEGIN ModuleBody kw_END
241		{
242			checkundefined();
243		}
244		;
245
246TagDefault	: kw_EXPLICIT kw_TAGS
247		| kw_IMPLICIT kw_TAGS
248		      { lex_error_message("implicit tagging is not supported"); }
249		| kw_AUTOMATIC kw_TAGS
250		      { lex_error_message("automatic tagging is not supported"); }
251		| /* empty */
252		;
253
254ExtensionDefault: kw_EXTENSIBILITY kw_IMPLIED
255		      { lex_error_message("no extensibility options supported"); }
256		| /* empty */
257		;
258
259ModuleBody	: Exports Imports AssignmentList
260		| /* empty */
261		;
262
263Imports		: kw_IMPORTS SymbolsImported ';'
264		| /* empty */
265		;
266
267SymbolsImported	: SymbolsFromModuleList
268		| /* empty */
269		;
270
271SymbolsFromModuleList: SymbolsFromModule
272		| SymbolsFromModuleList SymbolsFromModule
273		;
274
275SymbolsFromModule: referencenames kw_FROM IDENTIFIER objid_opt
276		{
277		    struct string_list *sl;
278		    for(sl = $1; sl != NULL; sl = sl->next) {
279			Symbol *s = addsym(sl->string);
280			s->stype = Stype;
281			gen_template_import(s);
282		    }
283		    add_import($3);
284		}
285		;
286
287Exports		: kw_EXPORTS referencenames ';'
288		{
289		    struct string_list *sl;
290		    for(sl = $2; sl != NULL; sl = sl->next)
291			add_export(sl->string);
292		}
293		| kw_EXPORTS kw_ALL
294		| /* empty */
295		;
296
297AssignmentList	: Assignment
298		| Assignment AssignmentList
299		;
300
301Assignment	: TypeAssignment
302		| ValueAssignment
303		;
304
305referencenames	: IDENTIFIER ',' referencenames
306		{
307		    $$ = emalloc(sizeof(*$$));
308		    $$->string = $1;
309		    $$->next = $3;
310		}
311		| IDENTIFIER
312		{
313		    $$ = emalloc(sizeof(*$$));
314		    $$->string = $1;
315		    $$->next = NULL;
316		}
317		;
318
319TypeAssignment	: IDENTIFIER EEQUAL Type
320		{
321		    Symbol *s = addsym ($1);
322		    s->stype = Stype;
323		    s->type = $3;
324		    fix_labels(s);
325		    generate_type (s);
326		}
327		;
328
329Type		: BuiltinType
330		| ReferencedType
331		| ConstrainedType
332		;
333
334BuiltinType	: BitStringType
335		| BooleanType
336		| CharacterStringType
337		| ChoiceType
338		| EnumeratedType
339		| IntegerType
340		| NullType
341		| ObjectIdentifierType
342		| OctetStringType
343		| SequenceType
344		| SequenceOfType
345		| SetType
346		| SetOfType
347		| TaggedType
348		;
349
350BooleanType	: kw_BOOLEAN
351		{
352			$$ = new_tag(ASN1_C_UNIV, UT_Boolean,
353				     TE_EXPLICIT, new_type(TBoolean));
354		}
355		;
356
357range		: '(' Value RANGE Value ')'
358		{
359		    if($2->type != integervalue)
360			lex_error_message("Non-integer used in first part of range");
361		    if($2->type != integervalue)
362			lex_error_message("Non-integer in second part of range");
363		    $$ = ecalloc(1, sizeof(*$$));
364		    $$->min = $2->u.integervalue;
365		    $$->max = $4->u.integervalue;
366		}
367		| '(' Value RANGE kw_MAX ')'
368		{
369		    if($2->type != integervalue)
370			lex_error_message("Non-integer in first part of range");
371		    $$ = ecalloc(1, sizeof(*$$));
372		    $$->min = $2->u.integervalue;
373		    $$->max = $2->u.integervalue - 1;
374		}
375		| '(' kw_MIN RANGE Value ')'
376		{
377		    if($4->type != integervalue)
378			lex_error_message("Non-integer in second part of range");
379		    $$ = ecalloc(1, sizeof(*$$));
380		    $$->min = $4->u.integervalue + 2;
381		    $$->max = $4->u.integervalue;
382		}
383		| '(' Value ')'
384		{
385		    if($2->type != integervalue)
386			lex_error_message("Non-integer used in limit");
387		    $$ = ecalloc(1, sizeof(*$$));
388		    $$->min = $2->u.integervalue;
389		    $$->max = $2->u.integervalue;
390		}
391		;
392
393
394IntegerType	: kw_INTEGER
395		{
396			$$ = new_tag(ASN1_C_UNIV, UT_Integer,
397				     TE_EXPLICIT, new_type(TInteger));
398		}
399		| kw_INTEGER range
400		{
401			$$ = new_type(TInteger);
402			$$->range = $2;
403			$$ = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, $$);
404		}
405		| kw_INTEGER '{' NamedNumberList '}'
406		{
407		  $$ = new_type(TInteger);
408		  $$->members = $3;
409		  $$ = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, $$);
410		}
411		;
412
413NamedNumberList	: NamedNumber
414		{
415			$$ = emalloc(sizeof(*$$));
416			ASN1_TAILQ_INIT($$);
417			ASN1_TAILQ_INSERT_HEAD($$, $1, members);
418		}
419		| NamedNumberList ',' NamedNumber
420		{
421			ASN1_TAILQ_INSERT_TAIL($1, $3, members);
422			$$ = $1;
423		}
424		| NamedNumberList ',' ELLIPSIS
425			{ $$ = $1; } /* XXX used for Enumerations */
426		;
427
428NamedNumber	: IDENTIFIER '(' SignedNumber ')'
429		{
430			$$ = emalloc(sizeof(*$$));
431			$$->name = $1;
432			$$->gen_name = estrdup($1);
433			output_name ($$->gen_name);
434			$$->val = $3;
435			$$->optional = 0;
436			$$->ellipsis = 0;
437			$$->type = NULL;
438		}
439		;
440
441EnumeratedType	: kw_ENUMERATED '{' Enumerations '}'
442		{
443		  $$ = new_type(TInteger);
444		  $$->members = $3;
445		  $$ = new_tag(ASN1_C_UNIV, UT_Enumerated, TE_EXPLICIT, $$);
446		}
447		;
448
449Enumerations	: NamedNumberList /* XXX */
450		;
451
452BitStringType	: kw_BIT kw_STRING
453		{
454		  $$ = new_type(TBitString);
455		  $$->members = emalloc(sizeof(*$$->members));
456		  ASN1_TAILQ_INIT($$->members);
457		  $$ = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, $$);
458		}
459		| kw_BIT kw_STRING '{' NamedBitList '}'
460		{
461		  $$ = new_type(TBitString);
462		  $$->members = $4;
463		  $$ = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, $$);
464		}
465		;
466
467ObjectIdentifierType: kw_OBJECT kw_IDENTIFIER
468		{
469			$$ = new_tag(ASN1_C_UNIV, UT_OID,
470				     TE_EXPLICIT, new_type(TOID));
471		}
472		;
473OctetStringType	: kw_OCTET kw_STRING size
474		{
475		    Type *t = new_type(TOctetString);
476		    t->range = $3;
477		    $$ = new_tag(ASN1_C_UNIV, UT_OctetString,
478				 TE_EXPLICIT, t);
479		}
480		;
481
482NullType	: kw_NULL
483		{
484			$$ = new_tag(ASN1_C_UNIV, UT_Null,
485				     TE_EXPLICIT, new_type(TNull));
486		}
487		;
488
489size		:
490		{ $$ = NULL; }
491		| kw_SIZE range
492		{ $$ = $2; }
493		;
494
495
496SequenceType	: kw_SEQUENCE '{' /* ComponentTypeLists */ ComponentTypeList '}'
497		{
498		  $$ = new_type(TSequence);
499		  $$->members = $3;
500		  $$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
501		}
502		| kw_SEQUENCE '{' '}'
503		{
504		  $$ = new_type(TSequence);
505		  $$->members = NULL;
506		  $$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
507		}
508		;
509
510SequenceOfType	: kw_SEQUENCE size kw_OF Type
511		{
512		  $$ = new_type(TSequenceOf);
513		  $$->range = $2;
514		  $$->subtype = $4;
515		  $$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
516		}
517		;
518
519SetType		: kw_SET '{' /* ComponentTypeLists */ ComponentTypeList '}'
520		{
521		  $$ = new_type(TSet);
522		  $$->members = $3;
523		  $$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
524		}
525		| kw_SET '{' '}'
526		{
527		  $$ = new_type(TSet);
528		  $$->members = NULL;
529		  $$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
530		}
531		;
532
533SetOfType	: kw_SET kw_OF Type
534		{
535		  $$ = new_type(TSetOf);
536		  $$->subtype = $3;
537		  $$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
538		}
539		;
540
541ChoiceType	: kw_CHOICE '{' /* AlternativeTypeLists */ ComponentTypeList '}'
542		{
543		  $$ = new_type(TChoice);
544		  $$->members = $3;
545		}
546		;
547
548ReferencedType	: DefinedType
549		| UsefulType
550		;
551
552DefinedType	: IDENTIFIER
553		{
554		  Symbol *s = addsym($1);
555		  $$ = new_type(TType);
556		  if(s->stype != Stype && s->stype != SUndefined)
557		    lex_error_message ("%s is not a type\n", $1);
558		  else
559		    $$->symbol = s;
560		}
561		;
562
563UsefulType	: kw_GeneralizedTime
564		{
565			$$ = new_tag(ASN1_C_UNIV, UT_GeneralizedTime,
566				     TE_EXPLICIT, new_type(TGeneralizedTime));
567		}
568		| kw_UTCTime
569		{
570			$$ = new_tag(ASN1_C_UNIV, UT_UTCTime,
571				     TE_EXPLICIT, new_type(TUTCTime));
572		}
573		;
574
575ConstrainedType	: Type Constraint
576		{
577		    /* if (Constraint.type == contentConstrant) {
578		       assert(Constraint.u.constraint.type == octetstring|bitstring-w/o-NamedBitList); // remember to check type reference too
579		       if (Constraint.u.constraint.type) {
580		         assert((Constraint.u.constraint.type.length % 8) == 0);
581		       }
582		      }
583		      if (Constraint.u.constraint.encoding) {
584		        type == der-oid|ber-oid
585		      }
586		    */
587		}
588		;
589
590
591Constraint	: '(' ConstraintSpec ')'
592		{
593		    $$ = $2;
594		}
595		;
596
597ConstraintSpec	: GeneralConstraint
598		;
599
600GeneralConstraint: ContentsConstraint
601		| UserDefinedConstraint
602		;
603
604ContentsConstraint: kw_CONTAINING Type
605		{
606		    $$ = new_constraint_spec(CT_CONTENTS);
607		    $$->u.content.type = $2;
608		    $$->u.content.encoding = NULL;
609		}
610		| kw_ENCODED kw_BY Value
611		{
612		    if ($3->type != objectidentifiervalue)
613			lex_error_message("Non-OID used in ENCODED BY constraint");
614		    $$ = new_constraint_spec(CT_CONTENTS);
615		    $$->u.content.type = NULL;
616		    $$->u.content.encoding = $3;
617		}
618		| kw_CONTAINING Type kw_ENCODED kw_BY Value
619		{
620		    if ($5->type != objectidentifiervalue)
621			lex_error_message("Non-OID used in ENCODED BY constraint");
622		    $$ = new_constraint_spec(CT_CONTENTS);
623		    $$->u.content.type = $2;
624		    $$->u.content.encoding = $5;
625		}
626		;
627
628UserDefinedConstraint: kw_CONSTRAINED kw_BY '{' '}'
629		{
630		    $$ = new_constraint_spec(CT_USER);
631		}
632		;
633
634TaggedType	: Tag tagenv Type
635		{
636			$$ = new_type(TTag);
637			$$->tag = $1;
638			$$->tag.tagenv = $2;
639			if($3->type == TTag && $2 == TE_IMPLICIT) {
640				$$->subtype = $3->subtype;
641				free($3);
642			} else
643				$$->subtype = $3;
644		}
645		;
646
647Tag		: '[' Class NUMBER ']'
648		{
649			$$.tagclass = $2;
650			$$.tagvalue = $3;
651			$$.tagenv = TE_EXPLICIT;
652		}
653		;
654
655Class		: /* */
656		{
657			$$ = ASN1_C_CONTEXT;
658		}
659		| kw_UNIVERSAL
660		{
661			$$ = ASN1_C_UNIV;
662		}
663		| kw_APPLICATION
664		{
665			$$ = ASN1_C_APPL;
666		}
667		| kw_PRIVATE
668		{
669			$$ = ASN1_C_PRIVATE;
670		}
671		;
672
673tagenv		: /* */
674		{
675			$$ = TE_EXPLICIT;
676		}
677		| kw_EXPLICIT
678		{
679			$$ = TE_EXPLICIT;
680		}
681		| kw_IMPLICIT
682		{
683			$$ = TE_IMPLICIT;
684		}
685		;
686
687
688ValueAssignment	: IDENTIFIER Type EEQUAL Value
689		{
690			Symbol *s;
691			s = addsym ($1);
692
693			s->stype = SValue;
694			s->value = $4;
695			generate_constant (s);
696		}
697		;
698
699CharacterStringType: RestrictedCharactedStringType
700		;
701
702RestrictedCharactedStringType: kw_GeneralString
703		{
704			$$ = new_tag(ASN1_C_UNIV, UT_GeneralString,
705				     TE_EXPLICIT, new_type(TGeneralString));
706		}
707		| kw_TeletexString
708		{
709			$$ = new_tag(ASN1_C_UNIV, UT_TeletexString,
710				     TE_EXPLICIT, new_type(TTeletexString));
711		}
712		| kw_UTF8String
713		{
714			$$ = new_tag(ASN1_C_UNIV, UT_UTF8String,
715				     TE_EXPLICIT, new_type(TUTF8String));
716		}
717		| kw_PrintableString
718		{
719			$$ = new_tag(ASN1_C_UNIV, UT_PrintableString,
720				     TE_EXPLICIT, new_type(TPrintableString));
721		}
722		| kw_VisibleString
723		{
724			$$ = new_tag(ASN1_C_UNIV, UT_VisibleString,
725				     TE_EXPLICIT, new_type(TVisibleString));
726		}
727		| kw_IA5String
728		{
729			$$ = new_tag(ASN1_C_UNIV, UT_IA5String,
730				     TE_EXPLICIT, new_type(TIA5String));
731		}
732		| kw_BMPString
733		{
734			$$ = new_tag(ASN1_C_UNIV, UT_BMPString,
735				     TE_EXPLICIT, new_type(TBMPString));
736		}
737		| kw_UniversalString
738		{
739			$$ = new_tag(ASN1_C_UNIV, UT_UniversalString,
740				     TE_EXPLICIT, new_type(TUniversalString));
741		}
742
743		;
744
745ComponentTypeList: ComponentType
746		{
747			$$ = emalloc(sizeof(*$$));
748			ASN1_TAILQ_INIT($$);
749			ASN1_TAILQ_INSERT_HEAD($$, $1, members);
750		}
751		| ComponentTypeList ',' ComponentType
752		{
753			ASN1_TAILQ_INSERT_TAIL($1, $3, members);
754			$$ = $1;
755		}
756		| ComponentTypeList ',' ELLIPSIS
757		{
758		        struct member *m = ecalloc(1, sizeof(*m));
759			m->name = estrdup("...");
760			m->gen_name = estrdup("asn1_ellipsis");
761			m->ellipsis = 1;
762			ASN1_TAILQ_INSERT_TAIL($1, m, members);
763			$$ = $1;
764		}
765		;
766
767NamedType	: IDENTIFIER Type
768		{
769		  $$ = emalloc(sizeof(*$$));
770		  $$->name = $1;
771		  $$->gen_name = estrdup($1);
772		  output_name ($$->gen_name);
773		  $$->type = $2;
774		  $$->ellipsis = 0;
775		}
776		;
777
778ComponentType	: NamedType
779		{
780			$$ = $1;
781			$$->optional = 0;
782			$$->defval = NULL;
783		}
784		| NamedType kw_OPTIONAL
785		{
786			$$ = $1;
787			$$->optional = 1;
788			$$->defval = NULL;
789		}
790		| NamedType kw_DEFAULT Value
791		{
792			$$ = $1;
793			$$->optional = 0;
794			$$->defval = $3;
795		}
796		;
797
798NamedBitList	: NamedBit
799		{
800			$$ = emalloc(sizeof(*$$));
801			ASN1_TAILQ_INIT($$);
802			ASN1_TAILQ_INSERT_HEAD($$, $1, members);
803		}
804		| NamedBitList ',' NamedBit
805		{
806			ASN1_TAILQ_INSERT_TAIL($1, $3, members);
807			$$ = $1;
808		}
809		;
810
811NamedBit	: IDENTIFIER '(' NUMBER ')'
812		{
813		  $$ = emalloc(sizeof(*$$));
814		  $$->name = $1;
815		  $$->gen_name = estrdup($1);
816		  output_name ($$->gen_name);
817		  $$->val = $3;
818		  $$->optional = 0;
819		  $$->ellipsis = 0;
820		  $$->type = NULL;
821		}
822		;
823
824objid_opt	: objid
825		| /* empty */ { $$ = NULL; }
826		;
827
828objid		: '{' objid_list '}'
829		{
830			$$ = $2;
831		}
832		;
833
834objid_list	:  /* empty */
835		{
836			$$ = NULL;
837		}
838		| objid_element objid_list
839		{
840		        if ($2) {
841				$$ = $2;
842				add_oid_to_tail($2, $1);
843			} else {
844				$$ = $1;
845			}
846		}
847		;
848
849objid_element	: IDENTIFIER '(' NUMBER ')'
850		{
851			$$ = new_objid($1, $3);
852		}
853		| IDENTIFIER
854		{
855		    Symbol *s = addsym($1);
856		    if(s->stype != SValue ||
857		       s->value->type != objectidentifiervalue) {
858			lex_error_message("%s is not an object identifier\n",
859				      s->name);
860			exit(1);
861		    }
862		    $$ = s->value->u.objectidentifiervalue;
863		}
864		| NUMBER
865		{
866		    $$ = new_objid(NULL, $1);
867		}
868		;
869
870Value		: BuiltinValue
871		| ReferencedValue
872		;
873
874BuiltinValue	: BooleanValue
875		| CharacterStringValue
876		| IntegerValue
877		| ObjectIdentifierValue
878		| NullValue
879		;
880
881ReferencedValue	: DefinedValue
882		;
883
884DefinedValue	: Valuereference
885		;
886
887Valuereference	: IDENTIFIER
888		{
889			Symbol *s = addsym($1);
890			if(s->stype != SValue)
891				lex_error_message ("%s is not a value\n",
892						s->name);
893			else
894				$$ = s->value;
895		}
896		;
897
898CharacterStringValue: STRING
899		{
900			$$ = emalloc(sizeof(*$$));
901			$$->type = stringvalue;
902			$$->u.stringvalue = $1;
903		}
904		;
905
906BooleanValue	: kw_TRUE
907		{
908			$$ = emalloc(sizeof(*$$));
909			$$->type = booleanvalue;
910			$$->u.booleanvalue = 0;
911		}
912		| kw_FALSE
913		{
914			$$ = emalloc(sizeof(*$$));
915			$$->type = booleanvalue;
916			$$->u.booleanvalue = 0;
917		}
918		;
919
920IntegerValue	: SignedNumber
921		{
922			$$ = emalloc(sizeof(*$$));
923			$$->type = integervalue;
924			$$->u.integervalue = $1;
925		}
926		;
927
928SignedNumber	: NUMBER
929		;
930
931NullValue	: kw_NULL
932		{
933		}
934		;
935
936ObjectIdentifierValue: objid
937		{
938			$$ = emalloc(sizeof(*$$));
939			$$->type = objectidentifiervalue;
940			$$->u.objectidentifiervalue = $1;
941		}
942		;
943
944%%
945
946void
947yyerror (const char *s)
948{
949     lex_error_message ("%s\n", s);
950}
951
952static Type *
953new_tag(int tagclass, int tagvalue, int tagenv, Type *oldtype)
954{
955    Type *t;
956    if(oldtype->type == TTag && oldtype->tag.tagenv == TE_IMPLICIT) {
957	t = oldtype;
958	oldtype = oldtype->subtype; /* XXX */
959    } else
960	t = new_type (TTag);
961
962    t->tag.tagclass = tagclass;
963    t->tag.tagvalue = tagvalue;
964    t->tag.tagenv = tagenv;
965    t->subtype = oldtype;
966    return t;
967}
968
969static struct objid *
970new_objid(const char *label, int value)
971{
972    struct objid *s;
973    s = emalloc(sizeof(*s));
974    s->label = label;
975    s->value = value;
976    s->next = NULL;
977    return s;
978}
979
980static void
981add_oid_to_tail(struct objid *head, struct objid *tail)
982{
983    struct objid *o;
984    o = head;
985    while (o->next)
986	o = o->next;
987    o->next = tail;
988}
989
990static Type *
991new_type (Typetype tt)
992{
993    Type *t = ecalloc(1, sizeof(*t));
994    t->type = tt;
995    return t;
996}
997
998static struct constraint_spec *
999new_constraint_spec(enum ctype ct)
1000{
1001    struct constraint_spec *c = ecalloc(1, sizeof(*c));
1002    c->ctype = ct;
1003    return c;
1004}
1005
1006static void fix_labels2(Type *t, const char *prefix);
1007static void fix_labels1(struct memhead *members, const char *prefix)
1008{
1009    Member *m;
1010
1011    if(members == NULL)
1012	return;
1013    ASN1_TAILQ_FOREACH(m, members, members) {
1014	if (asprintf(&m->label, "%s_%s", prefix, m->gen_name) < 0)
1015	    errx(1, "malloc");
1016	if (m->label == NULL)
1017	    errx(1, "malloc");
1018	if(m->type != NULL)
1019	    fix_labels2(m->type, m->label);
1020    }
1021}
1022
1023static void fix_labels2(Type *t, const char *prefix)
1024{
1025    for(; t; t = t->subtype)
1026	fix_labels1(t->members, prefix);
1027}
1028
1029static void
1030fix_labels(Symbol *s)
1031{
1032    char *p = NULL;
1033    if (asprintf(&p, "choice_%s", s->gen_name) < 0 || p == NULL)
1034	errx(1, "malloc");
1035    fix_labels2(s->type, p);
1036    free(p);
1037}
1038