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 <map> 24 #include <string> 25 26 27 namespace header_checker { 28 namespace repr { 29 30 31 enum ModeTagPolicy { 32 MatchTagAndApi, 33 MatchTagOnly, 34 }; 35 36 class VersionScriptParser { 37 private: 38 // This comparison function allows finding elements by string_view. 39 using ModeTagLevelMap = std::map<std::string, utils::ApiLevel, std::less<>>; 40 41 enum class LineScope { 42 GLOBAL, 43 LOCAL, 44 }; 45 46 struct ParsedTags { 47 public: 48 unsigned has_arch_tags_ : 1; 49 unsigned has_current_arch_tag_ : 1; 50 unsigned has_introduced_tags_ : 1; 51 unsigned has_excluded_tags_ : 1; 52 unsigned has_future_tag_ : 1; 53 unsigned has_var_tag_ : 1; 54 unsigned has_weak_tag_ : 1; 55 utils::ApiLevel introduced_; 56 ModeTagLevelMap mode_tags_; 57 58 public: ParsedTagsParsedTags59 ParsedTags() 60 : has_arch_tags_(0), has_current_arch_tag_(0), has_introduced_tags_(0), 61 has_excluded_tags_(0), has_future_tag_(0), has_var_tag_(0), 62 introduced_(-1) {} 63 }; 64 65 66 public: 67 class ErrorHandler { 68 public: 69 virtual ~ErrorHandler(); 70 71 virtual void OnError(int line_no, const std::string &error_msg) = 0; 72 }; 73 74 75 public: 76 VersionScriptParser(); 77 78 void SetArch(const std::string &arch); 79 SetApiLevel(utils::ApiLevel api_level)80 void SetApiLevel(utils::ApiLevel api_level) { 81 api_level_ = api_level; 82 } 83 84 void SetApiLevelMap(utils::ApiLevelMap api_level_map); 85 AddExcludedSymbolVersion(const std::string & version)86 void AddExcludedSymbolVersion(const std::string &version) { 87 excluded_symbol_versions_.insert(version); 88 } 89 AddExcludedSymbolTag(const std::string & tag)90 void AddExcludedSymbolTag(const std::string &tag) { 91 excluded_symbol_tags_.insert(tag); 92 } 93 94 // Returns whether the argument is valid. 95 bool AddModeTag(std::string_view mode_tag); 96 SetModeTagPolicy(ModeTagPolicy policy)97 void SetModeTagPolicy(ModeTagPolicy policy) { mode_tag_policy_ = policy; } 98 SetErrorHandler(std::unique_ptr<ErrorHandler> error_handler)99 void SetErrorHandler(std::unique_ptr<ErrorHandler> error_handler) { 100 error_handler_ = std::move(error_handler); 101 } 102 103 std::unique_ptr<ExportedSymbolSet> Parse(std::istream &version_script_stream); 104 105 106 private: 107 bool ReadLine(std::string &line); 108 109 bool ParseVersionBlock(bool ignore_symbols, const ParsedTags &tags); 110 111 bool ParseSymbolLine(const std::string &line, bool is_cpp_symbol, 112 const ParsedTags &version_block_tags); 113 114 ParsedTags ParseSymbolTags(const std::string &line, 115 const ParsedTags &initial_value); 116 117 bool MatchModeTags(const ParsedTags &tags); 118 119 bool MatchIntroducedTags(const ParsedTags &tags); 120 121 bool IsSymbolExported(const ParsedTags &tags); 122 123 124 private: ReportError(const std::string & error_msg)125 void ReportError(const std::string &error_msg) { 126 if (error_handler_) { 127 error_handler_->OnError(line_no_, error_msg); 128 } 129 } 130 131 132 private: 133 std::unique_ptr<ErrorHandler> error_handler_; 134 135 std::string arch_; 136 std::string introduced_arch_tag_; 137 utils::ApiLevel api_level_; 138 utils::ApiLevelMap api_level_map_; 139 140 utils::StringSet excluded_symbol_versions_; 141 utils::StringSet excluded_symbol_tags_; 142 ModeTagLevelMap included_mode_tags_; 143 ModeTagPolicy mode_tag_policy_; 144 145 std::istream *stream_; 146 int line_no_; 147 148 std::unique_ptr<ExportedSymbolSet> exported_symbols_; 149 }; 150 151 152 } // namespace repr 153 } // namespace header_checker 154 155 156 #endif // VERSION_SCRIPT_PARSER_H_ 157