1/* 2 * Copyright (c) 2007,2011-2012 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#include "antlrplugin.h" 25#include "cserror.h" 26#include "RequirementLexer.hpp" 27#include "RequirementParser.hpp" 28#include <antlr/TokenStreamException.hpp> 29 30 31namespace Security { 32namespace CodeSigning { 33 34namespace Parser = Security_CodeSigning; 35 36 37// 38// Lexer input adapters 39// 40class StdioInputStream : public antlr::InputBuffer { 41public: 42 StdioInputStream(FILE *fp) : mFile(fp) { } 43 int getChar() { return fgetc(mFile); } 44 45private: 46 FILE *mFile; 47}; 48 49class StringInputStream : public antlr::InputBuffer { 50public: 51 StringInputStream(const string &s) : mInput(s), mPos(mInput.begin()) { } 52 int getChar() { return (mPos == mInput.end()) ? EOF : *mPos++; } 53 54private: 55 string mInput; 56 string::const_iterator mPos; 57}; 58 59 60// 61// Generic parser driver 62// 63template <class Input, class Source, class Result> 64const Result *parse(Source source, Result *(Parser::RequirementParser::*rule)(), std::string &errors) 65{ 66 Input input(source); 67 Parser::RequirementLexer lexer(input); 68 Parser::RequirementParser parser(lexer); 69 try { 70 const Result *result = (parser.*rule)(); 71 errors = parser.errors; 72 if (errors.empty()) 73 return result; 74 else 75 ::free((void *)result); 76 } catch (const antlr::TokenStreamException &ex) { 77 errors = ex.toString() + "\n"; 78 } 79 return NULL; // signal failure 80} 81 82 83// 84// Hook up each supported parsing action to the plugin interface 85// 86static 87const Requirement *fileRequirement(FILE *source, string &errors) 88{ return parse<StdioInputStream>(source, &Parser::RequirementParser::requirement, errors); } 89 90static 91const Requirement *stringRequirement(string source, string &errors) 92{ return parse<StringInputStream>(source, &Parser::RequirementParser::requirement, errors); } 93 94static 95const Requirements *fileRequirements(FILE *source, string &errors) 96{ return parse<StdioInputStream>(source, &Parser::RequirementParser::requirementSet, errors); } 97 98static 99const Requirements *stringRequirements(string source, string &errors) 100{ return parse<StringInputStream>(source, &Parser::RequirementParser::requirementSet, errors); } 101 102static 103const BlobCore *fileGeneric(FILE *source, string &errors) 104{ return parse<StdioInputStream>(source, &Parser::RequirementParser::autosense, errors); } 105 106static 107const BlobCore *stringGeneric(string source, string &errors) 108{ return parse<StringInputStream>(source, &Parser::RequirementParser::autosense, errors); } 109 110 111// 112// Basic plugin hookup 113// 114static AntlrPlugin plugin = { 115 fileRequirement, 116 fileRequirements, 117 fileGeneric, 118 stringRequirement, 119 stringRequirements, 120 stringGeneric 121}; 122 123AntlrPlugin *findAntlrPlugin() 124{ 125 return &plugin; 126} 127 128 129} // end namespace CodeSigning 130} // end namespace Security 131