VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

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