1 // Copyright (C) 2018 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef VERSION_SCRIPT_PARSER_H_ 16 #define VERSION_SCRIPT_PARSER_H_ 17 18 #include "repr/ir_representation.h" 19 #include "repr/symbol/exported_symbol_set.h" 20 #include "utils/api_level.h" 21 22 #include <functional> 23 #include <set> 24 #include <string> 25 26 27 namespace header_checker { 28 namespace repr { 29 30 31 class VersionScriptParser { 32 private: 33 enum class LineScope { 34 GLOBAL, 35 LOCAL, 36 }; 37 38 39 struct ParsedTags { 40 public: 41 unsigned has_arch_tags_ : 1; 42 unsigned has_current_arch_tag_ : 1; 43 unsigned has_introduced_tags_ : 1; 44 unsigned has_excluded_tags_ : 1; 45 unsigned has_future_tag_ : 1; 46 unsigned has_var_tag_ : 1; 47 unsigned has_weak_tag_ : 1; 48 utils::ApiLevel introduced_; 49 50 51 public: ParsedTagsParsedTags52 ParsedTags() 53 : has_arch_tags_(0), has_current_arch_tag_(0), has_introduced_tags_(0), 54 has_excluded_tags_(0), has_future_tag_(0), has_var_tag_(0), 55 introduced_(-1) {} 56 }; 57 58 59 public: 60 class ErrorHandler { 61 public: 62 virtual ~ErrorHandler(); 63 64 virtual void OnError(int line_no, const std::string &error_msg) = 0; 65 }; 66 67 68 public: 69 VersionScriptParser(); 70 71 void SetArch(const std::string &arch); 72 SetApiLevel(utils::ApiLevel api_level)73 void SetApiLevel(utils::ApiLevel api_level) { 74 api_level_ = api_level; 75 } 76 AddExcludedSymbolVersion(const std::string & version)77 void AddExcludedSymbolVersion(const std::string &version) { 78 excluded_symbol_versions_.insert(version); 79 } 80 AddExcludedSymbolTag(const std::string & tag)81 void AddExcludedSymbolTag(const std::string &tag) { 82 excluded_symbol_tags_.insert(tag); 83 } 84 SetErrorHandler(std::unique_ptr<ErrorHandler> error_handler)85 void SetErrorHandler(std::unique_ptr<ErrorHandler> error_handler) { 86 error_handler_ = std::move(error_handler); 87 } 88 89 std::unique_ptr<ExportedSymbolSet> Parse(std::istream &version_script_stream); 90 91 92 private: 93 bool ReadLine(std::string &line); 94 95 bool ParseVersionBlock(bool ignore_symbols); 96 97 bool ParseSymbolLine(const std::string &line, bool is_cpp_symbol); 98 99 ParsedTags ParseSymbolTags(const std::string &line); 100 101 bool IsSymbolExported(const ParsedTags &tags); 102 103 104 private: ReportError(const std::string & error_msg)105 void ReportError(const std::string &error_msg) { 106 if (error_handler_) { 107 error_handler_->OnError(line_no_, error_msg); 108 } 109 } 110 111 112 private: 113 std::unique_ptr<ErrorHandler> error_handler_; 114 115 std::string arch_; 116 std::string introduced_arch_tag_; 117 utils::ApiLevel api_level_; 118 119 std::set<std::string, std::less<>> excluded_symbol_versions_; 120 std::set<std::string, std::less<>> excluded_symbol_tags_; 121 122 std::istream *stream_; 123 int line_no_; 124 125 std::unique_ptr<ExportedSymbolSet> exported_symbols_; 126 }; 127 128 129 } // namespace repr 130 } // namespace header_checker 131 132 133 #endif // VERSION_SCRIPT_PARSER_H_ 134