14520c6a49af833c83de6c74525ce8e07bbe6d783David Howells/* Simplified ASN.1 notation parser 24520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * 34520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved. 44520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * Written by David Howells (dhowells@redhat.com) 54520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * 64520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * This program is free software; you can redistribute it and/or 74520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * modify it under the terms of the GNU General Public Licence 84520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * as published by the Free Software Foundation; either version 94520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * 2 of the Licence, or (at your option) any later version. 104520c6a49af833c83de6c74525ce8e07bbe6d783David Howells */ 114520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 124520c6a49af833c83de6c74525ce8e07bbe6d783David Howells#include <stdarg.h> 134520c6a49af833c83de6c74525ce8e07bbe6d783David Howells#include <stdio.h> 144520c6a49af833c83de6c74525ce8e07bbe6d783David Howells#include <stdlib.h> 154520c6a49af833c83de6c74525ce8e07bbe6d783David Howells#include <stdint.h> 164520c6a49af833c83de6c74525ce8e07bbe6d783David Howells#include <string.h> 174520c6a49af833c83de6c74525ce8e07bbe6d783David Howells#include <ctype.h> 184520c6a49af833c83de6c74525ce8e07bbe6d783David Howells#include <unistd.h> 194520c6a49af833c83de6c74525ce8e07bbe6d783David Howells#include <fcntl.h> 204520c6a49af833c83de6c74525ce8e07bbe6d783David Howells#include <sys/stat.h> 214520c6a49af833c83de6c74525ce8e07bbe6d783David Howells#include <linux/asn1_ber_bytecode.h> 224520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 234520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsenum token_type { 244520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_ABSENT, 254520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_ALL, 264520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_ANY, 274520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_APPLICATION, 284520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_AUTOMATIC, 294520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_BEGIN, 304520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_BIT, 314520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_BMPString, 324520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_BOOLEAN, 334520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_BY, 344520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_CHARACTER, 354520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_CHOICE, 364520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_CLASS, 374520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_COMPONENT, 384520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_COMPONENTS, 394520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_CONSTRAINED, 404520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_CONTAINING, 414520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_DEFAULT, 424520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_DEFINED, 434520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_DEFINITIONS, 444520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_EMBEDDED, 454520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_ENCODED, 464520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_ENCODING_CONTROL, 474520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_END, 484520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_ENUMERATED, 494520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_EXCEPT, 504520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_EXPLICIT, 514520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_EXPORTS, 524520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_EXTENSIBILITY, 534520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_EXTERNAL, 544520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_FALSE, 554520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_FROM, 564520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_GeneralString, 574520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_GeneralizedTime, 584520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_GraphicString, 594520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_IA5String, 604520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_IDENTIFIER, 614520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_IMPLICIT, 624520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_IMPLIED, 634520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_IMPORTS, 644520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_INCLUDES, 654520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_INSTANCE, 664520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_INSTRUCTIONS, 674520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_INTEGER, 684520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_INTERSECTION, 694520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_ISO646String, 704520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_MAX, 714520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_MIN, 724520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_MINUS_INFINITY, 734520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_NULL, 744520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_NumericString, 754520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_OBJECT, 764520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_OCTET, 774520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_OF, 784520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_OPTIONAL, 794520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_ObjectDescriptor, 804520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_PATTERN, 814520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_PDV, 824520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_PLUS_INFINITY, 834520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_PRESENT, 844520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_PRIVATE, 854520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_PrintableString, 864520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_REAL, 874520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_RELATIVE_OID, 884520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_SEQUENCE, 894520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_SET, 904520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_SIZE, 914520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_STRING, 924520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_SYNTAX, 934520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_T61String, 944520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_TAGS, 954520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_TRUE, 964520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_TeletexString, 974520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_UNION, 984520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_UNIQUE, 994520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_UNIVERSAL, 1004520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_UTCTime, 1014520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_UTF8String, 1024520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_UniversalString, 1034520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_VideotexString, 1044520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_VisibleString, 1054520c6a49af833c83de6c74525ce8e07bbe6d783David Howells DIRECTIVE_WITH, 1064520c6a49af833c83de6c74525ce8e07bbe6d783David Howells NR__DIRECTIVES, 1074520c6a49af833c83de6c74525ce8e07bbe6d783David Howells TOKEN_ASSIGNMENT = NR__DIRECTIVES, 1084520c6a49af833c83de6c74525ce8e07bbe6d783David Howells TOKEN_OPEN_CURLY, 1094520c6a49af833c83de6c74525ce8e07bbe6d783David Howells TOKEN_CLOSE_CURLY, 1104520c6a49af833c83de6c74525ce8e07bbe6d783David Howells TOKEN_OPEN_SQUARE, 1114520c6a49af833c83de6c74525ce8e07bbe6d783David Howells TOKEN_CLOSE_SQUARE, 1124520c6a49af833c83de6c74525ce8e07bbe6d783David Howells TOKEN_OPEN_ACTION, 1134520c6a49af833c83de6c74525ce8e07bbe6d783David Howells TOKEN_CLOSE_ACTION, 1144520c6a49af833c83de6c74525ce8e07bbe6d783David Howells TOKEN_COMMA, 1154520c6a49af833c83de6c74525ce8e07bbe6d783David Howells TOKEN_NUMBER, 1164520c6a49af833c83de6c74525ce8e07bbe6d783David Howells TOKEN_TYPE_NAME, 1174520c6a49af833c83de6c74525ce8e07bbe6d783David Howells TOKEN_ELEMENT_NAME, 1184520c6a49af833c83de6c74525ce8e07bbe6d783David Howells NR__TOKENS 1194520c6a49af833c83de6c74525ce8e07bbe6d783David Howells}; 1204520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 1214520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic const unsigned char token_to_tag[NR__TOKENS] = { 1224520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* EOC goes first */ 1234520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_BOOLEAN] = ASN1_BOOL, 1244520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_INTEGER] = ASN1_INT, 1254520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_BIT] = ASN1_BTS, 1264520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_OCTET] = ASN1_OTS, 1274520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_NULL] = ASN1_NULL, 1284520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_OBJECT] = ASN1_OID, 1294520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_ObjectDescriptor] = ASN1_ODE, 1304520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_EXTERNAL] = ASN1_EXT, 1314520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_REAL] = ASN1_REAL, 1324520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_ENUMERATED] = ASN1_ENUM, 1334520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_EMBEDDED] = 0, 1344520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_UTF8String] = ASN1_UTF8STR, 1354520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_RELATIVE_OID] = ASN1_RELOID, 1364520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* 14 */ 1374520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* 15 */ 1384520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_SEQUENCE] = ASN1_SEQ, 1394520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_SET] = ASN1_SET, 1404520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_NumericString] = ASN1_NUMSTR, 1414520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_PrintableString] = ASN1_PRNSTR, 1424520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_T61String] = ASN1_TEXSTR, 1434520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_TeletexString] = ASN1_TEXSTR, 1444520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_VideotexString] = ASN1_VIDSTR, 1454520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_IA5String] = ASN1_IA5STR, 1464520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_UTCTime] = ASN1_UNITIM, 1474520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_GeneralizedTime] = ASN1_GENTIM, 1484520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_GraphicString] = ASN1_GRASTR, 1494520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_VisibleString] = ASN1_VISSTR, 1504520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_GeneralString] = ASN1_GENSTR, 1514520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_UniversalString] = ASN1_UNITIM, 1524520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_CHARACTER] = ASN1_CHRSTR, 1534520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_BMPString] = ASN1_BMPSTR, 1544520c6a49af833c83de6c74525ce8e07bbe6d783David Howells}; 1554520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 1564520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic const char asn1_classes[4][5] = { 1574520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [ASN1_UNIV] = "UNIV", 1584520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [ASN1_APPL] = "APPL", 1594520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [ASN1_CONT] = "CONT", 1604520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [ASN1_PRIV] = "PRIV" 1614520c6a49af833c83de6c74525ce8e07bbe6d783David Howells}; 1624520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 1634520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic const char asn1_methods[2][5] = { 1644520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [ASN1_UNIV] = "PRIM", 1654520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [ASN1_APPL] = "CONS" 1664520c6a49af833c83de6c74525ce8e07bbe6d783David Howells}; 1674520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 1684520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic const char *const asn1_universal_tags[32] = { 1694520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "EOC", 1704520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "BOOL", 1714520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "INT", 1724520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "BTS", 1734520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "OTS", 1744520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "NULL", 1754520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "OID", 1764520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "ODE", 1774520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "EXT", 1784520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "REAL", 1794520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "ENUM", 1804520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "EPDV", 1814520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "UTF8STR", 1824520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "RELOID", 1834520c6a49af833c83de6c74525ce8e07bbe6d783David Howells NULL, /* 14 */ 1844520c6a49af833c83de6c74525ce8e07bbe6d783David Howells NULL, /* 15 */ 1854520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "SEQ", 1864520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "SET", 1874520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "NUMSTR", 1884520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "PRNSTR", 1894520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "TEXSTR", 1904520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "VIDSTR", 1914520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "IA5STR", 1924520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "UNITIM", 1934520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "GENTIM", 1944520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "GRASTR", 1954520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "VISSTR", 1964520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "GENSTR", 1974520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "UNISTR", 1984520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "CHRSTR", 1994520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "BMPSTR", 2004520c6a49af833c83de6c74525ce8e07bbe6d783David Howells NULL /* 31 */ 2014520c6a49af833c83de6c74525ce8e07bbe6d783David Howells}; 2024520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 2034520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic const char *filename; 2044520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic const char *grammar_name; 2054520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic const char *outputname; 2064520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic const char *headername; 2074520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 2084520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic const char *const directives[NR__DIRECTIVES] = { 2094520c6a49af833c83de6c74525ce8e07bbe6d783David Howells#define _(X) [DIRECTIVE_##X] = #X 2104520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(ABSENT), 2114520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(ALL), 2124520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(ANY), 2134520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(APPLICATION), 2144520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(AUTOMATIC), 2154520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(BEGIN), 2164520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(BIT), 2174520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(BMPString), 2184520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(BOOLEAN), 2194520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(BY), 2204520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(CHARACTER), 2214520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(CHOICE), 2224520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(CLASS), 2234520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(COMPONENT), 2244520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(COMPONENTS), 2254520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(CONSTRAINED), 2264520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(CONTAINING), 2274520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(DEFAULT), 2284520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(DEFINED), 2294520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(DEFINITIONS), 2304520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(EMBEDDED), 2314520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(ENCODED), 2324520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_ENCODING_CONTROL] = "ENCODING-CONTROL", 2334520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(END), 2344520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(ENUMERATED), 2354520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(EXCEPT), 2364520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(EXPLICIT), 2374520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(EXPORTS), 2384520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(EXTENSIBILITY), 2394520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(EXTERNAL), 2404520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(FALSE), 2414520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(FROM), 2424520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(GeneralString), 2434520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(GeneralizedTime), 2444520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(GraphicString), 2454520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(IA5String), 2464520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(IDENTIFIER), 2474520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(IMPLICIT), 2484520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(IMPLIED), 2494520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(IMPORTS), 2504520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(INCLUDES), 2514520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(INSTANCE), 2524520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(INSTRUCTIONS), 2534520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(INTEGER), 2544520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(INTERSECTION), 2554520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(ISO646String), 2564520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(MAX), 2574520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(MIN), 2584520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_MINUS_INFINITY] = "MINUS-INFINITY", 2594520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_NULL] = "NULL", 2604520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(NumericString), 2614520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(OBJECT), 2624520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(OCTET), 2634520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(OF), 2644520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(OPTIONAL), 2654520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(ObjectDescriptor), 2664520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(PATTERN), 2674520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(PDV), 2684520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_PLUS_INFINITY] = "PLUS-INFINITY", 2694520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(PRESENT), 2704520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(PRIVATE), 2714520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(PrintableString), 2724520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(REAL), 2734520c6a49af833c83de6c74525ce8e07bbe6d783David Howells [DIRECTIVE_RELATIVE_OID] = "RELATIVE-OID", 2744520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(SEQUENCE), 2754520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(SET), 2764520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(SIZE), 2774520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(STRING), 2784520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(SYNTAX), 2794520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(T61String), 2804520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(TAGS), 2814520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(TRUE), 2824520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(TeletexString), 2834520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(UNION), 2844520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(UNIQUE), 2854520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(UNIVERSAL), 2864520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(UTCTime), 2874520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(UTF8String), 2884520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(UniversalString), 2894520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(VideotexString), 2904520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(VisibleString), 2914520c6a49af833c83de6c74525ce8e07bbe6d783David Howells _(WITH) 2924520c6a49af833c83de6c74525ce8e07bbe6d783David Howells}; 2934520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 2944520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstruct action { 2954520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct action *next; 2964520c6a49af833c83de6c74525ce8e07bbe6d783David Howells unsigned char index; 2974520c6a49af833c83de6c74525ce8e07bbe6d783David Howells char name[]; 2984520c6a49af833c83de6c74525ce8e07bbe6d783David Howells}; 2994520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 3004520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic struct action *action_list; 3014520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic unsigned nr_actions; 3024520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 3034520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstruct token { 3044520c6a49af833c83de6c74525ce8e07bbe6d783David Howells unsigned short line; 3054520c6a49af833c83de6c74525ce8e07bbe6d783David Howells enum token_type token_type : 8; 3064520c6a49af833c83de6c74525ce8e07bbe6d783David Howells unsigned char size; 3074520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct action *action; 3084520c6a49af833c83de6c74525ce8e07bbe6d783David Howells const char *value; 3094520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct type *type; 3104520c6a49af833c83de6c74525ce8e07bbe6d783David Howells}; 3114520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 3124520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic struct token *token_list; 3134520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic unsigned nr_tokens; 3144520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 3154520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic int directive_compare(const void *_key, const void *_pdir) 3164520c6a49af833c83de6c74525ce8e07bbe6d783David Howells{ 3174520c6a49af833c83de6c74525ce8e07bbe6d783David Howells const struct token *token = _key; 3184520c6a49af833c83de6c74525ce8e07bbe6d783David Howells const char *const *pdir = _pdir, *dir = *pdir; 3194520c6a49af833c83de6c74525ce8e07bbe6d783David Howells size_t dlen, clen; 3204520c6a49af833c83de6c74525ce8e07bbe6d783David Howells int val; 3214520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 3224520c6a49af833c83de6c74525ce8e07bbe6d783David Howells dlen = strlen(dir); 3234520c6a49af833c83de6c74525ce8e07bbe6d783David Howells clen = (dlen < token->size) ? dlen : token->size; 3244520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 3254520c6a49af833c83de6c74525ce8e07bbe6d783David Howells //printf("cmp(%*.*s,%s) = ", 3264520c6a49af833c83de6c74525ce8e07bbe6d783David Howells // (int)token->size, (int)token->size, token->value, 3274520c6a49af833c83de6c74525ce8e07bbe6d783David Howells // dir); 3284520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 3294520c6a49af833c83de6c74525ce8e07bbe6d783David Howells val = memcmp(token->value, dir, clen); 3304520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (val != 0) { 3314520c6a49af833c83de6c74525ce8e07bbe6d783David Howells //printf("%d [cmp]\n", val); 3324520c6a49af833c83de6c74525ce8e07bbe6d783David Howells return val; 3334520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 3344520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 3354520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (dlen == token->size) { 3364520c6a49af833c83de6c74525ce8e07bbe6d783David Howells //printf("0\n"); 3374520c6a49af833c83de6c74525ce8e07bbe6d783David Howells return 0; 3384520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 3394520c6a49af833c83de6c74525ce8e07bbe6d783David Howells //printf("%d\n", (int)dlen - (int)token->size); 3404520c6a49af833c83de6c74525ce8e07bbe6d783David Howells return dlen - token->size; /* shorter -> negative */ 3414520c6a49af833c83de6c74525ce8e07bbe6d783David Howells} 3424520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 3434520c6a49af833c83de6c74525ce8e07bbe6d783David Howells/* 3444520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * Tokenise an ASN.1 grammar 3454520c6a49af833c83de6c74525ce8e07bbe6d783David Howells */ 3464520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic void tokenise(char *buffer, char *end) 3474520c6a49af833c83de6c74525ce8e07bbe6d783David Howells{ 3484520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct token *tokens; 3494520c6a49af833c83de6c74525ce8e07bbe6d783David Howells char *line, *nl, *p, *q; 3504520c6a49af833c83de6c74525ce8e07bbe6d783David Howells unsigned tix, lineno; 3514520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 3524520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* Assume we're going to have half as many tokens as we have 3534520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * characters 3544520c6a49af833c83de6c74525ce8e07bbe6d783David Howells */ 3554520c6a49af833c83de6c74525ce8e07bbe6d783David Howells token_list = tokens = calloc((end - buffer) / 2, sizeof(struct token)); 3564520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (!tokens) { 3574520c6a49af833c83de6c74525ce8e07bbe6d783David Howells perror(NULL); 3584520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 3594520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 3604520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tix = 0; 3614520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 3624520c6a49af833c83de6c74525ce8e07bbe6d783David Howells lineno = 0; 3634520c6a49af833c83de6c74525ce8e07bbe6d783David Howells while (buffer < end) { 3644520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* First of all, break out a line */ 3654520c6a49af833c83de6c74525ce8e07bbe6d783David Howells lineno++; 3664520c6a49af833c83de6c74525ce8e07bbe6d783David Howells line = buffer; 3674520c6a49af833c83de6c74525ce8e07bbe6d783David Howells nl = memchr(line, '\n', end - buffer); 3684520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (!nl) { 3694520c6a49af833c83de6c74525ce8e07bbe6d783David Howells buffer = nl = end; 3704520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } else { 3714520c6a49af833c83de6c74525ce8e07bbe6d783David Howells buffer = nl + 1; 3724520c6a49af833c83de6c74525ce8e07bbe6d783David Howells *nl = '\0'; 3734520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 3744520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 3754520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* Remove "--" comments */ 3764520c6a49af833c83de6c74525ce8e07bbe6d783David Howells p = line; 3774520c6a49af833c83de6c74525ce8e07bbe6d783David Howells next_comment: 3784520c6a49af833c83de6c74525ce8e07bbe6d783David Howells while ((p = memchr(p, '-', nl - p))) { 3794520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (p[1] == '-') { 3804520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* Found a comment; see if there's a terminator */ 3814520c6a49af833c83de6c74525ce8e07bbe6d783David Howells q = p + 2; 3824520c6a49af833c83de6c74525ce8e07bbe6d783David Howells while ((q = memchr(q, '-', nl - q))) { 3834520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (q[1] == '-') { 3844520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* There is - excise the comment */ 3854520c6a49af833c83de6c74525ce8e07bbe6d783David Howells q += 2; 3864520c6a49af833c83de6c74525ce8e07bbe6d783David Howells memmove(p, q, nl - q); 3874520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto next_comment; 3884520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 3894520c6a49af833c83de6c74525ce8e07bbe6d783David Howells q++; 3904520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 3914520c6a49af833c83de6c74525ce8e07bbe6d783David Howells *p = '\0'; 3924520c6a49af833c83de6c74525ce8e07bbe6d783David Howells nl = p; 3934520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 3944520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } else { 3954520c6a49af833c83de6c74525ce8e07bbe6d783David Howells p++; 3964520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 3974520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 3984520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 3994520c6a49af833c83de6c74525ce8e07bbe6d783David Howells p = line; 4004520c6a49af833c83de6c74525ce8e07bbe6d783David Howells while (p < nl) { 4014520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* Skip white space */ 4024520c6a49af833c83de6c74525ce8e07bbe6d783David Howells while (p < nl && isspace(*p)) 4034520c6a49af833c83de6c74525ce8e07bbe6d783David Howells *(p++) = 0; 4044520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (p >= nl) 4054520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 4064520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 4074520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tokens[tix].line = lineno; 4084520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tokens[tix].value = p; 4094520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 4104520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* Handle string tokens */ 4114520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (isalpha(*p)) { 4124520c6a49af833c83de6c74525ce8e07bbe6d783David Howells const char **dir; 4134520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 4144520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* Can be a directive, type name or element 4154520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * name. Find the end of the name. 4164520c6a49af833c83de6c74525ce8e07bbe6d783David Howells */ 4174520c6a49af833c83de6c74525ce8e07bbe6d783David Howells q = p + 1; 4184520c6a49af833c83de6c74525ce8e07bbe6d783David Howells while (q < nl && (isalnum(*q) || *q == '-' || *q == '_')) 4194520c6a49af833c83de6c74525ce8e07bbe6d783David Howells q++; 4204520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tokens[tix].size = q - p; 4214520c6a49af833c83de6c74525ce8e07bbe6d783David Howells p = q; 4224520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 4234520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* If it begins with a lowercase letter then 4244520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * it's an element name 4254520c6a49af833c83de6c74525ce8e07bbe6d783David Howells */ 4264520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (islower(tokens[tix].value[0])) { 4274520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tokens[tix++].token_type = TOKEN_ELEMENT_NAME; 4284520c6a49af833c83de6c74525ce8e07bbe6d783David Howells continue; 4294520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 4304520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 4314520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* Otherwise we need to search the directive 4324520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * table 4334520c6a49af833c83de6c74525ce8e07bbe6d783David Howells */ 4344520c6a49af833c83de6c74525ce8e07bbe6d783David Howells dir = bsearch(&tokens[tix], directives, 4354520c6a49af833c83de6c74525ce8e07bbe6d783David Howells sizeof(directives) / sizeof(directives[1]), 4364520c6a49af833c83de6c74525ce8e07bbe6d783David Howells sizeof(directives[1]), 4374520c6a49af833c83de6c74525ce8e07bbe6d783David Howells directive_compare); 4384520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (dir) { 4394520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tokens[tix++].token_type = dir - directives; 4404520c6a49af833c83de6c74525ce8e07bbe6d783David Howells continue; 4414520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 4424520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 4434520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tokens[tix++].token_type = TOKEN_TYPE_NAME; 4444520c6a49af833c83de6c74525ce8e07bbe6d783David Howells continue; 4454520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 4464520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 4474520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* Handle numbers */ 4484520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (isdigit(*p)) { 4494520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* Find the end of the number */ 4504520c6a49af833c83de6c74525ce8e07bbe6d783David Howells q = p + 1; 4514520c6a49af833c83de6c74525ce8e07bbe6d783David Howells while (q < nl && (isdigit(*q))) 4524520c6a49af833c83de6c74525ce8e07bbe6d783David Howells q++; 4534520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tokens[tix].size = q - p; 4544520c6a49af833c83de6c74525ce8e07bbe6d783David Howells p = q; 4554520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tokens[tix++].token_type = TOKEN_NUMBER; 4564520c6a49af833c83de6c74525ce8e07bbe6d783David Howells continue; 4574520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 4584520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 4594520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (nl - p >= 3) { 4604520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (memcmp(p, "::=", 3) == 0) { 4614520c6a49af833c83de6c74525ce8e07bbe6d783David Howells p += 3; 4624520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tokens[tix].size = 3; 4634520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tokens[tix++].token_type = TOKEN_ASSIGNMENT; 4644520c6a49af833c83de6c74525ce8e07bbe6d783David Howells continue; 4654520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 4664520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 4674520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 4684520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (nl - p >= 2) { 4694520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (memcmp(p, "({", 2) == 0) { 4704520c6a49af833c83de6c74525ce8e07bbe6d783David Howells p += 2; 4714520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tokens[tix].size = 2; 4724520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tokens[tix++].token_type = TOKEN_OPEN_ACTION; 4734520c6a49af833c83de6c74525ce8e07bbe6d783David Howells continue; 4744520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 4754520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (memcmp(p, "})", 2) == 0) { 4764520c6a49af833c83de6c74525ce8e07bbe6d783David Howells p += 2; 4774520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tokens[tix].size = 2; 4784520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tokens[tix++].token_type = TOKEN_CLOSE_ACTION; 4794520c6a49af833c83de6c74525ce8e07bbe6d783David Howells continue; 4804520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 4814520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 4824520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 4834520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (nl - p >= 1) { 4844520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tokens[tix].size = 1; 4854520c6a49af833c83de6c74525ce8e07bbe6d783David Howells switch (*p) { 4864520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case '{': 4874520c6a49af833c83de6c74525ce8e07bbe6d783David Howells p += 1; 4884520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tokens[tix++].token_type = TOKEN_OPEN_CURLY; 4894520c6a49af833c83de6c74525ce8e07bbe6d783David Howells continue; 4904520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case '}': 4914520c6a49af833c83de6c74525ce8e07bbe6d783David Howells p += 1; 4924520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tokens[tix++].token_type = TOKEN_CLOSE_CURLY; 4934520c6a49af833c83de6c74525ce8e07bbe6d783David Howells continue; 4944520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case '[': 4954520c6a49af833c83de6c74525ce8e07bbe6d783David Howells p += 1; 4964520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tokens[tix++].token_type = TOKEN_OPEN_SQUARE; 4974520c6a49af833c83de6c74525ce8e07bbe6d783David Howells continue; 4984520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case ']': 4994520c6a49af833c83de6c74525ce8e07bbe6d783David Howells p += 1; 5004520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tokens[tix++].token_type = TOKEN_CLOSE_SQUARE; 5014520c6a49af833c83de6c74525ce8e07bbe6d783David Howells continue; 5024520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case ',': 5034520c6a49af833c83de6c74525ce8e07bbe6d783David Howells p += 1; 5044520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tokens[tix++].token_type = TOKEN_COMMA; 5054520c6a49af833c83de6c74525ce8e07bbe6d783David Howells continue; 5064520c6a49af833c83de6c74525ce8e07bbe6d783David Howells default: 5074520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 5084520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 5094520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 5104520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 5114520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(stderr, "%s:%u: Unknown character in grammar: '%c'\n", 5124520c6a49af833c83de6c74525ce8e07bbe6d783David Howells filename, lineno, *p); 5134520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 5144520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 5154520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 5164520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 5174520c6a49af833c83de6c74525ce8e07bbe6d783David Howells nr_tokens = tix; 5184520c6a49af833c83de6c74525ce8e07bbe6d783David Howells printf("Extracted %u tokens\n", nr_tokens); 5194520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 5204520c6a49af833c83de6c74525ce8e07bbe6d783David Howells#if 0 5214520c6a49af833c83de6c74525ce8e07bbe6d783David Howells { 5224520c6a49af833c83de6c74525ce8e07bbe6d783David Howells int n; 5234520c6a49af833c83de6c74525ce8e07bbe6d783David Howells for (n = 0; n < nr_tokens; n++) 5244520c6a49af833c83de6c74525ce8e07bbe6d783David Howells printf("Token %3u: '%*.*s'\n", 5254520c6a49af833c83de6c74525ce8e07bbe6d783David Howells n, 5264520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (int)token_list[n].size, (int)token_list[n].size, 5274520c6a49af833c83de6c74525ce8e07bbe6d783David Howells token_list[n].value); 5284520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 5294520c6a49af833c83de6c74525ce8e07bbe6d783David Howells#endif 5304520c6a49af833c83de6c74525ce8e07bbe6d783David Howells} 5314520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 5324520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic void build_type_list(void); 5334520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic void parse(void); 5344520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic void render(FILE *out, FILE *hdr); 5354520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 5364520c6a49af833c83de6c74525ce8e07bbe6d783David Howells/* 5374520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * 5384520c6a49af833c83de6c74525ce8e07bbe6d783David Howells */ 5394520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsint main(int argc, char **argv) 5404520c6a49af833c83de6c74525ce8e07bbe6d783David Howells{ 5414520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct stat st; 5424520c6a49af833c83de6c74525ce8e07bbe6d783David Howells ssize_t readlen; 5434520c6a49af833c83de6c74525ce8e07bbe6d783David Howells FILE *out, *hdr; 5444520c6a49af833c83de6c74525ce8e07bbe6d783David Howells char *buffer, *p; 5454520c6a49af833c83de6c74525ce8e07bbe6d783David Howells int fd; 5464520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 5474520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (argc != 4) { 5484520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(stderr, "Format: %s <grammar-file> <c-file> <hdr-file>\n", 5494520c6a49af833c83de6c74525ce8e07bbe6d783David Howells argv[0]); 5504520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(2); 5514520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 5524520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 5534520c6a49af833c83de6c74525ce8e07bbe6d783David Howells filename = argv[1]; 5544520c6a49af833c83de6c74525ce8e07bbe6d783David Howells outputname = argv[2]; 5554520c6a49af833c83de6c74525ce8e07bbe6d783David Howells headername = argv[3]; 5564520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 5574520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fd = open(filename, O_RDONLY); 5584520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (fd < 0) { 5594520c6a49af833c83de6c74525ce8e07bbe6d783David Howells perror(filename); 5604520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 5614520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 5624520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 5634520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (fstat(fd, &st) < 0) { 5644520c6a49af833c83de6c74525ce8e07bbe6d783David Howells perror(filename); 5654520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 5664520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 5674520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 5684520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (!(buffer = malloc(st.st_size + 1))) { 5694520c6a49af833c83de6c74525ce8e07bbe6d783David Howells perror(NULL); 5704520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 5714520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 5724520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 5734520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if ((readlen = read(fd, buffer, st.st_size)) < 0) { 5744520c6a49af833c83de6c74525ce8e07bbe6d783David Howells perror(filename); 5754520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 5764520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 5774520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 5784520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (close(fd) < 0) { 5794520c6a49af833c83de6c74525ce8e07bbe6d783David Howells perror(filename); 5804520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 5814520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 5824520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 5834520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (readlen != st.st_size) { 5844520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(stderr, "%s: Short read\n", filename); 5854520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 5864520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 5874520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 5884520c6a49af833c83de6c74525ce8e07bbe6d783David Howells p = strrchr(argv[1], '/'); 5894520c6a49af833c83de6c74525ce8e07bbe6d783David Howells p = p ? p + 1 : argv[1]; 5904520c6a49af833c83de6c74525ce8e07bbe6d783David Howells grammar_name = strdup(p); 5914520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (!p) { 5924520c6a49af833c83de6c74525ce8e07bbe6d783David Howells perror(NULL); 5934520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 5944520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 5954520c6a49af833c83de6c74525ce8e07bbe6d783David Howells p = strchr(grammar_name, '.'); 5964520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (p) 5974520c6a49af833c83de6c74525ce8e07bbe6d783David Howells *p = '\0'; 5984520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 5994520c6a49af833c83de6c74525ce8e07bbe6d783David Howells buffer[readlen] = 0; 6004520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tokenise(buffer, buffer + readlen); 6014520c6a49af833c83de6c74525ce8e07bbe6d783David Howells build_type_list(); 6024520c6a49af833c83de6c74525ce8e07bbe6d783David Howells parse(); 6034520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 6044520c6a49af833c83de6c74525ce8e07bbe6d783David Howells out = fopen(outputname, "w"); 6054520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (!out) { 6064520c6a49af833c83de6c74525ce8e07bbe6d783David Howells perror(outputname); 6074520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 6084520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 6094520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 6104520c6a49af833c83de6c74525ce8e07bbe6d783David Howells hdr = fopen(headername, "w"); 6114520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (!out) { 6124520c6a49af833c83de6c74525ce8e07bbe6d783David Howells perror(headername); 6134520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 6144520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 6154520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 6164520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render(out, hdr); 6174520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 6184520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (fclose(out) < 0) { 6194520c6a49af833c83de6c74525ce8e07bbe6d783David Howells perror(outputname); 6204520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 6214520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 6224520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 6234520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (fclose(hdr) < 0) { 6244520c6a49af833c83de6c74525ce8e07bbe6d783David Howells perror(headername); 6254520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 6264520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 6274520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 6284520c6a49af833c83de6c74525ce8e07bbe6d783David Howells return 0; 6294520c6a49af833c83de6c74525ce8e07bbe6d783David Howells} 6304520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 6314520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsenum compound { 6324520c6a49af833c83de6c74525ce8e07bbe6d783David Howells NOT_COMPOUND, 6334520c6a49af833c83de6c74525ce8e07bbe6d783David Howells SET, 6344520c6a49af833c83de6c74525ce8e07bbe6d783David Howells SET_OF, 6354520c6a49af833c83de6c74525ce8e07bbe6d783David Howells SEQUENCE, 6364520c6a49af833c83de6c74525ce8e07bbe6d783David Howells SEQUENCE_OF, 6374520c6a49af833c83de6c74525ce8e07bbe6d783David Howells CHOICE, 6384520c6a49af833c83de6c74525ce8e07bbe6d783David Howells ANY, 6394520c6a49af833c83de6c74525ce8e07bbe6d783David Howells TYPE_REF, 6404520c6a49af833c83de6c74525ce8e07bbe6d783David Howells TAG_OVERRIDE 6414520c6a49af833c83de6c74525ce8e07bbe6d783David Howells}; 6424520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 6434520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstruct element { 6444520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct type *type_def; 6454520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct token *name; 6464520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct token *type; 6474520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct action *action; 6484520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct element *children; 6494520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct element *next; 6504520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct element *render_next; 6514520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct element *list_next; 6524520c6a49af833c83de6c74525ce8e07bbe6d783David Howells uint8_t n_elements; 6534520c6a49af833c83de6c74525ce8e07bbe6d783David Howells enum compound compound : 8; 6544520c6a49af833c83de6c74525ce8e07bbe6d783David Howells enum asn1_class class : 8; 6554520c6a49af833c83de6c74525ce8e07bbe6d783David Howells enum asn1_method method : 8; 6564520c6a49af833c83de6c74525ce8e07bbe6d783David Howells uint8_t tag; 6574520c6a49af833c83de6c74525ce8e07bbe6d783David Howells unsigned entry_index; 6584520c6a49af833c83de6c74525ce8e07bbe6d783David Howells unsigned flags; 6594520c6a49af833c83de6c74525ce8e07bbe6d783David Howells#define ELEMENT_IMPLICIT 0x0001 6604520c6a49af833c83de6c74525ce8e07bbe6d783David Howells#define ELEMENT_EXPLICIT 0x0002 6614520c6a49af833c83de6c74525ce8e07bbe6d783David Howells#define ELEMENT_MARKED 0x0004 6624520c6a49af833c83de6c74525ce8e07bbe6d783David Howells#define ELEMENT_RENDERED 0x0008 6634520c6a49af833c83de6c74525ce8e07bbe6d783David Howells#define ELEMENT_SKIPPABLE 0x0010 6644520c6a49af833c83de6c74525ce8e07bbe6d783David Howells#define ELEMENT_CONDITIONAL 0x0020 6654520c6a49af833c83de6c74525ce8e07bbe6d783David Howells}; 6664520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 6674520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstruct type { 6684520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct token *name; 6694520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct token *def; 6704520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct element *element; 6714520c6a49af833c83de6c74525ce8e07bbe6d783David Howells unsigned ref_count; 6724520c6a49af833c83de6c74525ce8e07bbe6d783David Howells unsigned flags; 6734520c6a49af833c83de6c74525ce8e07bbe6d783David Howells#define TYPE_STOP_MARKER 0x0001 6744520c6a49af833c83de6c74525ce8e07bbe6d783David Howells#define TYPE_BEGIN 0x0002 6754520c6a49af833c83de6c74525ce8e07bbe6d783David Howells}; 6764520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 6774520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic struct type *type_list; 6784520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic struct type **type_index; 6794520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic unsigned nr_types; 6804520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 6814520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic int type_index_compare(const void *_a, const void *_b) 6824520c6a49af833c83de6c74525ce8e07bbe6d783David Howells{ 6834520c6a49af833c83de6c74525ce8e07bbe6d783David Howells const struct type *const *a = _a, *const *b = _b; 6844520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 6854520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if ((*a)->name->size != (*b)->name->size) 6864520c6a49af833c83de6c74525ce8e07bbe6d783David Howells return (*a)->name->size - (*b)->name->size; 6874520c6a49af833c83de6c74525ce8e07bbe6d783David Howells else 6884520c6a49af833c83de6c74525ce8e07bbe6d783David Howells return memcmp((*a)->name->value, (*b)->name->value, 6894520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (*a)->name->size); 6904520c6a49af833c83de6c74525ce8e07bbe6d783David Howells} 6914520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 6924520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic int type_finder(const void *_key, const void *_ti) 6934520c6a49af833c83de6c74525ce8e07bbe6d783David Howells{ 6944520c6a49af833c83de6c74525ce8e07bbe6d783David Howells const struct token *token = _key; 6954520c6a49af833c83de6c74525ce8e07bbe6d783David Howells const struct type *const *ti = _ti; 6964520c6a49af833c83de6c74525ce8e07bbe6d783David Howells const struct type *type = *ti; 6974520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 6984520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (token->size != type->name->size) 6994520c6a49af833c83de6c74525ce8e07bbe6d783David Howells return token->size - type->name->size; 7004520c6a49af833c83de6c74525ce8e07bbe6d783David Howells else 7014520c6a49af833c83de6c74525ce8e07bbe6d783David Howells return memcmp(token->value, type->name->value, 7024520c6a49af833c83de6c74525ce8e07bbe6d783David Howells token->size); 7034520c6a49af833c83de6c74525ce8e07bbe6d783David Howells} 7044520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 7054520c6a49af833c83de6c74525ce8e07bbe6d783David Howells/* 7064520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * Build up a list of types and a sorted index to that list. 7074520c6a49af833c83de6c74525ce8e07bbe6d783David Howells */ 7084520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic void build_type_list(void) 7094520c6a49af833c83de6c74525ce8e07bbe6d783David Howells{ 7104520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct type *types; 7114520c6a49af833c83de6c74525ce8e07bbe6d783David Howells unsigned nr, t, n; 7124520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 7134520c6a49af833c83de6c74525ce8e07bbe6d783David Howells nr = 0; 7144520c6a49af833c83de6c74525ce8e07bbe6d783David Howells for (n = 0; n < nr_tokens - 1; n++) 7154520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (token_list[n + 0].token_type == TOKEN_TYPE_NAME && 7164520c6a49af833c83de6c74525ce8e07bbe6d783David Howells token_list[n + 1].token_type == TOKEN_ASSIGNMENT) 7174520c6a49af833c83de6c74525ce8e07bbe6d783David Howells nr++; 7184520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 7194520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (nr == 0) { 7204520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(stderr, "%s: No defined types\n", filename); 7214520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 7224520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 7234520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 7244520c6a49af833c83de6c74525ce8e07bbe6d783David Howells nr_types = nr; 7254520c6a49af833c83de6c74525ce8e07bbe6d783David Howells types = type_list = calloc(nr + 1, sizeof(type_list[0])); 7264520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (!type_list) { 7274520c6a49af833c83de6c74525ce8e07bbe6d783David Howells perror(NULL); 7284520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 7294520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 7304520c6a49af833c83de6c74525ce8e07bbe6d783David Howells type_index = calloc(nr, sizeof(type_index[0])); 7314520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (!type_index) { 7324520c6a49af833c83de6c74525ce8e07bbe6d783David Howells perror(NULL); 7334520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 7344520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 7354520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 7364520c6a49af833c83de6c74525ce8e07bbe6d783David Howells t = 0; 7374520c6a49af833c83de6c74525ce8e07bbe6d783David Howells types[t].flags |= TYPE_BEGIN; 7384520c6a49af833c83de6c74525ce8e07bbe6d783David Howells for (n = 0; n < nr_tokens - 1; n++) { 7394520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (token_list[n + 0].token_type == TOKEN_TYPE_NAME && 7404520c6a49af833c83de6c74525ce8e07bbe6d783David Howells token_list[n + 1].token_type == TOKEN_ASSIGNMENT) { 7414520c6a49af833c83de6c74525ce8e07bbe6d783David Howells types[t].name = &token_list[n]; 7424520c6a49af833c83de6c74525ce8e07bbe6d783David Howells type_index[t] = &types[t]; 7434520c6a49af833c83de6c74525ce8e07bbe6d783David Howells t++; 7444520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 7454520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 7464520c6a49af833c83de6c74525ce8e07bbe6d783David Howells types[t].name = &token_list[n + 1]; 7474520c6a49af833c83de6c74525ce8e07bbe6d783David Howells types[t].flags |= TYPE_STOP_MARKER; 7484520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 7494520c6a49af833c83de6c74525ce8e07bbe6d783David Howells qsort(type_index, nr, sizeof(type_index[0]), type_index_compare); 7504520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 7514520c6a49af833c83de6c74525ce8e07bbe6d783David Howells printf("Extracted %u types\n", nr_types); 7524520c6a49af833c83de6c74525ce8e07bbe6d783David Howells#if 0 7534520c6a49af833c83de6c74525ce8e07bbe6d783David Howells for (n = 0; n < nr_types; n++) { 7544520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct type *type = type_index[n]; 7554520c6a49af833c83de6c74525ce8e07bbe6d783David Howells printf("- %*.*s\n", 7564520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (int)type->name->size, 7574520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (int)type->name->size, 7584520c6a49af833c83de6c74525ce8e07bbe6d783David Howells type->name->value); 7594520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 7604520c6a49af833c83de6c74525ce8e07bbe6d783David Howells#endif 7614520c6a49af833c83de6c74525ce8e07bbe6d783David Howells} 7624520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 7634520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic struct element *parse_type(struct token **_cursor, struct token *stop, 7644520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct token *name); 7654520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 7664520c6a49af833c83de6c74525ce8e07bbe6d783David Howells/* 7674520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * Parse the token stream 7684520c6a49af833c83de6c74525ce8e07bbe6d783David Howells */ 7694520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic void parse(void) 7704520c6a49af833c83de6c74525ce8e07bbe6d783David Howells{ 7714520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct token *cursor; 7724520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct type *type; 7734520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 7744520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* Parse one type definition statement at a time */ 7754520c6a49af833c83de6c74525ce8e07bbe6d783David Howells type = type_list; 7764520c6a49af833c83de6c74525ce8e07bbe6d783David Howells do { 7774520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor = type->name; 7784520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 7794520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor[0].token_type != TOKEN_TYPE_NAME || 7804520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor[1].token_type != TOKEN_ASSIGNMENT) 7814520c6a49af833c83de6c74525ce8e07bbe6d783David Howells abort(); 7824520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor += 2; 7834520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 7844520c6a49af833c83de6c74525ce8e07bbe6d783David Howells type->element = parse_type(&cursor, type[1].name, NULL); 7854520c6a49af833c83de6c74525ce8e07bbe6d783David Howells type->element->type_def = type; 7864520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 7874520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor != type[1].name) { 7884520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(stderr, "%s:%d: Parse error at token '%*.*s'\n", 7894520c6a49af833c83de6c74525ce8e07bbe6d783David Howells filename, cursor->line, 7904520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (int)cursor->size, (int)cursor->size, cursor->value); 7914520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 7924520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 7934520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 7944520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } while (type++, !(type->flags & TYPE_STOP_MARKER)); 7954520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 7964520c6a49af833c83de6c74525ce8e07bbe6d783David Howells printf("Extracted %u actions\n", nr_actions); 7974520c6a49af833c83de6c74525ce8e07bbe6d783David Howells} 7984520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 7994520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic struct element *element_list; 8004520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 8014520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic struct element *alloc_elem(struct token *type) 8024520c6a49af833c83de6c74525ce8e07bbe6d783David Howells{ 8034520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct element *e = calloc(1, sizeof(*e)); 8044520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (!e) { 8054520c6a49af833c83de6c74525ce8e07bbe6d783David Howells perror(NULL); 8064520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 8074520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 8084520c6a49af833c83de6c74525ce8e07bbe6d783David Howells e->list_next = element_list; 8094520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element_list = e; 8104520c6a49af833c83de6c74525ce8e07bbe6d783David Howells return e; 8114520c6a49af833c83de6c74525ce8e07bbe6d783David Howells} 8124520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 8134520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic struct element *parse_compound(struct token **_cursor, struct token *end, 8144520c6a49af833c83de6c74525ce8e07bbe6d783David Howells int alternates); 8154520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 8164520c6a49af833c83de6c74525ce8e07bbe6d783David Howells/* 8174520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * Parse one type definition statement 8184520c6a49af833c83de6c74525ce8e07bbe6d783David Howells */ 8194520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic struct element *parse_type(struct token **_cursor, struct token *end, 8204520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct token *name) 8214520c6a49af833c83de6c74525ce8e07bbe6d783David Howells{ 8224520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct element *top, *element; 8234520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct action *action, **ppaction; 8244520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct token *cursor = *_cursor; 8254520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct type **ref; 8264520c6a49af833c83de6c74525ce8e07bbe6d783David Howells char *p; 8274520c6a49af833c83de6c74525ce8e07bbe6d783David Howells int labelled = 0, implicit = 0; 8284520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 8294520c6a49af833c83de6c74525ce8e07bbe6d783David Howells top = element = alloc_elem(cursor); 8304520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->class = ASN1_UNIV; 8314520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->method = ASN1_PRIM; 8324520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->tag = token_to_tag[cursor->token_type]; 8334520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->name = name; 8344520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 8354520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* Extract the tag value if one given */ 8364520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor->token_type == TOKEN_OPEN_SQUARE) { 8374520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 8384520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor >= end) 8394520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto overrun_error; 8404520c6a49af833c83de6c74525ce8e07bbe6d783David Howells switch (cursor->token_type) { 8414520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_UNIVERSAL: 8424520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->class = ASN1_UNIV; 8434520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 8444520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 8454520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_APPLICATION: 8464520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->class = ASN1_APPL; 8474520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 8484520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 8494520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case TOKEN_NUMBER: 8504520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->class = ASN1_CONT; 8514520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 8524520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_PRIVATE: 8534520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->class = ASN1_PRIV; 8544520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 8554520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 8564520c6a49af833c83de6c74525ce8e07bbe6d783David Howells default: 8574520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(stderr, "%s:%d: Unrecognised tag class token '%*.*s'\n", 8584520c6a49af833c83de6c74525ce8e07bbe6d783David Howells filename, cursor->line, 8594520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (int)cursor->size, (int)cursor->size, cursor->value); 8604520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 8614520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 8624520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 8634520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor >= end) 8644520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto overrun_error; 8654520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor->token_type != TOKEN_NUMBER) { 8664520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(stderr, "%s:%d: Missing tag number '%*.*s'\n", 8674520c6a49af833c83de6c74525ce8e07bbe6d783David Howells filename, cursor->line, 8684520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (int)cursor->size, (int)cursor->size, cursor->value); 8694520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 8704520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 8714520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 8724520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->tag &= ~0x1f; 8734520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->tag |= strtoul(cursor->value, &p, 10); 8744520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (p - cursor->value != cursor->size) 8754520c6a49af833c83de6c74525ce8e07bbe6d783David Howells abort(); 8764520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 8774520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 8784520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor >= end) 8794520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto overrun_error; 8804520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor->token_type != TOKEN_CLOSE_SQUARE) { 8814520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(stderr, "%s:%d: Missing closing square bracket '%*.*s'\n", 8824520c6a49af833c83de6c74525ce8e07bbe6d783David Howells filename, cursor->line, 8834520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (int)cursor->size, (int)cursor->size, cursor->value); 8844520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 8854520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 8864520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 8874520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor >= end) 8884520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto overrun_error; 8894520c6a49af833c83de6c74525ce8e07bbe6d783David Howells labelled = 1; 8904520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 8914520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 8924520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* Handle implicit and explicit markers */ 8934520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor->token_type == DIRECTIVE_IMPLICIT) { 8944520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->flags |= ELEMENT_IMPLICIT; 8954520c6a49af833c83de6c74525ce8e07bbe6d783David Howells implicit = 1; 8964520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 8974520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor >= end) 8984520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto overrun_error; 8994520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } else if (cursor->token_type == DIRECTIVE_EXPLICIT) { 9004520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->flags |= ELEMENT_EXPLICIT; 9014520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 9024520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor >= end) 9034520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto overrun_error; 9044520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 9054520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 9064520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (labelled) { 9074520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (!implicit) 9084520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->method |= ASN1_CONS; 9094520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->compound = implicit ? TAG_OVERRIDE : SEQUENCE; 9104520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->children = alloc_elem(cursor); 9114520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element = element->children; 9124520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->class = ASN1_UNIV; 9134520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->method = ASN1_PRIM; 9144520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->tag = token_to_tag[cursor->token_type]; 9154520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->name = name; 9164520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 9174520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 9184520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* Extract the type we're expecting here */ 9194520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->type = cursor; 9204520c6a49af833c83de6c74525ce8e07bbe6d783David Howells switch (cursor->token_type) { 9214520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_ANY: 9224520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->compound = ANY; 9234520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 9244520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 9254520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 9264520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_NULL: 9274520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_BOOLEAN: 9284520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_ENUMERATED: 9294520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_INTEGER: 9304520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->compound = NOT_COMPOUND; 9314520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 9324520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 9334520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 9344520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_EXTERNAL: 9354520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->method = ASN1_CONS; 9364520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 9374520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_BMPString: 9384520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_GeneralString: 9394520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_GraphicString: 9404520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_IA5String: 9414520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_ISO646String: 9424520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_NumericString: 9434520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_PrintableString: 9444520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_T61String: 9454520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_TeletexString: 9464520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_UniversalString: 9474520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_UTF8String: 9484520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_VideotexString: 9494520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_VisibleString: 9504520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_ObjectDescriptor: 9514520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_GeneralizedTime: 9524520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_UTCTime: 9534520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->compound = NOT_COMPOUND; 9544520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 9554520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 9564520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 9574520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_BIT: 9584520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_OCTET: 9594520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->compound = NOT_COMPOUND; 9604520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 9614520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor >= end) 9624520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto overrun_error; 9634520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor->token_type != DIRECTIVE_STRING) 9644520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto parse_error; 9654520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 9664520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 9674520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 9684520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_OBJECT: 9694520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->compound = NOT_COMPOUND; 9704520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 9714520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor >= end) 9724520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto overrun_error; 9734520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor->token_type != DIRECTIVE_IDENTIFIER) 9744520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto parse_error; 9754520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 9764520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 9774520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 9784520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case TOKEN_TYPE_NAME: 9794520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->compound = TYPE_REF; 9804520c6a49af833c83de6c74525ce8e07bbe6d783David Howells ref = bsearch(cursor, type_index, nr_types, sizeof(type_index[0]), 9814520c6a49af833c83de6c74525ce8e07bbe6d783David Howells type_finder); 9824520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (!ref) { 9834520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(stderr, "%s:%d: Type '%*.*s' undefined\n", 9844520c6a49af833c83de6c74525ce8e07bbe6d783David Howells filename, cursor->line, 9854520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (int)cursor->size, (int)cursor->size, cursor->value); 9864520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 9874520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 9884520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor->type = *ref; 9894520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (*ref)->ref_count++; 9904520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 9914520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 9924520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 9934520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_CHOICE: 9944520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->compound = CHOICE; 9954520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 9964520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->children = parse_compound(&cursor, end, 1); 9974520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 9984520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 9994520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_SEQUENCE: 10004520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->compound = SEQUENCE; 10014520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->method = ASN1_CONS; 10024520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 10034520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor >= end) 10044520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto overrun_error; 10054520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor->token_type == DIRECTIVE_OF) { 10064520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->compound = SEQUENCE_OF; 10074520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 10084520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor >= end) 10094520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto overrun_error; 10104520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->children = parse_type(&cursor, end, NULL); 10114520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } else { 10124520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->children = parse_compound(&cursor, end, 0); 10134520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 10144520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 10154520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 10164520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case DIRECTIVE_SET: 10174520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->compound = SET; 10184520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->method = ASN1_CONS; 10194520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 10204520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor >= end) 10214520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto overrun_error; 10224520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor->token_type == DIRECTIVE_OF) { 10234520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->compound = SET_OF; 10244520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 10254520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor >= end) 10264520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto parse_error; 10274520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->children = parse_type(&cursor, end, NULL); 10284520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } else { 10294520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->children = parse_compound(&cursor, end, 1); 10304520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 10314520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 10324520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 10334520c6a49af833c83de6c74525ce8e07bbe6d783David Howells default: 10344520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(stderr, "%s:%d: Token '%*.*s' does not introduce a type\n", 10354520c6a49af833c83de6c74525ce8e07bbe6d783David Howells filename, cursor->line, 10364520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (int)cursor->size, (int)cursor->size, cursor->value); 10374520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 10384520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 10394520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 10404520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* Handle elements that are optional */ 10414520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor < end && (cursor->token_type == DIRECTIVE_OPTIONAL || 10424520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor->token_type == DIRECTIVE_DEFAULT) 10434520c6a49af833c83de6c74525ce8e07bbe6d783David Howells ) { 10444520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 10454520c6a49af833c83de6c74525ce8e07bbe6d783David Howells top->flags |= ELEMENT_SKIPPABLE; 10464520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 10474520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 10484520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor < end && cursor->token_type == TOKEN_OPEN_ACTION) { 10494520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 10504520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor >= end) 10514520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto overrun_error; 10524520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor->token_type != TOKEN_ELEMENT_NAME) { 10534520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(stderr, "%s:%d: Token '%*.*s' is not an action function name\n", 10544520c6a49af833c83de6c74525ce8e07bbe6d783David Howells filename, cursor->line, 10554520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (int)cursor->size, (int)cursor->size, cursor->value); 10564520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 10574520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 10584520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 10594520c6a49af833c83de6c74525ce8e07bbe6d783David Howells action = malloc(sizeof(struct action) + cursor->size + 1); 10604520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (!action) { 10614520c6a49af833c83de6c74525ce8e07bbe6d783David Howells perror(NULL); 10624520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 10634520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 10644520c6a49af833c83de6c74525ce8e07bbe6d783David Howells action->index = 0; 10654520c6a49af833c83de6c74525ce8e07bbe6d783David Howells memcpy(action->name, cursor->value, cursor->size); 10664520c6a49af833c83de6c74525ce8e07bbe6d783David Howells action->name[cursor->size] = 0; 10674520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 10684520c6a49af833c83de6c74525ce8e07bbe6d783David Howells for (ppaction = &action_list; 10694520c6a49af833c83de6c74525ce8e07bbe6d783David Howells *ppaction; 10704520c6a49af833c83de6c74525ce8e07bbe6d783David Howells ppaction = &(*ppaction)->next 10714520c6a49af833c83de6c74525ce8e07bbe6d783David Howells ) { 10724520c6a49af833c83de6c74525ce8e07bbe6d783David Howells int cmp = strcmp(action->name, (*ppaction)->name); 10734520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cmp == 0) { 10744520c6a49af833c83de6c74525ce8e07bbe6d783David Howells free(action); 10754520c6a49af833c83de6c74525ce8e07bbe6d783David Howells action = *ppaction; 10764520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto found; 10774520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 10784520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cmp < 0) { 10794520c6a49af833c83de6c74525ce8e07bbe6d783David Howells action->next = *ppaction; 10804520c6a49af833c83de6c74525ce8e07bbe6d783David Howells *ppaction = action; 10814520c6a49af833c83de6c74525ce8e07bbe6d783David Howells nr_actions++; 10824520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto found; 10834520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 10844520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 10854520c6a49af833c83de6c74525ce8e07bbe6d783David Howells action->next = NULL; 10864520c6a49af833c83de6c74525ce8e07bbe6d783David Howells *ppaction = action; 10874520c6a49af833c83de6c74525ce8e07bbe6d783David Howells nr_actions++; 10884520c6a49af833c83de6c74525ce8e07bbe6d783David Howells found: 10894520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 10904520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->action = action; 10914520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor->action = action; 10924520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 10934520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor >= end) 10944520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto overrun_error; 10954520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor->token_type != TOKEN_CLOSE_ACTION) { 10964520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(stderr, "%s:%d: Missing close action, got '%*.*s'\n", 10974520c6a49af833c83de6c74525ce8e07bbe6d783David Howells filename, cursor->line, 10984520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (int)cursor->size, (int)cursor->size, cursor->value); 10994520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 11004520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 11014520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 11024520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 11034520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 11044520c6a49af833c83de6c74525ce8e07bbe6d783David Howells *_cursor = cursor; 11054520c6a49af833c83de6c74525ce8e07bbe6d783David Howells return top; 11064520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 11074520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsparse_error: 11084520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(stderr, "%s:%d: Unexpected token '%*.*s'\n", 11094520c6a49af833c83de6c74525ce8e07bbe6d783David Howells filename, cursor->line, 11104520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (int)cursor->size, (int)cursor->size, cursor->value); 11114520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 11124520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 11134520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsoverrun_error: 11144520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(stderr, "%s: Unexpectedly hit EOF\n", filename); 11154520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 11164520c6a49af833c83de6c74525ce8e07bbe6d783David Howells} 11174520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 11184520c6a49af833c83de6c74525ce8e07bbe6d783David Howells/* 11194520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * Parse a compound type list 11204520c6a49af833c83de6c74525ce8e07bbe6d783David Howells */ 11214520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic struct element *parse_compound(struct token **_cursor, struct token *end, 11224520c6a49af833c83de6c74525ce8e07bbe6d783David Howells int alternates) 11234520c6a49af833c83de6c74525ce8e07bbe6d783David Howells{ 11244520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct element *children, **child_p = &children, *element; 11254520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct token *cursor = *_cursor, *name; 11264520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 11274520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor->token_type != TOKEN_OPEN_CURLY) { 11284520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(stderr, "%s:%d: Expected compound to start with brace not '%*.*s'\n", 11294520c6a49af833c83de6c74525ce8e07bbe6d783David Howells filename, cursor->line, 11304520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (int)cursor->size, (int)cursor->size, cursor->value); 11314520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 11324520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 11334520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 11344520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor >= end) 11354520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto overrun_error; 11364520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 11374520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor->token_type == TOKEN_OPEN_CURLY) { 11384520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(stderr, "%s:%d: Empty compound\n", 11394520c6a49af833c83de6c74525ce8e07bbe6d783David Howells filename, cursor->line); 11404520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 11414520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 11424520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 11434520c6a49af833c83de6c74525ce8e07bbe6d783David Howells for (;;) { 11444520c6a49af833c83de6c74525ce8e07bbe6d783David Howells name = NULL; 11454520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor->token_type == TOKEN_ELEMENT_NAME) { 11464520c6a49af833c83de6c74525ce8e07bbe6d783David Howells name = cursor; 11474520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 11484520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor >= end) 11494520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto overrun_error; 11504520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 11514520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 11524520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element = parse_type(&cursor, end, name); 11534520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (alternates) 11544520c6a49af833c83de6c74525ce8e07bbe6d783David Howells element->flags |= ELEMENT_SKIPPABLE | ELEMENT_CONDITIONAL; 11554520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 11564520c6a49af833c83de6c74525ce8e07bbe6d783David Howells *child_p = element; 11574520c6a49af833c83de6c74525ce8e07bbe6d783David Howells child_p = &element->next; 11584520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 11594520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor >= end) 11604520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto overrun_error; 11614520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor->token_type != TOKEN_COMMA) 11624520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 11634520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 11644520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor >= end) 11654520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto overrun_error; 11664520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 11674520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 11684520c6a49af833c83de6c74525ce8e07bbe6d783David Howells children->flags &= ~ELEMENT_CONDITIONAL; 11694520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 11704520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (cursor->token_type != TOKEN_CLOSE_CURLY) { 11714520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(stderr, "%s:%d: Expected compound closure, got '%*.*s'\n", 11724520c6a49af833c83de6c74525ce8e07bbe6d783David Howells filename, cursor->line, 11734520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (int)cursor->size, (int)cursor->size, cursor->value); 11744520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 11754520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 11764520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cursor++; 11774520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 11784520c6a49af833c83de6c74525ce8e07bbe6d783David Howells *_cursor = cursor; 11794520c6a49af833c83de6c74525ce8e07bbe6d783David Howells return children; 11804520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 11814520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsoverrun_error: 11824520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(stderr, "%s: Unexpectedly hit EOF\n", filename); 11834520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 11844520c6a49af833c83de6c74525ce8e07bbe6d783David Howells} 11854520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 11864520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic void render_element(FILE *out, struct element *e, struct element *tag); 11874520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic void render_out_of_line_list(FILE *out); 11884520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 11894520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic int nr_entries; 11904520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic int render_depth = 1; 11914520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic struct element *render_list, **render_list_p = &render_list; 11924520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 11934520c6a49af833c83de6c74525ce8e07bbe6d783David Howells__attribute__((format(printf, 2, 3))) 11944520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic void render_opcode(FILE *out, const char *fmt, ...) 11954520c6a49af833c83de6c74525ce8e07bbe6d783David Howells{ 11964520c6a49af833c83de6c74525ce8e07bbe6d783David Howells va_list va; 11974520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 11984520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (out) { 11994520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, "\t[%4d] =%*s", nr_entries, render_depth, ""); 12004520c6a49af833c83de6c74525ce8e07bbe6d783David Howells va_start(va, fmt); 12014520c6a49af833c83de6c74525ce8e07bbe6d783David Howells vfprintf(out, fmt, va); 12024520c6a49af833c83de6c74525ce8e07bbe6d783David Howells va_end(va); 12034520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 12044520c6a49af833c83de6c74525ce8e07bbe6d783David Howells nr_entries++; 12054520c6a49af833c83de6c74525ce8e07bbe6d783David Howells} 12064520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 12074520c6a49af833c83de6c74525ce8e07bbe6d783David Howells__attribute__((format(printf, 2, 3))) 12084520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic void render_more(FILE *out, const char *fmt, ...) 12094520c6a49af833c83de6c74525ce8e07bbe6d783David Howells{ 12104520c6a49af833c83de6c74525ce8e07bbe6d783David Howells va_list va; 12114520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 12124520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (out) { 12134520c6a49af833c83de6c74525ce8e07bbe6d783David Howells va_start(va, fmt); 12144520c6a49af833c83de6c74525ce8e07bbe6d783David Howells vfprintf(out, fmt, va); 12154520c6a49af833c83de6c74525ce8e07bbe6d783David Howells va_end(va); 12164520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 12174520c6a49af833c83de6c74525ce8e07bbe6d783David Howells} 12184520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 12194520c6a49af833c83de6c74525ce8e07bbe6d783David Howells/* 12204520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * Render the grammar into a state machine definition. 12214520c6a49af833c83de6c74525ce8e07bbe6d783David Howells */ 12224520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic void render(FILE *out, FILE *hdr) 12234520c6a49af833c83de6c74525ce8e07bbe6d783David Howells{ 12244520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct element *e; 12254520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct action *action; 12264520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct type *root; 12274520c6a49af833c83de6c74525ce8e07bbe6d783David Howells int index; 12284520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 12294520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(hdr, "/*\n"); 12304520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(hdr, " * Automatically generated by asn1_compiler. Do not edit\n"); 12314520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(hdr, " *\n"); 12324520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(hdr, " * ASN.1 parser for %s\n", grammar_name); 12334520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(hdr, " */\n"); 12344520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(hdr, "#include <linux/asn1_decoder.h>\n"); 12354520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(hdr, "\n"); 12364520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(hdr, "extern const struct asn1_decoder %s_decoder;\n", grammar_name); 12374520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (ferror(hdr)) { 12384520c6a49af833c83de6c74525ce8e07bbe6d783David Howells perror(headername); 12394520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 12404520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 12414520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 12424520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, "/*\n"); 12434520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, " * Automatically generated by asn1_compiler. Do not edit\n"); 12444520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, " *\n"); 12454520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, " * ASN.1 parser for %s\n", grammar_name); 12464520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, " */\n"); 12474520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, "#include <linux/asn1_ber_bytecode.h>\n"); 12484520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, "#include \"%s-asn1.h\"\n", grammar_name); 12494520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, "\n"); 12504520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (ferror(out)) { 12514520c6a49af833c83de6c74525ce8e07bbe6d783David Howells perror(outputname); 12524520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 12534520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 12544520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 12554520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* Tabulate the action functions we might have to call */ 12564520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(hdr, "\n"); 12574520c6a49af833c83de6c74525ce8e07bbe6d783David Howells index = 0; 12584520c6a49af833c83de6c74525ce8e07bbe6d783David Howells for (action = action_list; action; action = action->next) { 12594520c6a49af833c83de6c74525ce8e07bbe6d783David Howells action->index = index++; 12604520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(hdr, 12614520c6a49af833c83de6c74525ce8e07bbe6d783David Howells "extern int %s(void *, size_t, unsigned char," 12624520c6a49af833c83de6c74525ce8e07bbe6d783David Howells " const void *, size_t);\n", 12634520c6a49af833c83de6c74525ce8e07bbe6d783David Howells action->name); 12644520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 12654520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(hdr, "\n"); 12664520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 12674520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, "enum %s_actions {\n", grammar_name); 12684520c6a49af833c83de6c74525ce8e07bbe6d783David Howells for (action = action_list; action; action = action->next) 12694520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, "\tACT_%s = %u,\n", 12704520c6a49af833c83de6c74525ce8e07bbe6d783David Howells action->name, action->index); 12714520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, "\tNR__%s_actions = %u\n", grammar_name, nr_actions); 12724520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, "};\n"); 12734520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 12744520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, "\n"); 12754520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, "static const asn1_action_t %s_action_table[NR__%s_actions] = {\n", 12764520c6a49af833c83de6c74525ce8e07bbe6d783David Howells grammar_name, grammar_name); 12774520c6a49af833c83de6c74525ce8e07bbe6d783David Howells for (action = action_list; action; action = action->next) 12784520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, "\t[%4u] = %s,\n", action->index, action->name); 12794520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, "};\n"); 12804520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 12814520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (ferror(out)) { 12824520c6a49af833c83de6c74525ce8e07bbe6d783David Howells perror(outputname); 12834520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 12844520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 12854520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 12864520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* We do two passes - the first one calculates all the offsets */ 12874520c6a49af833c83de6c74525ce8e07bbe6d783David Howells printf("Pass 1\n"); 12884520c6a49af833c83de6c74525ce8e07bbe6d783David Howells nr_entries = 0; 12894520c6a49af833c83de6c74525ce8e07bbe6d783David Howells root = &type_list[0]; 12904520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_element(NULL, root->element, NULL); 12914520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(NULL, "ASN1_OP_COMPLETE,\n"); 12924520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_out_of_line_list(NULL); 12934520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 12944520c6a49af833c83de6c74525ce8e07bbe6d783David Howells for (e = element_list; e; e = e->list_next) 12954520c6a49af833c83de6c74525ce8e07bbe6d783David Howells e->flags &= ~ELEMENT_RENDERED; 12964520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 12974520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* And then we actually render */ 12984520c6a49af833c83de6c74525ce8e07bbe6d783David Howells printf("Pass 2\n"); 12994520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, "\n"); 13004520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, "static const unsigned char %s_machine[] = {\n", 13014520c6a49af833c83de6c74525ce8e07bbe6d783David Howells grammar_name); 13024520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 13034520c6a49af833c83de6c74525ce8e07bbe6d783David Howells nr_entries = 0; 13044520c6a49af833c83de6c74525ce8e07bbe6d783David Howells root = &type_list[0]; 13054520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_element(out, root->element, NULL); 13064520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(out, "ASN1_OP_COMPLETE,\n"); 13074520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_out_of_line_list(out); 13084520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 13094520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, "};\n"); 13104520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 13114520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, "\n"); 13124520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, "const struct asn1_decoder %s_decoder = {\n", grammar_name); 13134520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, "\t.machine = %s_machine,\n", grammar_name); 13144520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, "\t.machlen = sizeof(%s_machine),\n", grammar_name); 13154520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, "\t.actions = %s_action_table,\n", grammar_name); 13164520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(out, "};\n"); 13174520c6a49af833c83de6c74525ce8e07bbe6d783David Howells} 13184520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 13194520c6a49af833c83de6c74525ce8e07bbe6d783David Howells/* 13204520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * Render the out-of-line elements 13214520c6a49af833c83de6c74525ce8e07bbe6d783David Howells */ 13224520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic void render_out_of_line_list(FILE *out) 13234520c6a49af833c83de6c74525ce8e07bbe6d783David Howells{ 13244520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct element *e, *ce; 13254520c6a49af833c83de6c74525ce8e07bbe6d783David Howells const char *act; 13264520c6a49af833c83de6c74525ce8e07bbe6d783David Howells int entry; 13274520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 13284520c6a49af833c83de6c74525ce8e07bbe6d783David Howells while ((e = render_list)) { 13294520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_list = e->render_next; 13304520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (!render_list) 13314520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_list_p = &render_list; 13324520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 13334520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_more(out, "\n"); 13344520c6a49af833c83de6c74525ce8e07bbe6d783David Howells e->entry_index = entry = nr_entries; 13354520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_depth++; 13364520c6a49af833c83de6c74525ce8e07bbe6d783David Howells for (ce = e->children; ce; ce = ce->next) 13374520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_element(out, ce, NULL); 13384520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_depth--; 13394520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 13404520c6a49af833c83de6c74525ce8e07bbe6d783David Howells act = e->action ? "_ACT" : ""; 13414520c6a49af833c83de6c74525ce8e07bbe6d783David Howells switch (e->compound) { 13424520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case SEQUENCE: 13434520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(out, "ASN1_OP_END_SEQ%s,\n", act); 13444520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 13454520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case SEQUENCE_OF: 13464520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(out, "ASN1_OP_END_SEQ_OF%s,\n", act); 13474520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(out, "_jump_target(%u),\n", entry); 13484520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 13494520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case SET: 13504520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(out, "ASN1_OP_END_SET%s,\n", act); 13514520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 13524520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case SET_OF: 13534520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(out, "ASN1_OP_END_SET_OF%s,\n", act); 13544520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(out, "_jump_target(%u),\n", entry); 13554520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 1356eb8948a03704f3dbbfc7e83090e20e93c6c476d2Antonio Alecrim Jr default: 1357eb8948a03704f3dbbfc7e83090e20e93c6c476d2Antonio Alecrim Jr break; 13584520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 13594520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (e->action) 13604520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(out, "_action(ACT_%s),\n", 13614520c6a49af833c83de6c74525ce8e07bbe6d783David Howells e->action->name); 13624520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(out, "ASN1_OP_RETURN,\n"); 13634520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 13644520c6a49af833c83de6c74525ce8e07bbe6d783David Howells} 13654520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 13664520c6a49af833c83de6c74525ce8e07bbe6d783David Howells/* 13674520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * Render an element. 13684520c6a49af833c83de6c74525ce8e07bbe6d783David Howells */ 13694520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsstatic void render_element(FILE *out, struct element *e, struct element *tag) 13704520c6a49af833c83de6c74525ce8e07bbe6d783David Howells{ 13714520c6a49af833c83de6c74525ce8e07bbe6d783David Howells struct element *ec; 13724520c6a49af833c83de6c74525ce8e07bbe6d783David Howells const char *cond, *act; 13734520c6a49af833c83de6c74525ce8e07bbe6d783David Howells int entry, skippable = 0, outofline = 0; 13744520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 13754520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (e->flags & ELEMENT_SKIPPABLE || 13764520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (tag && tag->flags & ELEMENT_SKIPPABLE)) 13774520c6a49af833c83de6c74525ce8e07bbe6d783David Howells skippable = 1; 13784520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 13794520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if ((e->type_def && e->type_def->ref_count > 1) || 13804520c6a49af833c83de6c74525ce8e07bbe6d783David Howells skippable) 13814520c6a49af833c83de6c74525ce8e07bbe6d783David Howells outofline = 1; 13824520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 13834520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (e->type_def && out) { 13844520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_more(out, "\t// %*.*s\n", 13854520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (int)e->type_def->name->size, (int)e->type_def->name->size, 13864520c6a49af833c83de6c74525ce8e07bbe6d783David Howells e->type_def->name->value); 13874520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 13884520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 13894520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* Render the operation */ 13904520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cond = (e->flags & ELEMENT_CONDITIONAL || 13914520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (tag && tag->flags & ELEMENT_CONDITIONAL)) ? "COND_" : ""; 13924520c6a49af833c83de6c74525ce8e07bbe6d783David Howells act = e->action ? "_ACT" : ""; 13934520c6a49af833c83de6c74525ce8e07bbe6d783David Howells switch (e->compound) { 13944520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case ANY: 13954520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(out, "ASN1_OP_%sMATCH_ANY%s,", cond, act); 13964520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (e->name) 13974520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_more(out, "\t\t// %*.*s", 13984520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (int)e->name->size, (int)e->name->size, 13994520c6a49af833c83de6c74525ce8e07bbe6d783David Howells e->name->value); 14004520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_more(out, "\n"); 14014520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto dont_render_tag; 14024520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 14034520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case TAG_OVERRIDE: 14044520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_element(out, e->children, e); 14054520c6a49af833c83de6c74525ce8e07bbe6d783David Howells return; 14064520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 14074520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case SEQUENCE: 14084520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case SEQUENCE_OF: 14094520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case SET: 14104520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case SET_OF: 14114520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(out, "ASN1_OP_%sMATCH%s%s,", 14124520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cond, 14134520c6a49af833c83de6c74525ce8e07bbe6d783David Howells outofline ? "_JUMP" : "", 14144520c6a49af833c83de6c74525ce8e07bbe6d783David Howells skippable ? "_OR_SKIP" : ""); 14154520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 14164520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 14174520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case CHOICE: 14184520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto dont_render_tag; 14194520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 14204520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case TYPE_REF: 14214520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (e->class == ASN1_UNIV && e->method == ASN1_PRIM && e->tag == 0) 14224520c6a49af833c83de6c74525ce8e07bbe6d783David Howells goto dont_render_tag; 14234520c6a49af833c83de6c74525ce8e07bbe6d783David Howells default: 14244520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(out, "ASN1_OP_%sMATCH%s%s,", 14254520c6a49af833c83de6c74525ce8e07bbe6d783David Howells cond, act, 14264520c6a49af833c83de6c74525ce8e07bbe6d783David Howells skippable ? "_OR_SKIP" : ""); 14274520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 14284520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 14294520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 14304520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (e->name) 14314520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_more(out, "\t\t// %*.*s", 14324520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (int)e->name->size, (int)e->name->size, 14334520c6a49af833c83de6c74525ce8e07bbe6d783David Howells e->name->value); 14344520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_more(out, "\n"); 14354520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 14364520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* Render the tag */ 14374520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (!tag) 14384520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tag = e; 14394520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (tag->class == ASN1_UNIV && 14404520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tag->tag != 14 && 14414520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tag->tag != 15 && 14424520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tag->tag != 31) 14434520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(out, "_tag(%s, %s, %s),\n", 14444520c6a49af833c83de6c74525ce8e07bbe6d783David Howells asn1_classes[tag->class], 14454520c6a49af833c83de6c74525ce8e07bbe6d783David Howells asn1_methods[tag->method | e->method], 14464520c6a49af833c83de6c74525ce8e07bbe6d783David Howells asn1_universal_tags[tag->tag]); 14474520c6a49af833c83de6c74525ce8e07bbe6d783David Howells else 14484520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(out, "_tagn(%s, %s, %2u),\n", 14494520c6a49af833c83de6c74525ce8e07bbe6d783David Howells asn1_classes[tag->class], 14504520c6a49af833c83de6c74525ce8e07bbe6d783David Howells asn1_methods[tag->method | e->method], 14514520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tag->tag); 14524520c6a49af833c83de6c74525ce8e07bbe6d783David Howells tag = NULL; 14534520c6a49af833c83de6c74525ce8e07bbe6d783David Howellsdont_render_tag: 14544520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 14554520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* Deal with compound types */ 14564520c6a49af833c83de6c74525ce8e07bbe6d783David Howells switch (e->compound) { 14574520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case TYPE_REF: 14584520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_element(out, e->type->type->element, tag); 14594520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (e->action) 14604520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(out, "ASN1_OP_ACT,\n"); 14614520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 14624520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 14634520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case SEQUENCE: 14644520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (outofline) { 14654520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* Render out-of-line for multiple use or 14664520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * skipability */ 14674520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(out, "_jump_target(%u),", e->entry_index); 14684520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (e->type_def && e->type_def->name) 14694520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_more(out, "\t\t// --> %*.*s", 14704520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (int)e->type_def->name->size, 14714520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (int)e->type_def->name->size, 14724520c6a49af833c83de6c74525ce8e07bbe6d783David Howells e->type_def->name->value); 14734520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_more(out, "\n"); 14744520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (!(e->flags & ELEMENT_RENDERED)) { 14754520c6a49af833c83de6c74525ce8e07bbe6d783David Howells e->flags |= ELEMENT_RENDERED; 14764520c6a49af833c83de6c74525ce8e07bbe6d783David Howells *render_list_p = e; 14774520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_list_p = &e->render_next; 14784520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 14794520c6a49af833c83de6c74525ce8e07bbe6d783David Howells return; 14804520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } else { 14814520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* Render inline for single use */ 14824520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_depth++; 14834520c6a49af833c83de6c74525ce8e07bbe6d783David Howells for (ec = e->children; ec; ec = ec->next) 14844520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_element(out, ec, NULL); 14854520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_depth--; 14864520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(out, "ASN1_OP_END_SEQ%s,\n", act); 14874520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 14884520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 14894520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 14904520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case SEQUENCE_OF: 14914520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case SET_OF: 14924520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (outofline) { 14934520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* Render out-of-line for multiple use or 14944520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * skipability */ 14954520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(out, "_jump_target(%u),", e->entry_index); 14964520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (e->type_def && e->type_def->name) 14974520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_more(out, "\t\t// --> %*.*s", 14984520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (int)e->type_def->name->size, 14994520c6a49af833c83de6c74525ce8e07bbe6d783David Howells (int)e->type_def->name->size, 15004520c6a49af833c83de6c74525ce8e07bbe6d783David Howells e->type_def->name->value); 15014520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_more(out, "\n"); 15024520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (!(e->flags & ELEMENT_RENDERED)) { 15034520c6a49af833c83de6c74525ce8e07bbe6d783David Howells e->flags |= ELEMENT_RENDERED; 15044520c6a49af833c83de6c74525ce8e07bbe6d783David Howells *render_list_p = e; 15054520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_list_p = &e->render_next; 15064520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 15074520c6a49af833c83de6c74525ce8e07bbe6d783David Howells return; 15084520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } else { 15094520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* Render inline for single use */ 15104520c6a49af833c83de6c74525ce8e07bbe6d783David Howells entry = nr_entries; 15114520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_depth++; 15124520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_element(out, e->children, NULL); 15134520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_depth--; 15144520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (e->compound == SEQUENCE_OF) 15154520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(out, "ASN1_OP_END_SEQ_OF%s,\n", act); 15164520c6a49af833c83de6c74525ce8e07bbe6d783David Howells else 15174520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(out, "ASN1_OP_END_SET_OF%s,\n", act); 15184520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(out, "_jump_target(%u),\n", entry); 15194520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 15204520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 15214520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 15224520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case SET: 15234520c6a49af833c83de6c74525ce8e07bbe6d783David Howells /* I can't think of a nice way to do SET support without having 15244520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * a stack of bitmasks to make sure no element is repeated. 15254520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * The bitmask has also to be checked that no non-optional 15264520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * elements are left out whilst not preventing optional 15274520c6a49af833c83de6c74525ce8e07bbe6d783David Howells * elements from being left out. 15284520c6a49af833c83de6c74525ce8e07bbe6d783David Howells */ 15294520c6a49af833c83de6c74525ce8e07bbe6d783David Howells fprintf(stderr, "The ASN.1 SET type is not currently supported.\n"); 15304520c6a49af833c83de6c74525ce8e07bbe6d783David Howells exit(1); 15314520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 15324520c6a49af833c83de6c74525ce8e07bbe6d783David Howells case CHOICE: 15334520c6a49af833c83de6c74525ce8e07bbe6d783David Howells for (ec = e->children; ec; ec = ec->next) 15344520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_element(out, ec, NULL); 15354520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (!skippable) 15364520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(out, "ASN1_OP_COND_FAIL,\n"); 15374520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (e->action) 15384520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(out, "ASN1_OP_ACT,\n"); 15394520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 15404520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 15414520c6a49af833c83de6c74525ce8e07bbe6d783David Howells default: 15424520c6a49af833c83de6c74525ce8e07bbe6d783David Howells break; 15434520c6a49af833c83de6c74525ce8e07bbe6d783David Howells } 15444520c6a49af833c83de6c74525ce8e07bbe6d783David Howells 15454520c6a49af833c83de6c74525ce8e07bbe6d783David Howells if (e->action) 15464520c6a49af833c83de6c74525ce8e07bbe6d783David Howells render_opcode(out, "_action(ACT_%s),\n", e->action->name); 15474520c6a49af833c83de6c74525ce8e07bbe6d783David Howells} 1548