root/source4/heimdal/lib/asn1/parse.y

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. yyerror
  2. new_tag
  3. new_objid
  4. add_oid_to_tail
  5. new_type
  6. new_constraint_spec
  7. fix_labels1
  8. fix_labels2
  9. fix_labels

   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 #ifdef HAVE_CONFIG_H
  38 #include <config.h>
  39 #endif
  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_UTF8String
 691                 {
 692                         $$ = new_tag(ASN1_C_UNIV, UT_UTF8String,
 693                                      TE_EXPLICIT, new_type(TUTF8String));
 694                 }
 695                 | kw_PrintableString
 696                 {
 697                         $$ = new_tag(ASN1_C_UNIV, UT_PrintableString,
 698                                      TE_EXPLICIT, new_type(TPrintableString));
 699                 }
 700                 | kw_VisibleString
 701                 {
 702                         $$ = new_tag(ASN1_C_UNIV, UT_VisibleString,
 703                                      TE_EXPLICIT, new_type(TVisibleString));
 704                 }
 705                 | kw_IA5String
 706                 {
 707                         $$ = new_tag(ASN1_C_UNIV, UT_IA5String,
 708                                      TE_EXPLICIT, new_type(TIA5String));
 709                 }
 710                 | kw_BMPString
 711                 {
 712                         $$ = new_tag(ASN1_C_UNIV, UT_BMPString,
 713                                      TE_EXPLICIT, new_type(TBMPString));
 714                 }
 715                 | kw_UniversalString
 716                 {
 717                         $$ = new_tag(ASN1_C_UNIV, UT_UniversalString,
 718                                      TE_EXPLICIT, new_type(TUniversalString));
 719                 }
 720 
 721                 ;
 722 
 723 ComponentTypeList: ComponentType
 724                 {
 725                         $$ = emalloc(sizeof(*$$));
 726                         ASN1_TAILQ_INIT($$);
 727                         ASN1_TAILQ_INSERT_HEAD($$, $1, members);
 728                 }
 729                 | ComponentTypeList ',' ComponentType
 730                 {
 731                         ASN1_TAILQ_INSERT_TAIL($1, $3, members);
 732                         $$ = $1;
 733                 }
 734                 | ComponentTypeList ',' ELLIPSIS
 735                 {
 736                         struct member *m = ecalloc(1, sizeof(*m));
 737                         m->name = estrdup("...");
 738                         m->gen_name = estrdup("asn1_ellipsis");
 739                         m->ellipsis = 1;
 740                         ASN1_TAILQ_INSERT_TAIL($1, m, members);
 741                         $$ = $1;
 742                 }
 743                 ;
 744 
 745 NamedType       : IDENTIFIER Type
 746                 {
 747                   $$ = emalloc(sizeof(*$$));
 748                   $$->name = $1;
 749                   $$->gen_name = estrdup($1);
 750                   output_name ($$->gen_name);
 751                   $$->type = $2;
 752                   $$->ellipsis = 0;
 753                 }
 754                 ;
 755 
 756 ComponentType   : NamedType
 757                 {
 758                         $$ = $1;
 759                         $$->optional = 0;
 760                         $$->defval = NULL;
 761                 }
 762                 | NamedType kw_OPTIONAL
 763                 {
 764                         $$ = $1;
 765                         $$->optional = 1;
 766                         $$->defval = NULL;
 767                 }
 768                 | NamedType kw_DEFAULT Value
 769                 {
 770                         $$ = $1;
 771                         $$->optional = 0;
 772                         $$->defval = $3;
 773                 }
 774                 ;
 775 
 776 NamedBitList    : NamedBit
 777                 {
 778                         $$ = emalloc(sizeof(*$$));
 779                         ASN1_TAILQ_INIT($$);
 780                         ASN1_TAILQ_INSERT_HEAD($$, $1, members);
 781                 }
 782                 | NamedBitList ',' NamedBit
 783                 {
 784                         ASN1_TAILQ_INSERT_TAIL($1, $3, members);
 785                         $$ = $1;
 786                 }
 787                 ;
 788 
 789 NamedBit        : IDENTIFIER '(' NUMBER ')'
 790                 {
 791                   $$ = emalloc(sizeof(*$$));
 792                   $$->name = $1;
 793                   $$->gen_name = estrdup($1);
 794                   output_name ($$->gen_name);
 795                   $$->val = $3;
 796                   $$->optional = 0;
 797                   $$->ellipsis = 0;
 798                   $$->type = NULL;
 799                 }
 800                 ;
 801 
 802 objid_opt       : objid
 803                 | /* empty */ { $$ = NULL; }
 804                 ;
 805 
 806 objid           : '{' objid_list '}'
 807                 {
 808                         $$ = $2;
 809                 }
 810                 ;
 811 
 812 objid_list      :  /* empty */
 813                 {
 814                         $$ = NULL;
 815                 }
 816                 | objid_element objid_list
 817                 {
 818                         if ($2) {
 819                                 $$ = $2;
 820                                 add_oid_to_tail($2, $1);
 821                         } else {
 822                                 $$ = $1;
 823                         }
 824                 }
 825                 ;
 826 
 827 objid_element   : IDENTIFIER '(' NUMBER ')'
 828                 {
 829                         $$ = new_objid($1, $3);
 830                 }
 831                 | IDENTIFIER
 832                 {
 833                     Symbol *s = addsym($1);
 834                     if(s->stype != SValue ||
 835                        s->value->type != objectidentifiervalue) {
 836                         error_message("%s is not an object identifier\n",
 837                                       s->name);
 838                         exit(1);
 839                     }
 840                     $$ = s->value->u.objectidentifiervalue;
 841                 }
 842                 | NUMBER
 843                 {
 844                     $$ = new_objid(NULL, $1);
 845                 }
 846                 ;
 847 
 848 Value           : BuiltinValue
 849                 | ReferencedValue
 850                 ;
 851 
 852 BuiltinValue    : BooleanValue
 853                 | CharacterStringValue
 854                 | IntegerValue
 855                 | ObjectIdentifierValue
 856                 | NullValue
 857                 ;
 858 
 859 ReferencedValue : DefinedValue
 860                 ;
 861 
 862 DefinedValue    : Valuereference
 863                 ;
 864 
 865 Valuereference  : IDENTIFIER
 866                 {
 867                         Symbol *s = addsym($1);
 868                         if(s->stype != SValue)
 869                                 error_message ("%s is not a value\n",
 870                                                 s->name);
 871                         else
 872                                 $$ = s->value;
 873                 }
 874                 ;
 875 
 876 CharacterStringValue: STRING
 877                 {
 878                         $$ = emalloc(sizeof(*$$));
 879                         $$->type = stringvalue;
 880                         $$->u.stringvalue = $1;
 881                 }
 882                 ;
 883 
 884 BooleanValue    : kw_TRUE
 885                 {
 886                         $$ = emalloc(sizeof(*$$));
 887                         $$->type = booleanvalue;
 888                         $$->u.booleanvalue = 0;
 889                 }
 890                 | kw_FALSE
 891                 {
 892                         $$ = emalloc(sizeof(*$$));
 893                         $$->type = booleanvalue;
 894                         $$->u.booleanvalue = 0;
 895                 }
 896                 ;
 897 
 898 IntegerValue    : SignedNumber
 899                 {
 900                         $$ = emalloc(sizeof(*$$));
 901                         $$->type = integervalue;
 902                         $$->u.integervalue = $1;
 903                 }
 904                 ;
 905 
 906 SignedNumber    : NUMBER
 907                 ;
 908 
 909 NullValue       : kw_NULL
 910                 {
 911                 }
 912                 ;
 913 
 914 ObjectIdentifierValue: objid
 915                 {
 916                         $$ = emalloc(sizeof(*$$));
 917                         $$->type = objectidentifiervalue;
 918                         $$->u.objectidentifiervalue = $1;
 919                 }
 920                 ;
 921 
 922 %%
 923 
 924 void
 925 yyerror (const char *s)
     /* [<][>][^][v][top][bottom][index][help] */
 926 {
 927      error_message ("%s\n", s);
 928 }
 929 
 930 static Type *
 931 new_tag(int tagclass, int tagvalue, int tagenv, Type *oldtype)
     /* [<][>][^][v][top][bottom][index][help] */
 932 {
 933     Type *t;
 934     if(oldtype->type == TTag && oldtype->tag.tagenv == TE_IMPLICIT) {
 935         t = oldtype;
 936         oldtype = oldtype->subtype; /* XXX */
 937     } else
 938         t = new_type (TTag);
 939 
 940     t->tag.tagclass = tagclass;
 941     t->tag.tagvalue = tagvalue;
 942     t->tag.tagenv = tagenv;
 943     t->subtype = oldtype;
 944     return t;
 945 }
 946 
 947 static struct objid *
 948 new_objid(const char *label, int value)
     /* [<][>][^][v][top][bottom][index][help] */
 949 {
 950     struct objid *s;
 951     s = emalloc(sizeof(*s));
 952     s->label = label;
 953     s->value = value;
 954     s->next = NULL;
 955     return s;
 956 }
 957 
 958 static void
 959 add_oid_to_tail(struct objid *head, struct objid *tail)
     /* [<][>][^][v][top][bottom][index][help] */
 960 {
 961     struct objid *o;
 962     o = head;
 963     while (o->next)
 964         o = o->next;
 965     o->next = tail;
 966 }
 967 
 968 static Type *
 969 new_type (Typetype tt)
     /* [<][>][^][v][top][bottom][index][help] */
 970 {
 971     Type *t = ecalloc(1, sizeof(*t));
 972     t->type = tt;
 973     return t;
 974 }
 975 
 976 static struct constraint_spec *
 977 new_constraint_spec(enum ctype ct)
     /* [<][>][^][v][top][bottom][index][help] */
 978 {
 979     struct constraint_spec *c = ecalloc(1, sizeof(*c));
 980     c->ctype = ct;
 981     return c;
 982 }
 983 
 984 static void fix_labels2(Type *t, const char *prefix);
 985 static void fix_labels1(struct memhead *members, const char *prefix)
     /* [<][>][^][v][top][bottom][index][help] */
 986 {
 987     Member *m;
 988 
 989     if(members == NULL)
 990         return;
 991     ASN1_TAILQ_FOREACH(m, members, members) {
 992         asprintf(&m->label, "%s_%s", prefix, m->gen_name);
 993         if (m->label == NULL)
 994             errx(1, "malloc");
 995         if(m->type != NULL)
 996             fix_labels2(m->type, m->label);
 997     }
 998 }
 999 
1000 static void fix_labels2(Type *t, const char *prefix)
     /* [<][>][^][v][top][bottom][index][help] */
1001 {
1002     for(; t; t = t->subtype)
1003         fix_labels1(t->members, prefix);
1004 }
1005 
1006 static void
1007 fix_labels(Symbol *s)
     /* [<][>][^][v][top][bottom][index][help] */
1008 {
1009     char *p;
1010     asprintf(&p, "choice_%s", s->gen_name);
1011     if (p == NULL)
1012         errx(1, "malloc");
1013     fix_labels2(s->type, p);
1014     free(p);
1015 }

/* [<][>][^][v][top][bottom][index][help] */