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