• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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