antlrplugin.cpp
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 31 namespace Security { 32 namespace CodeSigning { 33 34 namespace Parser = Security_CodeSigning; 35 36 37 // 38 // Lexer input adapters 39 // 40 class StdioInputStream : public antlr::InputBuffer { 41 public: 42 StdioInputStream(FILE *fp) : mFile(fp) { } 43 int getChar() { return fgetc(mFile); } 44 45 private: 46 FILE *mFile; 47 }; 48 49 class StringInputStream : public antlr::InputBuffer { 50 public: 51 StringInputStream(const string &s) : mInput(s), mPos(mInput.begin()) { } 52 int getChar() { return (mPos == mInput.end()) ? EOF : static_cast<unsigned char>(*mPos++); } 53 54 private: 55 string mInput; 56 string::const_iterator mPos; 57 }; 58 59 60 // 61 // Generic parser driver 62 // 63 template <class Input, class Source, class Result> 64 const 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 // 86 static 87 const Requirement *fileRequirement(FILE *source, string &errors) 88 { return parse<StdioInputStream>(source, &Parser::RequirementParser::requirement, errors); } 89 90 static 91 const Requirement *stringRequirement(string source, string &errors) 92 { return parse<StringInputStream>(source, &Parser::RequirementParser::requirement, errors); } 93 94 static 95 const Requirements *fileRequirements(FILE *source, string &errors) 96 { return parse<StdioInputStream>(source, &Parser::RequirementParser::requirementSet, errors); } 97 98 static 99 const Requirements *stringRequirements(string source, string &errors) 100 { return parse<StringInputStream>(source, &Parser::RequirementParser::requirementSet, errors); } 101 102 static 103 const BlobCore *fileGeneric(FILE *source, string &errors) 104 { return parse<StdioInputStream>(source, &Parser::RequirementParser::autosense, errors); } 105 106 static 107 const BlobCore *stringGeneric(string source, string &errors) 108 { return parse<StringInputStream>(source, &Parser::RequirementParser::autosense, errors); } 109 110 111 // 112 // Basic plugin hookup 113 // 114 static AntlrPlugin plugin = { 115 fileRequirement, 116 fileRequirements, 117 fileGeneric, 118 stringRequirement, 119 stringRequirements, 120 stringGeneric 121 }; 122 123 AntlrPlugin *findAntlrPlugin() 124 { 125 return &plugin; 126 } 127 128 129 } // end namespace CodeSigning 130 } // end namespace Security