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