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