b4d0d230ccfb5 (Thomas Gleixner 2019-05-20 19:08:01 +0200 1) // SPDX-License-Identifier: GPL-2.0-or-later
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 2) /* Simplified ASN.1 notation parser
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 3) *
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 4) * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 5) * Written by David Howells (dhowells@redhat.com)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 6) */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 7)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 8) #include <stdarg.h>
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 9) #include <stdio.h>
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 10) #include <stdlib.h>
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 11) #include <stdint.h>
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 12) #include <stdbool.h>
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 13) #include <string.h>
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 14) #include <ctype.h>
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 15) #include <unistd.h>
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 16) #include <fcntl.h>
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 17) #include <sys/stat.h>
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 18) #include <linux/asn1_ber_bytecode.h>
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 19)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 20) enum token_type {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 21) DIRECTIVE_ABSENT,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 22) DIRECTIVE_ALL,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 23) DIRECTIVE_ANY,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 24) DIRECTIVE_APPLICATION,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 25) DIRECTIVE_AUTOMATIC,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 26) DIRECTIVE_BEGIN,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 27) DIRECTIVE_BIT,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 28) DIRECTIVE_BMPString,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 29) DIRECTIVE_BOOLEAN,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 30) DIRECTIVE_BY,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 31) DIRECTIVE_CHARACTER,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 32) DIRECTIVE_CHOICE,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 33) DIRECTIVE_CLASS,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 34) DIRECTIVE_COMPONENT,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 35) DIRECTIVE_COMPONENTS,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 36) DIRECTIVE_CONSTRAINED,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 37) DIRECTIVE_CONTAINING,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 38) DIRECTIVE_DEFAULT,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 39) DIRECTIVE_DEFINED,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 40) DIRECTIVE_DEFINITIONS,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 41) DIRECTIVE_EMBEDDED,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 42) DIRECTIVE_ENCODED,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 43) DIRECTIVE_ENCODING_CONTROL,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 44) DIRECTIVE_END,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 45) DIRECTIVE_ENUMERATED,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 46) DIRECTIVE_EXCEPT,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 47) DIRECTIVE_EXPLICIT,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 48) DIRECTIVE_EXPORTS,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 49) DIRECTIVE_EXTENSIBILITY,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 50) DIRECTIVE_EXTERNAL,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 51) DIRECTIVE_FALSE,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 52) DIRECTIVE_FROM,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 53) DIRECTIVE_GeneralString,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 54) DIRECTIVE_GeneralizedTime,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 55) DIRECTIVE_GraphicString,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 56) DIRECTIVE_IA5String,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 57) DIRECTIVE_IDENTIFIER,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 58) DIRECTIVE_IMPLICIT,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 59) DIRECTIVE_IMPLIED,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 60) DIRECTIVE_IMPORTS,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 61) DIRECTIVE_INCLUDES,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 62) DIRECTIVE_INSTANCE,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 63) DIRECTIVE_INSTRUCTIONS,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 64) DIRECTIVE_INTEGER,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 65) DIRECTIVE_INTERSECTION,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 66) DIRECTIVE_ISO646String,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 67) DIRECTIVE_MAX,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 68) DIRECTIVE_MIN,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 69) DIRECTIVE_MINUS_INFINITY,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 70) DIRECTIVE_NULL,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 71) DIRECTIVE_NumericString,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 72) DIRECTIVE_OBJECT,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 73) DIRECTIVE_OCTET,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 74) DIRECTIVE_OF,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 75) DIRECTIVE_OPTIONAL,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 76) DIRECTIVE_ObjectDescriptor,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 77) DIRECTIVE_PATTERN,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 78) DIRECTIVE_PDV,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 79) DIRECTIVE_PLUS_INFINITY,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 80) DIRECTIVE_PRESENT,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 81) DIRECTIVE_PRIVATE,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 82) DIRECTIVE_PrintableString,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 83) DIRECTIVE_REAL,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 84) DIRECTIVE_RELATIVE_OID,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 85) DIRECTIVE_SEQUENCE,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 86) DIRECTIVE_SET,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 87) DIRECTIVE_SIZE,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 88) DIRECTIVE_STRING,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 89) DIRECTIVE_SYNTAX,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 90) DIRECTIVE_T61String,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 91) DIRECTIVE_TAGS,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 92) DIRECTIVE_TRUE,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 93) DIRECTIVE_TeletexString,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 94) DIRECTIVE_UNION,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 95) DIRECTIVE_UNIQUE,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 96) DIRECTIVE_UNIVERSAL,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 97) DIRECTIVE_UTCTime,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 98) DIRECTIVE_UTF8String,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 99) DIRECTIVE_UniversalString,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 100) DIRECTIVE_VideotexString,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 101) DIRECTIVE_VisibleString,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 102) DIRECTIVE_WITH,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 103) NR__DIRECTIVES,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 104) TOKEN_ASSIGNMENT = NR__DIRECTIVES,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 105) TOKEN_OPEN_CURLY,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 106) TOKEN_CLOSE_CURLY,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 107) TOKEN_OPEN_SQUARE,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 108) TOKEN_CLOSE_SQUARE,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 109) TOKEN_OPEN_ACTION,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 110) TOKEN_CLOSE_ACTION,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 111) TOKEN_COMMA,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 112) TOKEN_NUMBER,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 113) TOKEN_TYPE_NAME,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 114) TOKEN_ELEMENT_NAME,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 115) NR__TOKENS
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 116) };
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 117)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 118) static const unsigned char token_to_tag[NR__TOKENS] = {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 119) /* EOC goes first */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 120) [DIRECTIVE_BOOLEAN] = ASN1_BOOL,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 121) [DIRECTIVE_INTEGER] = ASN1_INT,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 122) [DIRECTIVE_BIT] = ASN1_BTS,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 123) [DIRECTIVE_OCTET] = ASN1_OTS,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 124) [DIRECTIVE_NULL] = ASN1_NULL,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 125) [DIRECTIVE_OBJECT] = ASN1_OID,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 126) [DIRECTIVE_ObjectDescriptor] = ASN1_ODE,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 127) [DIRECTIVE_EXTERNAL] = ASN1_EXT,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 128) [DIRECTIVE_REAL] = ASN1_REAL,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 129) [DIRECTIVE_ENUMERATED] = ASN1_ENUM,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 130) [DIRECTIVE_EMBEDDED] = 0,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 131) [DIRECTIVE_UTF8String] = ASN1_UTF8STR,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 132) [DIRECTIVE_RELATIVE_OID] = ASN1_RELOID,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 133) /* 14 */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 134) /* 15 */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 135) [DIRECTIVE_SEQUENCE] = ASN1_SEQ,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 136) [DIRECTIVE_SET] = ASN1_SET,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 137) [DIRECTIVE_NumericString] = ASN1_NUMSTR,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 138) [DIRECTIVE_PrintableString] = ASN1_PRNSTR,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 139) [DIRECTIVE_T61String] = ASN1_TEXSTR,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 140) [DIRECTIVE_TeletexString] = ASN1_TEXSTR,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 141) [DIRECTIVE_VideotexString] = ASN1_VIDSTR,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 142) [DIRECTIVE_IA5String] = ASN1_IA5STR,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 143) [DIRECTIVE_UTCTime] = ASN1_UNITIM,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 144) [DIRECTIVE_GeneralizedTime] = ASN1_GENTIM,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 145) [DIRECTIVE_GraphicString] = ASN1_GRASTR,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 146) [DIRECTIVE_VisibleString] = ASN1_VISSTR,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 147) [DIRECTIVE_GeneralString] = ASN1_GENSTR,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 148) [DIRECTIVE_UniversalString] = ASN1_UNITIM,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 149) [DIRECTIVE_CHARACTER] = ASN1_CHRSTR,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 150) [DIRECTIVE_BMPString] = ASN1_BMPSTR,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 151) };
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 152)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 153) static const char asn1_classes[4][5] = {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 154) [ASN1_UNIV] = "UNIV",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 155) [ASN1_APPL] = "APPL",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 156) [ASN1_CONT] = "CONT",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 157) [ASN1_PRIV] = "PRIV"
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 158) };
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 159)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 160) static const char asn1_methods[2][5] = {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 161) [ASN1_UNIV] = "PRIM",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 162) [ASN1_APPL] = "CONS"
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 163) };
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 164)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 165) static const char *const asn1_universal_tags[32] = {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 166) "EOC",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 167) "BOOL",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 168) "INT",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 169) "BTS",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 170) "OTS",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 171) "NULL",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 172) "OID",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 173) "ODE",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 174) "EXT",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 175) "REAL",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 176) "ENUM",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 177) "EPDV",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 178) "UTF8STR",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 179) "RELOID",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 180) NULL, /* 14 */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 181) NULL, /* 15 */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 182) "SEQ",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 183) "SET",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 184) "NUMSTR",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 185) "PRNSTR",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 186) "TEXSTR",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 187) "VIDSTR",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 188) "IA5STR",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 189) "UNITIM",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 190) "GENTIM",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 191) "GRASTR",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 192) "VISSTR",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 193) "GENSTR",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 194) "UNISTR",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 195) "CHRSTR",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 196) "BMPSTR",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 197) NULL /* 31 */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 198) };
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 199)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 200) static const char *filename;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 201) static const char *grammar_name;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 202) static const char *outputname;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 203) static const char *headername;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 204)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 205) static const char *const directives[NR__DIRECTIVES] = {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 206) #define _(X) [DIRECTIVE_##X] = #X
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 207) _(ABSENT),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 208) _(ALL),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 209) _(ANY),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 210) _(APPLICATION),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 211) _(AUTOMATIC),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 212) _(BEGIN),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 213) _(BIT),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 214) _(BMPString),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 215) _(BOOLEAN),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 216) _(BY),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 217) _(CHARACTER),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 218) _(CHOICE),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 219) _(CLASS),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 220) _(COMPONENT),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 221) _(COMPONENTS),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 222) _(CONSTRAINED),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 223) _(CONTAINING),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 224) _(DEFAULT),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 225) _(DEFINED),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 226) _(DEFINITIONS),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 227) _(EMBEDDED),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 228) _(ENCODED),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 229) [DIRECTIVE_ENCODING_CONTROL] = "ENCODING-CONTROL",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 230) _(END),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 231) _(ENUMERATED),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 232) _(EXCEPT),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 233) _(EXPLICIT),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 234) _(EXPORTS),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 235) _(EXTENSIBILITY),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 236) _(EXTERNAL),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 237) _(FALSE),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 238) _(FROM),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 239) _(GeneralString),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 240) _(GeneralizedTime),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 241) _(GraphicString),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 242) _(IA5String),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 243) _(IDENTIFIER),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 244) _(IMPLICIT),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 245) _(IMPLIED),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 246) _(IMPORTS),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 247) _(INCLUDES),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 248) _(INSTANCE),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 249) _(INSTRUCTIONS),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 250) _(INTEGER),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 251) _(INTERSECTION),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 252) _(ISO646String),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 253) _(MAX),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 254) _(MIN),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 255) [DIRECTIVE_MINUS_INFINITY] = "MINUS-INFINITY",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 256) [DIRECTIVE_NULL] = "NULL",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 257) _(NumericString),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 258) _(OBJECT),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 259) _(OCTET),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 260) _(OF),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 261) _(OPTIONAL),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 262) _(ObjectDescriptor),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 263) _(PATTERN),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 264) _(PDV),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 265) [DIRECTIVE_PLUS_INFINITY] = "PLUS-INFINITY",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 266) _(PRESENT),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 267) _(PRIVATE),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 268) _(PrintableString),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 269) _(REAL),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 270) [DIRECTIVE_RELATIVE_OID] = "RELATIVE-OID",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 271) _(SEQUENCE),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 272) _(SET),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 273) _(SIZE),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 274) _(STRING),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 275) _(SYNTAX),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 276) _(T61String),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 277) _(TAGS),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 278) _(TRUE),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 279) _(TeletexString),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 280) _(UNION),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 281) _(UNIQUE),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 282) _(UNIVERSAL),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 283) _(UTCTime),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 284) _(UTF8String),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 285) _(UniversalString),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 286) _(VideotexString),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 287) _(VisibleString),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 288) _(WITH)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 289) };
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 290)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 291) struct action {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 292) struct action *next;
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 293) char *name;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 294) unsigned char index;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 295) };
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 296)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 297) static struct action *action_list;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 298) static unsigned nr_actions;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 299)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 300) struct token {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 301) unsigned short line;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 302) enum token_type token_type : 8;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 303) unsigned char size;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 304) struct action *action;
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 305) char *content;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 306) struct type *type;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 307) };
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 308)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 309) static struct token *token_list;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 310) static unsigned nr_tokens;
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 311) static bool verbose_opt;
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 312) static bool debug_opt;
e994393acd65e (Arnd Bergmann 2015-01-13 22:24:31 +0100 313)
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 314) #define verbose(fmt, ...) do { if (verbose_opt) printf(fmt, ## __VA_ARGS__); } while (0)
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 315) #define debug(fmt, ...) do { if (debug_opt) printf(fmt, ## __VA_ARGS__); } while (0)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 316)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 317) static int directive_compare(const void *_key, const void *_pdir)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 318) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 319) const struct token *token = _key;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 320) const char *const *pdir = _pdir, *dir = *pdir;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 321) size_t dlen, clen;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 322) int val;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 323)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 324) dlen = strlen(dir);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 325) clen = (dlen < token->size) ? dlen : token->size;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 326)
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 327) //debug("cmp(%s,%s) = ", token->content, dir);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 328)
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 329) val = memcmp(token->content, dir, clen);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 330) if (val != 0) {
e994393acd65e (Arnd Bergmann 2015-01-13 22:24:31 +0100 331) //debug("%d [cmp]\n", val);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 332) return val;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 333) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 334)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 335) if (dlen == token->size) {
e994393acd65e (Arnd Bergmann 2015-01-13 22:24:31 +0100 336) //debug("0\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 337) return 0;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 338) }
e994393acd65e (Arnd Bergmann 2015-01-13 22:24:31 +0100 339) //debug("%d\n", (int)dlen - (int)token->size);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 340) return dlen - token->size; /* shorter -> negative */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 341) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 342)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 343) /*
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 344) * Tokenise an ASN.1 grammar
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 345) */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 346) static void tokenise(char *buffer, char *end)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 347) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 348) struct token *tokens;
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 349) char *line, *nl, *start, *p, *q;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 350) unsigned tix, lineno;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 351)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 352) /* Assume we're going to have half as many tokens as we have
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 353) * characters
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 354) */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 355) token_list = tokens = calloc((end - buffer) / 2, sizeof(struct token));
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 356) if (!tokens) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 357) perror(NULL);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 358) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 359) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 360) tix = 0;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 361)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 362) lineno = 0;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 363) while (buffer < end) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 364) /* First of all, break out a line */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 365) lineno++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 366) line = buffer;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 367) nl = memchr(line, '\n', end - buffer);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 368) if (!nl) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 369) buffer = nl = end;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 370) } else {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 371) buffer = nl + 1;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 372) *nl = '\0';
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 373) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 374)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 375) /* Remove "--" comments */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 376) p = line;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 377) next_comment:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 378) while ((p = memchr(p, '-', nl - p))) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 379) if (p[1] == '-') {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 380) /* Found a comment; see if there's a terminator */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 381) q = p + 2;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 382) while ((q = memchr(q, '-', nl - q))) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 383) if (q[1] == '-') {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 384) /* There is - excise the comment */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 385) q += 2;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 386) memmove(p, q, nl - q);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 387) goto next_comment;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 388) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 389) q++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 390) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 391) *p = '\0';
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 392) nl = p;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 393) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 394) } else {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 395) p++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 396) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 397) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 398)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 399) p = line;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 400) while (p < nl) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 401) /* Skip white space */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 402) while (p < nl && isspace(*p))
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 403) *(p++) = 0;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 404) if (p >= nl)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 405) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 406)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 407) tokens[tix].line = lineno;
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 408) start = p;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 409)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 410) /* Handle string tokens */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 411) if (isalpha(*p)) {
9e1e8194332fa (Leonardo Bras 2018-10-24 01:03:51 -0300 412) const char **dir;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 413)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 414) /* Can be a directive, type name or element
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 415) * name. Find the end of the name.
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 416) */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 417) q = p + 1;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 418) while (q < nl && (isalnum(*q) || *q == '-' || *q == '_'))
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 419) q++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 420) tokens[tix].size = q - p;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 421) p = q;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 422)
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 423) tokens[tix].content = malloc(tokens[tix].size + 1);
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 424) if (!tokens[tix].content) {
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 425) perror(NULL);
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 426) exit(1);
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 427) }
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 428) memcpy(tokens[tix].content, start, tokens[tix].size);
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 429) tokens[tix].content[tokens[tix].size] = 0;
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 430)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 431) /* If it begins with a lowercase letter then
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 432) * it's an element name
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 433) */
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 434) if (islower(tokens[tix].content[0])) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 435) tokens[tix++].token_type = TOKEN_ELEMENT_NAME;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 436) continue;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 437) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 438)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 439) /* Otherwise we need to search the directive
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 440) * table
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 441) */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 442) dir = bsearch(&tokens[tix], directives,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 443) sizeof(directives) / sizeof(directives[1]),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 444) sizeof(directives[1]),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 445) directive_compare);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 446) if (dir) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 447) tokens[tix++].token_type = dir - directives;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 448) continue;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 449) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 450)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 451) tokens[tix++].token_type = TOKEN_TYPE_NAME;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 452) continue;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 453) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 454)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 455) /* Handle numbers */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 456) if (isdigit(*p)) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 457) /* Find the end of the number */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 458) q = p + 1;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 459) while (q < nl && (isdigit(*q)))
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 460) q++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 461) tokens[tix].size = q - p;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 462) p = q;
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 463) tokens[tix].content = malloc(tokens[tix].size + 1);
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 464) if (!tokens[tix].content) {
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 465) perror(NULL);
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 466) exit(1);
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 467) }
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 468) memcpy(tokens[tix].content, start, tokens[tix].size);
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 469) tokens[tix].content[tokens[tix].size] = 0;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 470) tokens[tix++].token_type = TOKEN_NUMBER;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 471) continue;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 472) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 473)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 474) if (nl - p >= 3) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 475) if (memcmp(p, "::=", 3) == 0) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 476) p += 3;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 477) tokens[tix].size = 3;
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 478) tokens[tix].content = "::=";
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 479) tokens[tix++].token_type = TOKEN_ASSIGNMENT;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 480) continue;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 481) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 482) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 483)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 484) if (nl - p >= 2) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 485) if (memcmp(p, "({", 2) == 0) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 486) p += 2;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 487) tokens[tix].size = 2;
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 488) tokens[tix].content = "({";
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 489) tokens[tix++].token_type = TOKEN_OPEN_ACTION;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 490) continue;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 491) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 492) if (memcmp(p, "})", 2) == 0) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 493) p += 2;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 494) tokens[tix].size = 2;
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 495) tokens[tix].content = "})";
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 496) tokens[tix++].token_type = TOKEN_CLOSE_ACTION;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 497) continue;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 498) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 499) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 500)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 501) if (nl - p >= 1) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 502) tokens[tix].size = 1;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 503) switch (*p) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 504) case '{':
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 505) p += 1;
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 506) tokens[tix].content = "{";
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 507) tokens[tix++].token_type = TOKEN_OPEN_CURLY;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 508) continue;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 509) case '}':
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 510) p += 1;
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 511) tokens[tix].content = "}";
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 512) tokens[tix++].token_type = TOKEN_CLOSE_CURLY;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 513) continue;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 514) case '[':
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 515) p += 1;
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 516) tokens[tix].content = "[";
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 517) tokens[tix++].token_type = TOKEN_OPEN_SQUARE;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 518) continue;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 519) case ']':
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 520) p += 1;
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 521) tokens[tix].content = "]";
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 522) tokens[tix++].token_type = TOKEN_CLOSE_SQUARE;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 523) continue;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 524) case ',':
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 525) p += 1;
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 526) tokens[tix].content = ",";
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 527) tokens[tix++].token_type = TOKEN_COMMA;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 528) continue;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 529) default:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 530) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 531) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 532) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 533)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 534) fprintf(stderr, "%s:%u: Unknown character in grammar: '%c'\n",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 535) filename, lineno, *p);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 536) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 537) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 538) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 539)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 540) nr_tokens = tix;
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 541) verbose("Extracted %u tokens\n", nr_tokens);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 542)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 543) #if 0
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 544) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 545) int n;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 546) for (n = 0; n < nr_tokens; n++)
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 547) debug("Token %3u: '%s'\n", n, token_list[n].content);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 548) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 549) #endif
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 550) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 551)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 552) static void build_type_list(void);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 553) static void parse(void);
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 554) static void dump_elements(void);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 555) static void render(FILE *out, FILE *hdr);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 556)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 557) /*
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 558) *
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 559) */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 560) int main(int argc, char **argv)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 561) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 562) struct stat st;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 563) ssize_t readlen;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 564) FILE *out, *hdr;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 565) char *buffer, *p;
e994393acd65e (Arnd Bergmann 2015-01-13 22:24:31 +0100 566) char *kbuild_verbose;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 567) int fd;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 568)
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 569) kbuild_verbose = getenv("KBUILD_VERBOSE");
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 570) if (kbuild_verbose)
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 571) verbose_opt = atoi(kbuild_verbose);
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 572)
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 573) while (argc > 4) {
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 574) if (strcmp(argv[1], "-v") == 0)
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 575) verbose_opt = true;
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 576) else if (strcmp(argv[1], "-d") == 0)
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 577) debug_opt = true;
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 578) else
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 579) break;
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 580) memmove(&argv[1], &argv[2], (argc - 2) * sizeof(char *));
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 581) argc--;
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 582) }
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 583)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 584) if (argc != 4) {
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 585) fprintf(stderr, "Format: %s [-v] [-d] <grammar-file> <c-file> <hdr-file>\n",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 586) argv[0]);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 587) exit(2);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 588) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 589)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 590) filename = argv[1];
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 591) outputname = argv[2];
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 592) headername = argv[3];
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 593)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 594) fd = open(filename, O_RDONLY);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 595) if (fd < 0) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 596) perror(filename);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 597) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 598) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 599)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 600) if (fstat(fd, &st) < 0) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 601) perror(filename);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 602) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 603) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 604)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 605) if (!(buffer = malloc(st.st_size + 1))) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 606) perror(NULL);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 607) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 608) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 609)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 610) if ((readlen = read(fd, buffer, st.st_size)) < 0) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 611) perror(filename);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 612) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 613) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 614)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 615) if (close(fd) < 0) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 616) perror(filename);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 617) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 618) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 619)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 620) if (readlen != st.st_size) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 621) fprintf(stderr, "%s: Short read\n", filename);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 622) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 623) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 624)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 625) p = strrchr(argv[1], '/');
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 626) p = p ? p + 1 : argv[1];
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 627) grammar_name = strdup(p);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 628) if (!p) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 629) perror(NULL);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 630) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 631) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 632) p = strchr(grammar_name, '.');
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 633) if (p)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 634) *p = '\0';
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 635)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 636) buffer[readlen] = 0;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 637) tokenise(buffer, buffer + readlen);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 638) build_type_list();
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 639) parse();
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 640) dump_elements();
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 641)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 642) out = fopen(outputname, "w");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 643) if (!out) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 644) perror(outputname);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 645) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 646) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 647)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 648) hdr = fopen(headername, "w");
952cca6a724c4 (Colin Ian King 2016-04-06 14:06:48 +0100 649) if (!hdr) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 650) perror(headername);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 651) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 652) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 653)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 654) render(out, hdr);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 655)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 656) if (fclose(out) < 0) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 657) perror(outputname);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 658) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 659) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 660)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 661) if (fclose(hdr) < 0) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 662) perror(headername);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 663) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 664) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 665)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 666) return 0;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 667) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 668)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 669) enum compound {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 670) NOT_COMPOUND,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 671) SET,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 672) SET_OF,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 673) SEQUENCE,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 674) SEQUENCE_OF,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 675) CHOICE,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 676) ANY,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 677) TYPE_REF,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 678) TAG_OVERRIDE
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 679) };
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 680)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 681) struct element {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 682) struct type *type_def;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 683) struct token *name;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 684) struct token *type;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 685) struct action *action;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 686) struct element *children;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 687) struct element *next;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 688) struct element *render_next;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 689) struct element *list_next;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 690) uint8_t n_elements;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 691) enum compound compound : 8;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 692) enum asn1_class class : 8;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 693) enum asn1_method method : 8;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 694) uint8_t tag;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 695) unsigned entry_index;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 696) unsigned flags;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 697) #define ELEMENT_IMPLICIT 0x0001
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 698) #define ELEMENT_EXPLICIT 0x0002
8d9b21dcfe681 (David Howells 2015-08-05 12:54:45 +0100 699) #define ELEMENT_TAG_SPECIFIED 0x0004
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 700) #define ELEMENT_RENDERED 0x0008
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 701) #define ELEMENT_SKIPPABLE 0x0010
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 702) #define ELEMENT_CONDITIONAL 0x0020
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 703) };
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 704)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 705) struct type {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 706) struct token *name;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 707) struct token *def;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 708) struct element *element;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 709) unsigned ref_count;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 710) unsigned flags;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 711) #define TYPE_STOP_MARKER 0x0001
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 712) #define TYPE_BEGIN 0x0002
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 713) };
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 714)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 715) static struct type *type_list;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 716) static struct type **type_index;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 717) static unsigned nr_types;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 718)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 719) static int type_index_compare(const void *_a, const void *_b)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 720) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 721) const struct type *const *a = _a, *const *b = _b;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 722)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 723) if ((*a)->name->size != (*b)->name->size)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 724) return (*a)->name->size - (*b)->name->size;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 725) else
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 726) return memcmp((*a)->name->content, (*b)->name->content,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 727) (*a)->name->size);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 728) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 729)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 730) static int type_finder(const void *_key, const void *_ti)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 731) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 732) const struct token *token = _key;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 733) const struct type *const *ti = _ti;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 734) const struct type *type = *ti;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 735)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 736) if (token->size != type->name->size)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 737) return token->size - type->name->size;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 738) else
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 739) return memcmp(token->content, type->name->content,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 740) token->size);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 741) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 742)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 743) /*
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 744) * Build up a list of types and a sorted index to that list.
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 745) */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 746) static void build_type_list(void)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 747) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 748) struct type *types;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 749) unsigned nr, t, n;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 750)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 751) nr = 0;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 752) for (n = 0; n < nr_tokens - 1; n++)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 753) if (token_list[n + 0].token_type == TOKEN_TYPE_NAME &&
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 754) token_list[n + 1].token_type == TOKEN_ASSIGNMENT)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 755) nr++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 756)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 757) if (nr == 0) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 758) fprintf(stderr, "%s: No defined types\n", filename);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 759) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 760) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 761)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 762) nr_types = nr;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 763) types = type_list = calloc(nr + 1, sizeof(type_list[0]));
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 764) if (!type_list) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 765) perror(NULL);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 766) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 767) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 768) type_index = calloc(nr, sizeof(type_index[0]));
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 769) if (!type_index) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 770) perror(NULL);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 771) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 772) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 773)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 774) t = 0;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 775) types[t].flags |= TYPE_BEGIN;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 776) for (n = 0; n < nr_tokens - 1; n++) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 777) if (token_list[n + 0].token_type == TOKEN_TYPE_NAME &&
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 778) token_list[n + 1].token_type == TOKEN_ASSIGNMENT) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 779) types[t].name = &token_list[n];
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 780) type_index[t] = &types[t];
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 781) t++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 782) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 783) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 784) types[t].name = &token_list[n + 1];
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 785) types[t].flags |= TYPE_STOP_MARKER;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 786)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 787) qsort(type_index, nr, sizeof(type_index[0]), type_index_compare);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 788)
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 789) verbose("Extracted %u types\n", nr_types);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 790) #if 0
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 791) for (n = 0; n < nr_types; n++) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 792) struct type *type = type_index[n];
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 793) debug("- %*.*s\n", type->name->content);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 794) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 795) #endif
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 796) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 797)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 798) static struct element *parse_type(struct token **_cursor, struct token *stop,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 799) struct token *name);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 800)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 801) /*
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 802) * Parse the token stream
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 803) */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 804) static void parse(void)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 805) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 806) struct token *cursor;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 807) struct type *type;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 808)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 809) /* Parse one type definition statement at a time */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 810) type = type_list;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 811) do {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 812) cursor = type->name;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 813)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 814) if (cursor[0].token_type != TOKEN_TYPE_NAME ||
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 815) cursor[1].token_type != TOKEN_ASSIGNMENT)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 816) abort();
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 817) cursor += 2;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 818)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 819) type->element = parse_type(&cursor, type[1].name, NULL);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 820) type->element->type_def = type;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 821)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 822) if (cursor != type[1].name) {
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 823) fprintf(stderr, "%s:%d: Parse error at token '%s'\n",
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 824) filename, cursor->line, cursor->content);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 825) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 826) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 827)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 828) } while (type++, !(type->flags & TYPE_STOP_MARKER));
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 829)
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 830) verbose("Extracted %u actions\n", nr_actions);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 831) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 832)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 833) static struct element *element_list;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 834)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 835) static struct element *alloc_elem(struct token *type)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 836) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 837) struct element *e = calloc(1, sizeof(*e));
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 838) if (!e) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 839) perror(NULL);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 840) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 841) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 842) e->list_next = element_list;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 843) element_list = e;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 844) return e;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 845) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 846)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 847) static struct element *parse_compound(struct token **_cursor, struct token *end,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 848) int alternates);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 849)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 850) /*
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 851) * Parse one type definition statement
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 852) */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 853) static struct element *parse_type(struct token **_cursor, struct token *end,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 854) struct token *name)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 855) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 856) struct element *top, *element;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 857) struct action *action, **ppaction;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 858) struct token *cursor = *_cursor;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 859) struct type **ref;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 860) char *p;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 861) int labelled = 0, implicit = 0;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 862)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 863) top = element = alloc_elem(cursor);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 864) element->class = ASN1_UNIV;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 865) element->method = ASN1_PRIM;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 866) element->tag = token_to_tag[cursor->token_type];
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 867) element->name = name;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 868)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 869) /* Extract the tag value if one given */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 870) if (cursor->token_type == TOKEN_OPEN_SQUARE) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 871) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 872) if (cursor >= end)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 873) goto overrun_error;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 874) switch (cursor->token_type) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 875) case DIRECTIVE_UNIVERSAL:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 876) element->class = ASN1_UNIV;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 877) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 878) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 879) case DIRECTIVE_APPLICATION:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 880) element->class = ASN1_APPL;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 881) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 882) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 883) case TOKEN_NUMBER:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 884) element->class = ASN1_CONT;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 885) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 886) case DIRECTIVE_PRIVATE:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 887) element->class = ASN1_PRIV;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 888) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 889) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 890) default:
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 891) fprintf(stderr, "%s:%d: Unrecognised tag class token '%s'\n",
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 892) filename, cursor->line, cursor->content);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 893) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 894) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 895)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 896) if (cursor >= end)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 897) goto overrun_error;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 898) if (cursor->token_type != TOKEN_NUMBER) {
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 899) fprintf(stderr, "%s:%d: Missing tag number '%s'\n",
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 900) filename, cursor->line, cursor->content);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 901) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 902) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 903)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 904) element->tag &= ~0x1f;
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 905) element->tag |= strtoul(cursor->content, &p, 10);
8d9b21dcfe681 (David Howells 2015-08-05 12:54:45 +0100 906) element->flags |= ELEMENT_TAG_SPECIFIED;
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 907) if (p - cursor->content != cursor->size)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 908) abort();
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 909) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 910)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 911) if (cursor >= end)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 912) goto overrun_error;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 913) if (cursor->token_type != TOKEN_CLOSE_SQUARE) {
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 914) fprintf(stderr, "%s:%d: Missing closing square bracket '%s'\n",
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 915) filename, cursor->line, cursor->content);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 916) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 917) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 918) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 919) if (cursor >= end)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 920) goto overrun_error;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 921) labelled = 1;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 922) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 923)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 924) /* Handle implicit and explicit markers */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 925) if (cursor->token_type == DIRECTIVE_IMPLICIT) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 926) element->flags |= ELEMENT_IMPLICIT;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 927) implicit = 1;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 928) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 929) if (cursor >= end)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 930) goto overrun_error;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 931) } else if (cursor->token_type == DIRECTIVE_EXPLICIT) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 932) element->flags |= ELEMENT_EXPLICIT;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 933) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 934) if (cursor >= end)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 935) goto overrun_error;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 936) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 937)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 938) if (labelled) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 939) if (!implicit)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 940) element->method |= ASN1_CONS;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 941) element->compound = implicit ? TAG_OVERRIDE : SEQUENCE;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 942) element->children = alloc_elem(cursor);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 943) element = element->children;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 944) element->class = ASN1_UNIV;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 945) element->method = ASN1_PRIM;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 946) element->tag = token_to_tag[cursor->token_type];
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 947) element->name = name;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 948) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 949)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 950) /* Extract the type we're expecting here */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 951) element->type = cursor;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 952) switch (cursor->token_type) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 953) case DIRECTIVE_ANY:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 954) element->compound = ANY;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 955) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 956) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 957)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 958) case DIRECTIVE_NULL:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 959) case DIRECTIVE_BOOLEAN:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 960) case DIRECTIVE_ENUMERATED:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 961) case DIRECTIVE_INTEGER:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 962) element->compound = NOT_COMPOUND;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 963) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 964) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 965)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 966) case DIRECTIVE_EXTERNAL:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 967) element->method = ASN1_CONS;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 968)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 969) case DIRECTIVE_BMPString:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 970) case DIRECTIVE_GeneralString:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 971) case DIRECTIVE_GraphicString:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 972) case DIRECTIVE_IA5String:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 973) case DIRECTIVE_ISO646String:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 974) case DIRECTIVE_NumericString:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 975) case DIRECTIVE_PrintableString:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 976) case DIRECTIVE_T61String:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 977) case DIRECTIVE_TeletexString:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 978) case DIRECTIVE_UniversalString:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 979) case DIRECTIVE_UTF8String:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 980) case DIRECTIVE_VideotexString:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 981) case DIRECTIVE_VisibleString:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 982) case DIRECTIVE_ObjectDescriptor:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 983) case DIRECTIVE_GeneralizedTime:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 984) case DIRECTIVE_UTCTime:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 985) element->compound = NOT_COMPOUND;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 986) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 987) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 988)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 989) case DIRECTIVE_BIT:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 990) case DIRECTIVE_OCTET:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 991) element->compound = NOT_COMPOUND;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 992) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 993) if (cursor >= end)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 994) goto overrun_error;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 995) if (cursor->token_type != DIRECTIVE_STRING)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 996) goto parse_error;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 997) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 998) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 999)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1000) case DIRECTIVE_OBJECT:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1001) element->compound = NOT_COMPOUND;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1002) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1003) if (cursor >= end)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1004) goto overrun_error;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1005) if (cursor->token_type != DIRECTIVE_IDENTIFIER)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1006) goto parse_error;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1007) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1008) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1009)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1010) case TOKEN_TYPE_NAME:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1011) element->compound = TYPE_REF;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1012) ref = bsearch(cursor, type_index, nr_types, sizeof(type_index[0]),
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1013) type_finder);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1014) if (!ref) {
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1015) fprintf(stderr, "%s:%d: Type '%s' undefined\n",
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1016) filename, cursor->line, cursor->content);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1017) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1018) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1019) cursor->type = *ref;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1020) (*ref)->ref_count++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1021) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1022) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1023)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1024) case DIRECTIVE_CHOICE:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1025) element->compound = CHOICE;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1026) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1027) element->children = parse_compound(&cursor, end, 1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1028) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1029)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1030) case DIRECTIVE_SEQUENCE:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1031) element->compound = SEQUENCE;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1032) element->method = ASN1_CONS;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1033) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1034) if (cursor >= end)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1035) goto overrun_error;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1036) if (cursor->token_type == DIRECTIVE_OF) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1037) element->compound = SEQUENCE_OF;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1038) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1039) if (cursor >= end)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1040) goto overrun_error;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1041) element->children = parse_type(&cursor, end, NULL);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1042) } else {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1043) element->children = parse_compound(&cursor, end, 0);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1044) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1045) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1046)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1047) case DIRECTIVE_SET:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1048) element->compound = SET;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1049) element->method = ASN1_CONS;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1050) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1051) if (cursor >= end)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1052) goto overrun_error;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1053) if (cursor->token_type == DIRECTIVE_OF) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1054) element->compound = SET_OF;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1055) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1056) if (cursor >= end)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1057) goto parse_error;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1058) element->children = parse_type(&cursor, end, NULL);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1059) } else {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1060) element->children = parse_compound(&cursor, end, 1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1061) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1062) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1063)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1064) default:
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1065) fprintf(stderr, "%s:%d: Token '%s' does not introduce a type\n",
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1066) filename, cursor->line, cursor->content);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1067) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1068) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1069)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1070) /* Handle elements that are optional */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1071) if (cursor < end && (cursor->token_type == DIRECTIVE_OPTIONAL ||
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1072) cursor->token_type == DIRECTIVE_DEFAULT)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1073) ) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1074) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1075) top->flags |= ELEMENT_SKIPPABLE;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1076) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1077)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1078) if (cursor < end && cursor->token_type == TOKEN_OPEN_ACTION) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1079) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1080) if (cursor >= end)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1081) goto overrun_error;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1082) if (cursor->token_type != TOKEN_ELEMENT_NAME) {
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1083) fprintf(stderr, "%s:%d: Token '%s' is not an action function name\n",
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1084) filename, cursor->line, cursor->content);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1085) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1086) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1087)
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1088) action = malloc(sizeof(struct action));
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1089) if (!action) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1090) perror(NULL);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1091) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1092) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1093) action->index = 0;
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1094) action->name = cursor->content;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1095)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1096) for (ppaction = &action_list;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1097) *ppaction;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1098) ppaction = &(*ppaction)->next
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1099) ) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1100) int cmp = strcmp(action->name, (*ppaction)->name);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1101) if (cmp == 0) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1102) free(action);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1103) action = *ppaction;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1104) goto found;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1105) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1106) if (cmp < 0) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1107) action->next = *ppaction;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1108) *ppaction = action;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1109) nr_actions++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1110) goto found;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1111) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1112) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1113) action->next = NULL;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1114) *ppaction = action;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1115) nr_actions++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1116) found:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1117)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1118) element->action = action;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1119) cursor->action = action;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1120) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1121) if (cursor >= end)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1122) goto overrun_error;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1123) if (cursor->token_type != TOKEN_CLOSE_ACTION) {
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1124) fprintf(stderr, "%s:%d: Missing close action, got '%s'\n",
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1125) filename, cursor->line, cursor->content);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1126) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1127) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1128) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1129) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1130)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1131) *_cursor = cursor;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1132) return top;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1133)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1134) parse_error:
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1135) fprintf(stderr, "%s:%d: Unexpected token '%s'\n",
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1136) filename, cursor->line, cursor->content);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1137) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1138)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1139) overrun_error:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1140) fprintf(stderr, "%s: Unexpectedly hit EOF\n", filename);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1141) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1142) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1143)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1144) /*
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1145) * Parse a compound type list
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1146) */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1147) static struct element *parse_compound(struct token **_cursor, struct token *end,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1148) int alternates)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1149) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1150) struct element *children, **child_p = &children, *element;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1151) struct token *cursor = *_cursor, *name;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1152)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1153) if (cursor->token_type != TOKEN_OPEN_CURLY) {
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1154) fprintf(stderr, "%s:%d: Expected compound to start with brace not '%s'\n",
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1155) filename, cursor->line, cursor->content);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1156) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1157) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1158) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1159) if (cursor >= end)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1160) goto overrun_error;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1161)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1162) if (cursor->token_type == TOKEN_OPEN_CURLY) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1163) fprintf(stderr, "%s:%d: Empty compound\n",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1164) filename, cursor->line);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1165) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1166) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1167)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1168) for (;;) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1169) name = NULL;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1170) if (cursor->token_type == TOKEN_ELEMENT_NAME) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1171) name = cursor;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1172) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1173) if (cursor >= end)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1174) goto overrun_error;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1175) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1176)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1177) element = parse_type(&cursor, end, name);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1178) if (alternates)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1179) element->flags |= ELEMENT_SKIPPABLE | ELEMENT_CONDITIONAL;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1180)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1181) *child_p = element;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1182) child_p = &element->next;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1183)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1184) if (cursor >= end)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1185) goto overrun_error;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1186) if (cursor->token_type != TOKEN_COMMA)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1187) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1188) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1189) if (cursor >= end)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1190) goto overrun_error;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1191) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1192)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1193) children->flags &= ~ELEMENT_CONDITIONAL;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1194)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1195) if (cursor->token_type != TOKEN_CLOSE_CURLY) {
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1196) fprintf(stderr, "%s:%d: Expected compound closure, got '%s'\n",
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1197) filename, cursor->line, cursor->content);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1198) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1199) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1200) cursor++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1201)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1202) *_cursor = cursor;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1203) return children;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1204)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1205) overrun_error:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1206) fprintf(stderr, "%s: Unexpectedly hit EOF\n", filename);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1207) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1208) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1209)
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1210) static void dump_element(const struct element *e, int level)
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1211) {
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1212) const struct element *c;
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1213) const struct type *t = e->type_def;
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1214) const char *name = e->name ? e->name->content : ".";
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1215) const char *tname = t && t->name ? t->name->content : ".";
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1216) char tag[32];
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1217)
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1218) if (e->class == 0 && e->method == 0 && e->tag == 0)
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1219) strcpy(tag, "<...>");
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1220) else if (e->class == ASN1_UNIV)
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1221) sprintf(tag, "%s %s %s",
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1222) asn1_classes[e->class],
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1223) asn1_methods[e->method],
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1224) asn1_universal_tags[e->tag]);
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1225) else
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1226) sprintf(tag, "%s %s %u",
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1227) asn1_classes[e->class],
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1228) asn1_methods[e->method],
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1229) e->tag);
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1230)
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1231) printf("%c%c%c%c%c %c %*s[*] \e[33m%s\e[m %s %s \e[35m%s\e[m\n",
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1232) e->flags & ELEMENT_IMPLICIT ? 'I' : '-',
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1233) e->flags & ELEMENT_EXPLICIT ? 'E' : '-',
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1234) e->flags & ELEMENT_TAG_SPECIFIED ? 'T' : '-',
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1235) e->flags & ELEMENT_SKIPPABLE ? 'S' : '-',
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1236) e->flags & ELEMENT_CONDITIONAL ? 'C' : '-',
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1237) "-tTqQcaro"[e->compound],
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1238) level, "",
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1239) tag,
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1240) tname,
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1241) name,
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1242) e->action ? e->action->name : "");
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1243) if (e->compound == TYPE_REF)
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1244) dump_element(e->type->type->element, level + 3);
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1245) else
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1246) for (c = e->children; c; c = c->next)
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1247) dump_element(c, level + 3);
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1248) }
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1249)
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1250) static void dump_elements(void)
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1251) {
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1252) if (debug_opt)
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1253) dump_element(type_list[0].element, 0);
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1254) }
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1255)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1256) static void render_element(FILE *out, struct element *e, struct element *tag);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1257) static void render_out_of_line_list(FILE *out);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1258)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1259) static int nr_entries;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1260) static int render_depth = 1;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1261) static struct element *render_list, **render_list_p = &render_list;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1262)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1263) __attribute__((format(printf, 2, 3)))
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1264) static void render_opcode(FILE *out, const char *fmt, ...)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1265) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1266) va_list va;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1267)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1268) if (out) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1269) fprintf(out, "\t[%4d] =%*s", nr_entries, render_depth, "");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1270) va_start(va, fmt);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1271) vfprintf(out, fmt, va);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1272) va_end(va);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1273) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1274) nr_entries++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1275) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1276)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1277) __attribute__((format(printf, 2, 3)))
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1278) static void render_more(FILE *out, const char *fmt, ...)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1279) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1280) va_list va;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1281)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1282) if (out) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1283) va_start(va, fmt);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1284) vfprintf(out, fmt, va);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1285) va_end(va);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1286) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1287) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1288)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1289) /*
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1290) * Render the grammar into a state machine definition.
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1291) */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1292) static void render(FILE *out, FILE *hdr)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1293) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1294) struct element *e;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1295) struct action *action;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1296) struct type *root;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1297) int index;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1298)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1299) fprintf(hdr, "/*\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1300) fprintf(hdr, " * Automatically generated by asn1_compiler. Do not edit\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1301) fprintf(hdr, " *\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1302) fprintf(hdr, " * ASN.1 parser for %s\n", grammar_name);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1303) fprintf(hdr, " */\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1304) fprintf(hdr, "#include <linux/asn1_decoder.h>\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1305) fprintf(hdr, "\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1306) fprintf(hdr, "extern const struct asn1_decoder %s_decoder;\n", grammar_name);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1307) if (ferror(hdr)) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1308) perror(headername);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1309) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1310) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1311)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1312) fprintf(out, "/*\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1313) fprintf(out, " * Automatically generated by asn1_compiler. Do not edit\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1314) fprintf(out, " *\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1315) fprintf(out, " * ASN.1 parser for %s\n", grammar_name);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1316) fprintf(out, " */\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1317) fprintf(out, "#include <linux/asn1_ber_bytecode.h>\n");
4fa8bc949de11 (Masahiro Yamada 2018-03-23 22:04:37 +0900 1318) fprintf(out, "#include \"%s.asn1.h\"\n", grammar_name);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1319) fprintf(out, "\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1320) if (ferror(out)) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1321) perror(outputname);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1322) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1323) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1324)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1325) /* Tabulate the action functions we might have to call */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1326) fprintf(hdr, "\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1327) index = 0;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1328) for (action = action_list; action; action = action->next) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1329) action->index = index++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1330) fprintf(hdr,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1331) "extern int %s(void *, size_t, unsigned char,"
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1332) " const void *, size_t);\n",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1333) action->name);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1334) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1335) fprintf(hdr, "\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1336)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1337) fprintf(out, "enum %s_actions {\n", grammar_name);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1338) for (action = action_list; action; action = action->next)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1339) fprintf(out, "\tACT_%s = %u,\n",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1340) action->name, action->index);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1341) fprintf(out, "\tNR__%s_actions = %u\n", grammar_name, nr_actions);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1342) fprintf(out, "};\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1343)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1344) fprintf(out, "\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1345) fprintf(out, "static const asn1_action_t %s_action_table[NR__%s_actions] = {\n",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1346) grammar_name, grammar_name);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1347) for (action = action_list; action; action = action->next)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1348) fprintf(out, "\t[%4u] = %s,\n", action->index, action->name);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1349) fprintf(out, "};\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1350)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1351) if (ferror(out)) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1352) perror(outputname);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1353) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1354) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1355)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1356) /* We do two passes - the first one calculates all the offsets */
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1357) verbose("Pass 1\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1358) nr_entries = 0;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1359) root = &type_list[0];
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1360) render_element(NULL, root->element, NULL);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1361) render_opcode(NULL, "ASN1_OP_COMPLETE,\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1362) render_out_of_line_list(NULL);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1363)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1364) for (e = element_list; e; e = e->list_next)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1365) e->flags &= ~ELEMENT_RENDERED;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1366)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1367) /* And then we actually render */
ae44a2f6a0333 (David Howells 2015-08-05 14:07:01 +0100 1368) verbose("Pass 2\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1369) fprintf(out, "\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1370) fprintf(out, "static const unsigned char %s_machine[] = {\n",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1371) grammar_name);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1372)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1373) nr_entries = 0;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1374) root = &type_list[0];
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1375) render_element(out, root->element, NULL);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1376) render_opcode(out, "ASN1_OP_COMPLETE,\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1377) render_out_of_line_list(out);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1378)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1379) fprintf(out, "};\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1380)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1381) fprintf(out, "\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1382) fprintf(out, "const struct asn1_decoder %s_decoder = {\n", grammar_name);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1383) fprintf(out, "\t.machine = %s_machine,\n", grammar_name);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1384) fprintf(out, "\t.machlen = sizeof(%s_machine),\n", grammar_name);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1385) fprintf(out, "\t.actions = %s_action_table,\n", grammar_name);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1386) fprintf(out, "};\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1387) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1388)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1389) /*
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1390) * Render the out-of-line elements
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1391) */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1392) static void render_out_of_line_list(FILE *out)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1393) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1394) struct element *e, *ce;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1395) const char *act;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1396) int entry;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1397)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1398) while ((e = render_list)) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1399) render_list = e->render_next;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1400) if (!render_list)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1401) render_list_p = &render_list;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1402)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1403) render_more(out, "\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1404) e->entry_index = entry = nr_entries;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1405) render_depth++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1406) for (ce = e->children; ce; ce = ce->next)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1407) render_element(out, ce, NULL);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1408) render_depth--;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1409)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1410) act = e->action ? "_ACT" : "";
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1411) switch (e->compound) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1412) case SEQUENCE:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1413) render_opcode(out, "ASN1_OP_END_SEQ%s,\n", act);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1414) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1415) case SEQUENCE_OF:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1416) render_opcode(out, "ASN1_OP_END_SEQ_OF%s,\n", act);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1417) render_opcode(out, "_jump_target(%u),\n", entry);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1418) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1419) case SET:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1420) render_opcode(out, "ASN1_OP_END_SET%s,\n", act);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1421) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1422) case SET_OF:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1423) render_opcode(out, "ASN1_OP_END_SET_OF%s,\n", act);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1424) render_opcode(out, "_jump_target(%u),\n", entry);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1425) break;
eb8948a03704f (Antonio Alecrim Jr 2013-09-16 11:04:54 -0300 1426) default:
eb8948a03704f (Antonio Alecrim Jr 2013-09-16 11:04:54 -0300 1427) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1428) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1429) if (e->action)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1430) render_opcode(out, "_action(ACT_%s),\n",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1431) e->action->name);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1432) render_opcode(out, "ASN1_OP_RETURN,\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1433) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1434) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1435)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1436) /*
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1437) * Render an element.
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1438) */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1439) static void render_element(FILE *out, struct element *e, struct element *tag)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1440) {
8d9b21dcfe681 (David Howells 2015-08-05 12:54:45 +0100 1441) struct element *ec, *x;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1442) const char *cond, *act;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1443) int entry, skippable = 0, outofline = 0;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1444)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1445) if (e->flags & ELEMENT_SKIPPABLE ||
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1446) (tag && tag->flags & ELEMENT_SKIPPABLE))
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1447) skippable = 1;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1448)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1449) if ((e->type_def && e->type_def->ref_count > 1) ||
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1450) skippable)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1451) outofline = 1;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1452)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1453) if (e->type_def && out) {
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1454) render_more(out, "\t// %s\n", e->type_def->name->content);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1455) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1456)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1457) /* Render the operation */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1458) cond = (e->flags & ELEMENT_CONDITIONAL ||
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1459) (tag && tag->flags & ELEMENT_CONDITIONAL)) ? "COND_" : "";
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1460) act = e->action ? "_ACT" : "";
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1461) switch (e->compound) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1462) case ANY:
233ce79db4b23 (David Howells 2015-08-05 12:54:46 +0100 1463) render_opcode(out, "ASN1_OP_%sMATCH_ANY%s%s,",
233ce79db4b23 (David Howells 2015-08-05 12:54:46 +0100 1464) cond, act, skippable ? "_OR_SKIP" : "");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1465) if (e->name)
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1466) render_more(out, "\t\t// %s", e->name->content);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1467) render_more(out, "\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1468) goto dont_render_tag;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1469)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1470) case TAG_OVERRIDE:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1471) render_element(out, e->children, e);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1472) return;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1473)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1474) case SEQUENCE:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1475) case SEQUENCE_OF:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1476) case SET:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1477) case SET_OF:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1478) render_opcode(out, "ASN1_OP_%sMATCH%s%s,",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1479) cond,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1480) outofline ? "_JUMP" : "",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1481) skippable ? "_OR_SKIP" : "");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1482) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1483)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1484) case CHOICE:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1485) goto dont_render_tag;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1486)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1487) case TYPE_REF:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1488) if (e->class == ASN1_UNIV && e->method == ASN1_PRIM && e->tag == 0)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1489) goto dont_render_tag;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1490) default:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1491) render_opcode(out, "ASN1_OP_%sMATCH%s%s,",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1492) cond, act,
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1493) skippable ? "_OR_SKIP" : "");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1494) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1495) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1496)
8d9b21dcfe681 (David Howells 2015-08-05 12:54:45 +0100 1497) x = tag ?: e;
8d9b21dcfe681 (David Howells 2015-08-05 12:54:45 +0100 1498) if (x->name)
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1499) render_more(out, "\t\t// %s", x->name->content);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1500) render_more(out, "\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1501)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1502) /* Render the tag */
8d9b21dcfe681 (David Howells 2015-08-05 12:54:45 +0100 1503) if (!tag || !(tag->flags & ELEMENT_TAG_SPECIFIED))
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1504) tag = e;
8d9b21dcfe681 (David Howells 2015-08-05 12:54:45 +0100 1505)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1506) if (tag->class == ASN1_UNIV &&
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1507) tag->tag != 14 &&
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1508) tag->tag != 15 &&
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1509) tag->tag != 31)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1510) render_opcode(out, "_tag(%s, %s, %s),\n",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1511) asn1_classes[tag->class],
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1512) asn1_methods[tag->method | e->method],
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1513) asn1_universal_tags[tag->tag]);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1514) else
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1515) render_opcode(out, "_tagn(%s, %s, %2u),\n",
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1516) asn1_classes[tag->class],
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1517) asn1_methods[tag->method | e->method],
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1518) tag->tag);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1519) tag = NULL;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1520) dont_render_tag:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1521)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1522) /* Deal with compound types */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1523) switch (e->compound) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1524) case TYPE_REF:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1525) render_element(out, e->type->type->element, tag);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1526) if (e->action)
3f3af97d8225a (David Howells 2015-08-05 12:54:46 +0100 1527) render_opcode(out, "ASN1_OP_%sACT,\n",
3f3af97d8225a (David Howells 2015-08-05 12:54:46 +0100 1528) skippable ? "MAYBE_" : "");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1529) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1530)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1531) case SEQUENCE:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1532) if (outofline) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1533) /* Render out-of-line for multiple use or
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1534) * skipability */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1535) render_opcode(out, "_jump_target(%u),", e->entry_index);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1536) if (e->type_def && e->type_def->name)
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1537) render_more(out, "\t\t// --> %s",
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1538) e->type_def->name->content);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1539) render_more(out, "\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1540) if (!(e->flags & ELEMENT_RENDERED)) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1541) e->flags |= ELEMENT_RENDERED;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1542) *render_list_p = e;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1543) render_list_p = &e->render_next;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1544) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1545) return;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1546) } else {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1547) /* Render inline for single use */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1548) render_depth++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1549) for (ec = e->children; ec; ec = ec->next)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1550) render_element(out, ec, NULL);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1551) render_depth--;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1552) render_opcode(out, "ASN1_OP_END_SEQ%s,\n", act);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1553) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1554) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1555)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1556) case SEQUENCE_OF:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1557) case SET_OF:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1558) if (outofline) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1559) /* Render out-of-line for multiple use or
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1560) * skipability */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1561) render_opcode(out, "_jump_target(%u),", e->entry_index);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1562) if (e->type_def && e->type_def->name)
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1563) render_more(out, "\t\t// --> %s",
c05cae9a58dca (David Howells 2015-07-29 21:14:00 +0100 1564) e->type_def->name->content);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1565) render_more(out, "\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1566) if (!(e->flags & ELEMENT_RENDERED)) {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1567) e->flags |= ELEMENT_RENDERED;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1568) *render_list_p = e;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1569) render_list_p = &e->render_next;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1570) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1571) return;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1572) } else {
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1573) /* Render inline for single use */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1574) entry = nr_entries;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1575) render_depth++;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1576) render_element(out, e->children, NULL);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1577) render_depth--;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1578) if (e->compound == SEQUENCE_OF)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1579) render_opcode(out, "ASN1_OP_END_SEQ_OF%s,\n", act);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1580) else
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1581) render_opcode(out, "ASN1_OP_END_SET_OF%s,\n", act);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1582) render_opcode(out, "_jump_target(%u),\n", entry);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1583) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1584) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1585)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1586) case SET:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1587) /* I can't think of a nice way to do SET support without having
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1588) * a stack of bitmasks to make sure no element is repeated.
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1589) * The bitmask has also to be checked that no non-optional
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1590) * elements are left out whilst not preventing optional
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1591) * elements from being left out.
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1592) */
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1593) fprintf(stderr, "The ASN.1 SET type is not currently supported.\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1594) exit(1);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1595)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1596) case CHOICE:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1597) for (ec = e->children; ec; ec = ec->next)
8d9b21dcfe681 (David Howells 2015-08-05 12:54:45 +0100 1598) render_element(out, ec, ec);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1599) if (!skippable)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1600) render_opcode(out, "ASN1_OP_COND_FAIL,\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1601) if (e->action)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1602) render_opcode(out, "ASN1_OP_ACT,\n");
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1603) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1604)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1605) default:
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1606) break;
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1607) }
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1608)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1609) if (e->action)
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1610) render_opcode(out, "_action(ACT_%s),\n", e->action->name);
4520c6a49af83 (David Howells 2012-09-21 23:31:13 +0100 1611) }