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