diff options
Diffstat (limited to 'source4/heimdal/lib/asn1/asn1parse.y')
-rw-r--r-- | source4/heimdal/lib/asn1/asn1parse.y | 1015 |
1 files changed, 1015 insertions, 0 deletions
diff --git a/source4/heimdal/lib/asn1/asn1parse.y b/source4/heimdal/lib/asn1/asn1parse.y new file mode 100644 index 0000000000..7975fe4f6b --- /dev/null +++ b/source4/heimdal/lib/asn1/asn1parse.y @@ -0,0 +1,1015 @@ +/* + * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id$ */ + +%{ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "symbol.h" +#include "lex.h" +#include "gen_locl.h" +#include "der.h" + +RCSID("$Id$"); + +static Type *new_type (Typetype t); +static struct constraint_spec *new_constraint_spec(enum ctype); +static Type *new_tag(int tagclass, int tagvalue, int tagenv, Type *oldtype); +void yyerror (const char *); +static struct objid *new_objid(const char *label, int value); +static void add_oid_to_tail(struct objid *, struct objid *); +static void fix_labels(Symbol *s); + +struct string_list { + char *string; + struct string_list *next; +}; + +%} + +%union { + int constant; + struct value *value; + struct range *range; + char *name; + Type *type; + Member *member; + struct objid *objid; + char *defval; + struct string_list *sl; + struct tagtype tag; + struct memhead *members; + struct constraint_spec *constraint_spec; +} + +%token kw_ABSENT +%token kw_ABSTRACT_SYNTAX +%token kw_ALL +%token kw_APPLICATION +%token kw_AUTOMATIC +%token kw_BEGIN +%token kw_BIT +%token kw_BMPString +%token kw_BOOLEAN +%token kw_BY +%token kw_CHARACTER +%token kw_CHOICE +%token kw_CLASS +%token kw_COMPONENT +%token kw_COMPONENTS +%token kw_CONSTRAINED +%token kw_CONTAINING +%token kw_DEFAULT +%token kw_DEFINITIONS +%token kw_EMBEDDED +%token kw_ENCODED +%token kw_END +%token kw_ENUMERATED +%token kw_EXCEPT +%token kw_EXPLICIT +%token kw_EXPORTS +%token kw_EXTENSIBILITY +%token kw_EXTERNAL +%token kw_FALSE +%token kw_FROM +%token kw_GeneralString +%token kw_GeneralizedTime +%token kw_GraphicString +%token kw_IA5String +%token kw_IDENTIFIER +%token kw_IMPLICIT +%token kw_IMPLIED +%token kw_IMPORTS +%token kw_INCLUDES +%token kw_INSTANCE +%token kw_INTEGER +%token kw_INTERSECTION +%token kw_ISO646String +%token kw_MAX +%token kw_MIN +%token kw_MINUS_INFINITY +%token kw_NULL +%token kw_NumericString +%token kw_OBJECT +%token kw_OCTET +%token kw_OF +%token kw_OPTIONAL +%token kw_ObjectDescriptor +%token kw_PATTERN +%token kw_PDV +%token kw_PLUS_INFINITY +%token kw_PRESENT +%token kw_PRIVATE +%token kw_PrintableString +%token kw_REAL +%token kw_RELATIVE_OID +%token kw_SEQUENCE +%token kw_SET +%token kw_SIZE +%token kw_STRING +%token kw_SYNTAX +%token kw_T61String +%token kw_TAGS +%token kw_TRUE +%token kw_TYPE_IDENTIFIER +%token kw_TeletexString +%token kw_UNION +%token kw_UNIQUE +%token kw_UNIVERSAL +%token kw_UTCTime +%token kw_UTF8String +%token kw_UniversalString +%token kw_VideotexString +%token kw_VisibleString +%token kw_WITH + +%token RANGE +%token EEQUAL +%token ELLIPSIS + +%token <name> IDENTIFIER referencename +%token <name> STRING + +%token <constant> NUMBER +%type <constant> SignedNumber +%type <constant> Class tagenv + +%type <value> Value +%type <value> BuiltinValue +%type <value> IntegerValue +%type <value> BooleanValue +%type <value> ObjectIdentifierValue +%type <value> CharacterStringValue +%type <value> NullValue +%type <value> DefinedValue +%type <value> ReferencedValue +%type <value> Valuereference + +%type <type> Type +%type <type> BuiltinType +%type <type> BitStringType +%type <type> BooleanType +%type <type> ChoiceType +%type <type> ConstrainedType +%type <type> EnumeratedType +%type <type> IntegerType +%type <type> NullType +%type <type> OctetStringType +%type <type> SequenceType +%type <type> SequenceOfType +%type <type> SetType +%type <type> SetOfType +%type <type> TaggedType +%type <type> ReferencedType +%type <type> DefinedType +%type <type> UsefulType +%type <type> ObjectIdentifierType +%type <type> CharacterStringType +%type <type> RestrictedCharactedStringType + +%type <tag> Tag + +%type <member> ComponentType +%type <member> NamedBit +%type <member> NamedNumber +%type <member> NamedType +%type <members> ComponentTypeList +%type <members> Enumerations +%type <members> NamedBitList +%type <members> NamedNumberList + +%type <objid> objid objid_list objid_element objid_opt +%type <range> range size + +%type <sl> referencenames + +%type <constraint_spec> Constraint +%type <constraint_spec> ConstraintSpec +%type <constraint_spec> GeneralConstraint +%type <constraint_spec> ContentsConstraint +%type <constraint_spec> UserDefinedConstraint + + + +%start ModuleDefinition + +%% + +ModuleDefinition: IDENTIFIER objid_opt kw_DEFINITIONS TagDefault ExtensionDefault + EEQUAL kw_BEGIN ModuleBody kw_END + { + checkundefined(); + } + ; + +TagDefault : kw_EXPLICIT kw_TAGS + | kw_IMPLICIT kw_TAGS + { error_message("implicit tagging is not supported"); } + | kw_AUTOMATIC kw_TAGS + { error_message("automatic tagging is not supported"); } + | /* empty */ + ; + +ExtensionDefault: kw_EXTENSIBILITY kw_IMPLIED + { error_message("no extensibility options supported"); } + | /* empty */ + ; + +ModuleBody : /* Exports */ Imports AssignmentList + | /* empty */ + ; + +Imports : kw_IMPORTS SymbolsImported ';' + | /* empty */ + ; + +SymbolsImported : SymbolsFromModuleList + | /* empty */ + ; + +SymbolsFromModuleList: SymbolsFromModule + | SymbolsFromModuleList SymbolsFromModule + ; + +SymbolsFromModule: referencenames kw_FROM IDENTIFIER objid_opt + { + struct string_list *sl; + for(sl = $1; sl != NULL; sl = sl->next) { + Symbol *s = addsym(sl->string); + s->stype = Stype; + } + add_import($3); + } + ; + +AssignmentList : Assignment + | Assignment AssignmentList + ; + +Assignment : TypeAssignment + | ValueAssignment + ; + +referencenames : IDENTIFIER ',' referencenames + { + $$ = emalloc(sizeof(*$$)); + $$->string = $1; + $$->next = $3; + } + | IDENTIFIER + { + $$ = emalloc(sizeof(*$$)); + $$->string = $1; + $$->next = NULL; + } + ; + +TypeAssignment : IDENTIFIER EEQUAL Type + { + Symbol *s = addsym ($1); + s->stype = Stype; + s->type = $3; + fix_labels(s); + generate_type (s); + } + ; + +Type : BuiltinType + | ReferencedType + | ConstrainedType + ; + +BuiltinType : BitStringType + | BooleanType + | CharacterStringType + | ChoiceType + | EnumeratedType + | IntegerType + | NullType + | ObjectIdentifierType + | OctetStringType + | SequenceType + | SequenceOfType + | SetType + | SetOfType + | TaggedType + ; + +BooleanType : kw_BOOLEAN + { + $$ = new_tag(ASN1_C_UNIV, UT_Boolean, + TE_EXPLICIT, new_type(TBoolean)); + } + ; + +range : '(' Value RANGE Value ')' + { + if($2->type != integervalue) + error_message("Non-integer used in first part of range"); + if($2->type != integervalue) + error_message("Non-integer in second part of range"); + $$ = ecalloc(1, sizeof(*$$)); + $$->min = $2->u.integervalue; + $$->max = $4->u.integervalue; + } + | '(' Value RANGE kw_MAX ')' + { + if($2->type != integervalue) + error_message("Non-integer in first part of range"); + $$ = ecalloc(1, sizeof(*$$)); + $$->min = $2->u.integervalue; + $$->max = $2->u.integervalue - 1; + } + | '(' kw_MIN RANGE Value ')' + { + if($4->type != integervalue) + error_message("Non-integer in second part of range"); + $$ = ecalloc(1, sizeof(*$$)); + $$->min = $4->u.integervalue + 2; + $$->max = $4->u.integervalue; + } + | '(' Value ')' + { + if($2->type != integervalue) + error_message("Non-integer used in limit"); + $$ = ecalloc(1, sizeof(*$$)); + $$->min = $2->u.integervalue; + $$->max = $2->u.integervalue; + } + ; + + +IntegerType : kw_INTEGER + { + $$ = new_tag(ASN1_C_UNIV, UT_Integer, + TE_EXPLICIT, new_type(TInteger)); + } + | kw_INTEGER range + { + $$ = new_type(TInteger); + $$->range = $2; + $$ = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, $$); + } + | kw_INTEGER '{' NamedNumberList '}' + { + $$ = new_type(TInteger); + $$->members = $3; + $$ = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, $$); + } + ; + +NamedNumberList : NamedNumber + { + $$ = emalloc(sizeof(*$$)); + ASN1_TAILQ_INIT($$); + ASN1_TAILQ_INSERT_HEAD($$, $1, members); + } + | NamedNumberList ',' NamedNumber + { + ASN1_TAILQ_INSERT_TAIL($1, $3, members); + $$ = $1; + } + | NamedNumberList ',' ELLIPSIS + { $$ = $1; } /* XXX used for Enumerations */ + ; + +NamedNumber : IDENTIFIER '(' SignedNumber ')' + { + $$ = emalloc(sizeof(*$$)); + $$->name = $1; + $$->gen_name = estrdup($1); + output_name ($$->gen_name); + $$->val = $3; + $$->optional = 0; + $$->ellipsis = 0; + $$->type = NULL; + } + ; + +EnumeratedType : kw_ENUMERATED '{' Enumerations '}' + { + $$ = new_type(TInteger); + $$->members = $3; + $$ = new_tag(ASN1_C_UNIV, UT_Enumerated, TE_EXPLICIT, $$); + } + ; + +Enumerations : NamedNumberList /* XXX */ + ; + +BitStringType : kw_BIT kw_STRING + { + $$ = new_type(TBitString); + $$->members = emalloc(sizeof(*$$->members)); + ASN1_TAILQ_INIT($$->members); + $$ = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, $$); + } + | kw_BIT kw_STRING '{' NamedBitList '}' + { + $$ = new_type(TBitString); + $$->members = $4; + $$ = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, $$); + } + ; + +ObjectIdentifierType: kw_OBJECT kw_IDENTIFIER + { + $$ = new_tag(ASN1_C_UNIV, UT_OID, + TE_EXPLICIT, new_type(TOID)); + } + ; +OctetStringType : kw_OCTET kw_STRING size + { + Type *t = new_type(TOctetString); + t->range = $3; + $$ = new_tag(ASN1_C_UNIV, UT_OctetString, + TE_EXPLICIT, t); + } + ; + +NullType : kw_NULL + { + $$ = new_tag(ASN1_C_UNIV, UT_Null, + TE_EXPLICIT, new_type(TNull)); + } + ; + +size : + { $$ = NULL; } + | kw_SIZE range + { $$ = $2; } + ; + + +SequenceType : kw_SEQUENCE '{' /* ComponentTypeLists */ ComponentTypeList '}' + { + $$ = new_type(TSequence); + $$->members = $3; + $$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$); + } + | kw_SEQUENCE '{' '}' + { + $$ = new_type(TSequence); + $$->members = NULL; + $$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$); + } + ; + +SequenceOfType : kw_SEQUENCE size kw_OF Type + { + $$ = new_type(TSequenceOf); + $$->range = $2; + $$->subtype = $4; + $$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$); + } + ; + +SetType : kw_SET '{' /* ComponentTypeLists */ ComponentTypeList '}' + { + $$ = new_type(TSet); + $$->members = $3; + $$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$); + } + | kw_SET '{' '}' + { + $$ = new_type(TSet); + $$->members = NULL; + $$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$); + } + ; + +SetOfType : kw_SET kw_OF Type + { + $$ = new_type(TSetOf); + $$->subtype = $3; + $$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$); + } + ; + +ChoiceType : kw_CHOICE '{' /* AlternativeTypeLists */ ComponentTypeList '}' + { + $$ = new_type(TChoice); + $$->members = $3; + } + ; + +ReferencedType : DefinedType + | UsefulType + ; + +DefinedType : IDENTIFIER + { + Symbol *s = addsym($1); + $$ = new_type(TType); + if(s->stype != Stype && s->stype != SUndefined) + error_message ("%s is not a type\n", $1); + else + $$->symbol = s; + } + ; + +UsefulType : kw_GeneralizedTime + { + $$ = new_tag(ASN1_C_UNIV, UT_GeneralizedTime, + TE_EXPLICIT, new_type(TGeneralizedTime)); + } + | kw_UTCTime + { + $$ = new_tag(ASN1_C_UNIV, UT_UTCTime, + TE_EXPLICIT, new_type(TUTCTime)); + } + ; + +ConstrainedType : Type Constraint + { + /* if (Constraint.type == contentConstrant) { + assert(Constraint.u.constraint.type == octetstring|bitstring-w/o-NamedBitList); // remember to check type reference too + if (Constraint.u.constraint.type) { + assert((Constraint.u.constraint.type.length % 8) == 0); + } + } + if (Constraint.u.constraint.encoding) { + type == der-oid|ber-oid + } + */ + } + ; + + +Constraint : '(' ConstraintSpec ')' + { + $$ = $2; + } + ; + +ConstraintSpec : GeneralConstraint + ; + +GeneralConstraint: ContentsConstraint + | UserDefinedConstraint + ; + +ContentsConstraint: kw_CONTAINING Type + { + $$ = new_constraint_spec(CT_CONTENTS); + $$->u.content.type = $2; + $$->u.content.encoding = NULL; + } + | kw_ENCODED kw_BY Value + { + if ($3->type != objectidentifiervalue) + error_message("Non-OID used in ENCODED BY constraint"); + $$ = new_constraint_spec(CT_CONTENTS); + $$->u.content.type = NULL; + $$->u.content.encoding = $3; + } + | kw_CONTAINING Type kw_ENCODED kw_BY Value + { + if ($5->type != objectidentifiervalue) + error_message("Non-OID used in ENCODED BY constraint"); + $$ = new_constraint_spec(CT_CONTENTS); + $$->u.content.type = $2; + $$->u.content.encoding = $5; + } + ; + +UserDefinedConstraint: kw_CONSTRAINED kw_BY '{' '}' + { + $$ = new_constraint_spec(CT_USER); + } + ; + +TaggedType : Tag tagenv Type + { + $$ = new_type(TTag); + $$->tag = $1; + $$->tag.tagenv = $2; + if($3->type == TTag && $2 == TE_IMPLICIT) { + $$->subtype = $3->subtype; + free($3); + } else + $$->subtype = $3; + } + ; + +Tag : '[' Class NUMBER ']' + { + $$.tagclass = $2; + $$.tagvalue = $3; + $$.tagenv = TE_EXPLICIT; + } + ; + +Class : /* */ + { + $$ = ASN1_C_CONTEXT; + } + | kw_UNIVERSAL + { + $$ = ASN1_C_UNIV; + } + | kw_APPLICATION + { + $$ = ASN1_C_APPL; + } + | kw_PRIVATE + { + $$ = ASN1_C_PRIVATE; + } + ; + +tagenv : /* */ + { + $$ = TE_EXPLICIT; + } + | kw_EXPLICIT + { + $$ = TE_EXPLICIT; + } + | kw_IMPLICIT + { + $$ = TE_IMPLICIT; + } + ; + + +ValueAssignment : IDENTIFIER Type EEQUAL Value + { + Symbol *s; + s = addsym ($1); + + s->stype = SValue; + s->value = $4; + generate_constant (s); + } + ; + +CharacterStringType: RestrictedCharactedStringType + ; + +RestrictedCharactedStringType: kw_GeneralString + { + $$ = new_tag(ASN1_C_UNIV, UT_GeneralString, + TE_EXPLICIT, new_type(TGeneralString)); + } + | kw_UTF8String + { + $$ = new_tag(ASN1_C_UNIV, UT_UTF8String, + TE_EXPLICIT, new_type(TUTF8String)); + } + | kw_PrintableString + { + $$ = new_tag(ASN1_C_UNIV, UT_PrintableString, + TE_EXPLICIT, new_type(TPrintableString)); + } + | kw_VisibleString + { + $$ = new_tag(ASN1_C_UNIV, UT_VisibleString, + TE_EXPLICIT, new_type(TVisibleString)); + } + | kw_IA5String + { + $$ = new_tag(ASN1_C_UNIV, UT_IA5String, + TE_EXPLICIT, new_type(TIA5String)); + } + | kw_BMPString + { + $$ = new_tag(ASN1_C_UNIV, UT_BMPString, + TE_EXPLICIT, new_type(TBMPString)); + } + | kw_UniversalString + { + $$ = new_tag(ASN1_C_UNIV, UT_UniversalString, + TE_EXPLICIT, new_type(TUniversalString)); + } + + ; + +ComponentTypeList: ComponentType + { + $$ = emalloc(sizeof(*$$)); + ASN1_TAILQ_INIT($$); + ASN1_TAILQ_INSERT_HEAD($$, $1, members); + } + | ComponentTypeList ',' ComponentType + { + ASN1_TAILQ_INSERT_TAIL($1, $3, members); + $$ = $1; + } + | ComponentTypeList ',' ELLIPSIS + { + struct member *m = ecalloc(1, sizeof(*m)); + m->name = estrdup("..."); + m->gen_name = estrdup("asn1_ellipsis"); + m->ellipsis = 1; + ASN1_TAILQ_INSERT_TAIL($1, m, members); + $$ = $1; + } + ; + +NamedType : IDENTIFIER Type + { + $$ = emalloc(sizeof(*$$)); + $$->name = $1; + $$->gen_name = estrdup($1); + output_name ($$->gen_name); + $$->type = $2; + $$->ellipsis = 0; + } + ; + +ComponentType : NamedType + { + $$ = $1; + $$->optional = 0; + $$->defval = NULL; + } + | NamedType kw_OPTIONAL + { + $$ = $1; + $$->optional = 1; + $$->defval = NULL; + } + | NamedType kw_DEFAULT Value + { + $$ = $1; + $$->optional = 0; + $$->defval = $3; + } + ; + +NamedBitList : NamedBit + { + $$ = emalloc(sizeof(*$$)); + ASN1_TAILQ_INIT($$); + ASN1_TAILQ_INSERT_HEAD($$, $1, members); + } + | NamedBitList ',' NamedBit + { + ASN1_TAILQ_INSERT_TAIL($1, $3, members); + $$ = $1; + } + ; + +NamedBit : IDENTIFIER '(' NUMBER ')' + { + $$ = emalloc(sizeof(*$$)); + $$->name = $1; + $$->gen_name = estrdup($1); + output_name ($$->gen_name); + $$->val = $3; + $$->optional = 0; + $$->ellipsis = 0; + $$->type = NULL; + } + ; + +objid_opt : objid + | /* empty */ { $$ = NULL; } + ; + +objid : '{' objid_list '}' + { + $$ = $2; + } + ; + +objid_list : /* empty */ + { + $$ = NULL; + } + | objid_element objid_list + { + if ($2) { + $$ = $2; + add_oid_to_tail($2, $1); + } else { + $$ = $1; + } + } + ; + +objid_element : IDENTIFIER '(' NUMBER ')' + { + $$ = new_objid($1, $3); + } + | IDENTIFIER + { + Symbol *s = addsym($1); + if(s->stype != SValue || + s->value->type != objectidentifiervalue) { + error_message("%s is not an object identifier\n", + s->name); + exit(1); + } + $$ = s->value->u.objectidentifiervalue; + } + | NUMBER + { + $$ = new_objid(NULL, $1); + } + ; + +Value : BuiltinValue + | ReferencedValue + ; + +BuiltinValue : BooleanValue + | CharacterStringValue + | IntegerValue + | ObjectIdentifierValue + | NullValue + ; + +ReferencedValue : DefinedValue + ; + +DefinedValue : Valuereference + ; + +Valuereference : IDENTIFIER + { + Symbol *s = addsym($1); + if(s->stype != SValue) + error_message ("%s is not a value\n", + s->name); + else + $$ = s->value; + } + ; + +CharacterStringValue: STRING + { + $$ = emalloc(sizeof(*$$)); + $$->type = stringvalue; + $$->u.stringvalue = $1; + } + ; + +BooleanValue : kw_TRUE + { + $$ = emalloc(sizeof(*$$)); + $$->type = booleanvalue; + $$->u.booleanvalue = 0; + } + | kw_FALSE + { + $$ = emalloc(sizeof(*$$)); + $$->type = booleanvalue; + $$->u.booleanvalue = 0; + } + ; + +IntegerValue : SignedNumber + { + $$ = emalloc(sizeof(*$$)); + $$->type = integervalue; + $$->u.integervalue = $1; + } + ; + +SignedNumber : NUMBER + ; + +NullValue : kw_NULL + { + } + ; + +ObjectIdentifierValue: objid + { + $$ = emalloc(sizeof(*$$)); + $$->type = objectidentifiervalue; + $$->u.objectidentifiervalue = $1; + } + ; + +%% + +void +yyerror (const char *s) +{ + error_message ("%s\n", s); +} + +static Type * +new_tag(int tagclass, int tagvalue, int tagenv, Type *oldtype) +{ + Type *t; + if(oldtype->type == TTag && oldtype->tag.tagenv == TE_IMPLICIT) { + t = oldtype; + oldtype = oldtype->subtype; /* XXX */ + } else + t = new_type (TTag); + + t->tag.tagclass = tagclass; + t->tag.tagvalue = tagvalue; + t->tag.tagenv = tagenv; + t->subtype = oldtype; + return t; +} + +static struct objid * +new_objid(const char *label, int value) +{ + struct objid *s; + s = emalloc(sizeof(*s)); + s->label = label; + s->value = value; + s->next = NULL; + return s; +} + +static void +add_oid_to_tail(struct objid *head, struct objid *tail) +{ + struct objid *o; + o = head; + while (o->next) + o = o->next; + o->next = tail; +} + +static Type * +new_type (Typetype tt) +{ + Type *t = ecalloc(1, sizeof(*t)); + t->type = tt; + return t; +} + +static struct constraint_spec * +new_constraint_spec(enum ctype ct) +{ + struct constraint_spec *c = ecalloc(1, sizeof(*c)); + c->ctype = ct; + return c; +} + +static void fix_labels2(Type *t, const char *prefix); +static void fix_labels1(struct memhead *members, const char *prefix) +{ + Member *m; + + if(members == NULL) + return; + ASN1_TAILQ_FOREACH(m, members, members) { + asprintf(&m->label, "%s_%s", prefix, m->gen_name); + if (m->label == NULL) + errx(1, "malloc"); + if(m->type != NULL) + fix_labels2(m->type, m->label); + } +} + +static void fix_labels2(Type *t, const char *prefix) +{ + for(; t; t = t->subtype) + fix_labels1(t->members, prefix); +} + +static void +fix_labels(Symbol *s) +{ + char *p; + asprintf(&p, "choice_%s", s->gen_name); + if (p == NULL) + errx(1, "malloc"); + fix_labels2(s->type, p); + free(p); +} |