1/* 2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 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// Autogenerated file -- DO NOT EDIT! 16 17#ifndef PANDA_<%= Common::module.name.upcase %>_OPTIONS_GEN_H 18#define PANDA_<%= Common::module.name.upcase %>_OPTIONS_GEN_H 19 20#include "utils/pandargs.h" 21#include "platforms/target_defaults/default_target_options.h" 22#include "macros.h" 23 24#include <optional> 25#include <string> 26#include <unordered_set> 27#include <vector> 28 29namespace <%= Common::module.namespace %> { 30% Common::options.select { |op| op.has_enum? }.each do |op| 31namespace <%= op.camel_name.snakecase %> { 32enum Enum : size_t { 33% op.flat_enum.each do |enumerator| 34 <%= enumerator.snakecase.upcase %>, 35% end 36% op.sub_enums.each do |name, sub_enum| 37 <%= name.snakecase.upcase %>_FIRST = <%= sub_enum[0].snakecase.upcase %>, 38 <%= name.snakecase.upcase %>_LAST = <%= sub_enum[-1].snakecase.upcase %>, 39% end 40 FIRST = <%= op.flat_enum[0].snakecase.upcase %>, 41 LAST = <%= op.flat_enum[-1].snakecase.upcase %>, 42 COUNT = LAST - FIRST + 1, 43 INVALID = COUNT, 44}; 45 46inline auto FromString(std::string_view str) { 47 static const std::map<std::string_view, Enum> MAP { 48% op.flat_enum.each do |enumerator| 49 {"<%= enumerator %>", <%= enumerator.snakecase.upcase %>}, 50% end 51 }; 52 if (MAP.find(str) == MAP.end()) { 53 return INVALID; 54 } 55 return MAP.at(str); 56} 57 58constexpr std::string_view ToString(Enum e) { 59 constexpr std::array<std::string_view, COUNT> MAP { 60% op.flat_enum.each do |enumerator| 61 "<%= enumerator %>", 62% end 63 }; 64 return MAP[e]; 65} 66 67} // namespace <%= op.camel_name.snakecase %> 68 69% end 70// NOLINTBEGIN(readability-identifier-naming) 71class PANDA_PUBLIC_API Options { 72public: 73 class Error { 74 public: 75 explicit Error(std::string msg) : msg_(std::move(msg)) {} 76 77 std::string GetMessage() { 78 return msg_; 79 } 80 private: 81 std::string msg_; 82 }; 83 84 explicit Options(const std::string &exe_path) : 85 exe_dir_(GetExeDir(exe_path)) 86% Common::options.each do |op| 87% next if op.sub_option? 88% next if op.deprecated? 89% if op.default_target_specific? 90 ,<%= op.field_name %>{"<%= op.name %>", <%= op.default_value %>, <%= op.full_description %>} 91% end 92% end 93 {} 94 95 // NOLINTBEGIN(readability-function-size) 96 void AddOptions(PandArgParser *parser) { 97 parser->Add(&version_); 98% Common::options.each do |op| 99% next if op.sub_option? 100% next if op.deprecated? 101 parser->Add(&<%= op.field_name %>); 102% end 103 } 104 // NOLINTEND(readability-function-size) 105 106 bool IsVersion() const { 107 return version_.GetValue(); 108 } 109 110 void SetVersion(bool value) { 111 version_.SetValue(value); 112 } 113 114 bool WasSetVersion() { 115 return version_.WasSet(); 116 } 117 118% Common::options.each do |op| 119% if !op.lang_specific? && !op.has_lang_suboptions? 120 <%= op.getter_signature %> { 121% if op.deprecated? 122 std::cerr << "WARNING: Option '<%= op.name %>' is deprecated and should not be used\n"; 123% end 124 return <%= op.field_name %>.GetValue(); 125 } 126 127 void <%= op.setter_name %>(<%= op.type %> value) { 128% if op.deprecated? 129 std::cerr << "WARNING: Option '<%= op.name %>' is deprecated and should not be used\n"; 130% end 131 <%= op.field_name %>.SetValue(<%= op.type == 'std::string' || op.type == 'arg_list_t' ? 'std::move(value)' : 'value' %>); 132 } 133 134 bool WasSet<%= op.camel_name %>([[maybe_unused]] std::string_view lang = "") const { 135% if op.deprecated? 136 std::cerr << "WARNING: Option '<%= op.name %>' is deprecated and should not be used\n"; 137% end 138 return <%= op.field_name %>.WasSet(); 139 } 140% end 141% if op.has_lang_suboptions? 142 <%= op.getter_signature %> { 143% if op.deprecated? 144 std::cerr << "WARNING: Option '<%= op.name %>' is deprecated and should not be used\n"; 145% end 146% op.lang.each do |lang| 147 if (lang == "<%= "#{lang}" %>") { 148 return WasSet<%= op.lang_camel_name(lang) %>() ? <%= op.lang_field_name(lang) %>.GetValue() : <%= op.field_name %>.GetValue(); 149 } 150% end 151 return <%= op.field_name %>.GetValue(); 152 } 153 154 void <%= op.setter_name %>(<%= op.type %> value) { 155% if op.deprecated? 156 std::cerr << "WARNING: Option '<%= op.name %>' is deprecated and should not be used\n"; 157% end 158 <%= op.field_name %>.SetValue(<%= op.type == 'std::string' || op.type == 'arg_list_t' ? 'std::move(value)' : 'value' %>); 159 } 160 161 bool WasSet<%= op.camel_name %>(std::string_view lang) const { 162% if op.deprecated? 163 std::cerr << "WARNING: Option '<%= op.name %>' is deprecated and should not be used\n"; 164% end 165% op.lang.each do |lang| 166 if (lang == "<%= "#{lang}" %>") { 167 return <%= op.lang_field_name(lang) %>.WasSet(); 168 } 169% end 170 return <%= op.field_name %>.WasSet(); 171 } 172% end 173% end 174// NOLINTNEXTLINE(readability-function-size) 175 std::optional<Error> Validate() const { 176% Common::options.each do |op| 177% next unless defined? op.possible_values 178% is_string = op.type == 'std::string' || op.type == 'arg_list_t' 179% possible_values = op.possible_values.map { |e| is_string ? Common::to_raw(e) : e }.join(', ') 180 { 181 std::unordered_set<<%= is_string ? "std::string" : op.type %>> possible_values{<%= possible_values %>}; 182% if op.type != 'arg_list_t' 183 std::vector<<%= op.type %>> values{<%= op.field_name %>.GetValue()}; 184% else 185 const auto &values = <%= op.field_name %>.GetValue(); 186% end 187 for (const auto &value : values) { 188 if (possible_values.find(value) == possible_values.cend()) { 189 return Error("argument --<%= op.name %>: invalid value: '" + <%= is_string ? "value" : "std::to_string(value)" %> + \ 190 R"('. Possible values: <%= op.possible_values %>)"); 191 } 192 } 193 } 194% end 195 return {}; 196 } 197 198private: 199% Common::options.each do |op| 200% if op.lang_specific? 201 bool WasSet<%= op.camel_name %>() const { 202% if op.deprecated? 203 std::cerr << "WARNING: Option '<%= op.name %>' is deprecated and should not be used\n"; 204% end 205 return <%= op.field_name %>.WasSet(); 206 } 207% end 208% end 209 210 static std::string GetExeDir(const std::string &exe_path) { 211#ifdef PANDA_TARGET_WINDOWS 212 const char preferred_separator = '\\'; 213#else 214 const char preferred_separator = '/'; 215#endif 216 auto pos = exe_path.find_last_of(preferred_separator); 217 if (pos == std::string::npos) { 218 return "."; 219 } 220 return exe_path.substr(0, pos); 221 } 222 223% Common::options.each do |op| 224% next unless op.need_default_constant 225 static constexpr <%= op.type %> <%= op.default_constant_name %> = <%= op.default %>; 226 227% end 228 std::string exe_dir_; 229 PandArg<bool> version_{"version", false, R"(Ark version, file format version and minimum supported file format version)"}; 230% Common::options.each do |op| 231% if op.default_target_specific? 232 PandArg<<%= op.type %>> <%= op.field_name %>; 233% elsif defined? op.delimiter 234 PandArg<<%= op.type %>> <%= op.field_name %>{"<%= op.name %>", <%= op.default_value %>, <%= op.full_description %>, "<%= op.delimiter %>"}; 235% elsif defined? op.range 236% min, max = op.range.match('(\d+)\D*(\d+)').captures; 237% if op.default.to_i > max.to_i || op.default.to_i < min.to_i 238% abort "FAILED: Default value of argument " + op.name + " has out of range default parameter" 239% end 240 PandArg<<%= op.type %>> <%= op.field_name %>{"<%= op.name %>", <%= op.default_value %>, <%= op.full_description %>, <%= min.to_i %>, <%= max.to_i %>}; 241% elsif op.has_sub_options? 242 PandArgCompound <%= op.field_name %>{"<%= op.name %>", <%= op.full_description %>, {<%= op.sub_options.map{|o| '&' + o.field_name}.join(', ') %>}}; 243% else 244 PandArg<<%= op.type %>> <%= op.field_name %>{"<%= op.name %>", <%= op.default_value %>, <%= op.full_description %>}; 245% end 246% end 247}; 248// NOLINTEND(readability-identifier-naming) 249} // namespace <%= Common::module.namespace %> 250 251#endif // PANDA_<%= Common::module.name.upcase %>_OPTIONS_GEN_H 252