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