diff options
author | Yabin Cui <yabinc@google.com> | 2020-07-07 15:56:34 -0700 |
---|---|---|
committer | Yabin Cui <yabinc@google.com> | 2020-07-08 15:02:56 -0700 |
commit | acbdb2456da4837a143d096a8a0563ba1dfc0507 (patch) | |
tree | 9e07abefafc96e76fb9b065264fb67cb78c0d9ad /simpleperf/command.h | |
parent | 4f6808ce8d0a10cb4c8588ddd7ed275001da3154 (diff) | |
download | extras-acbdb2456da4837a143d096a8a0563ba1dfc0507.tar.gz |
simpleperf: add function to preprocess options.
Add Command::PreprocessOptions() to extracts options from the
argument list. It splits options into different types. Instead of
replying on the order in the argument list, it allows a command
choosing the order to process each option.
Also put whole command.h in simpleperf namespace.
Bug: 160701181
Test: run simpleperf_unit_test.
Change-Id: I9b20e21a94797c322c1371cbe1704b3e2ce1be28
Diffstat (limited to 'simpleperf/command.h')
-rw-r--r-- | simpleperf/command.h | 100 |
1 files changed, 97 insertions, 3 deletions
diff --git a/simpleperf/command.h b/simpleperf/command.h index fe71a31a..2f0a038c 100644 --- a/simpleperf/command.h +++ b/simpleperf/command.h @@ -18,15 +18,103 @@ #define SIMPLE_PERF_COMMAND_H_ #include <functional> -#include <memory> #include <limits> +#include <map> +#include <memory> +#include <optional> #include <string> +#include <unordered_map> #include <vector> #include <android-base/logging.h> #include <android-base/macros.h> #include <android-base/parseint.h> +namespace simpleperf { + +using OptionName = std::string; + +enum class OptionType { + SINGLE, // this option has a single value (use the last one in the arg list) + MULTIPLE, // this option can have multiple values (keep all values appeared in the arg list) + ORDERED, // keep the order of this option in the arg list +}; + +enum class OptionValueType { + NONE, // No value is needed + STRING, + OPT_STRING, // optional string + UINT, + DOUBLE, +}; + +struct OptionFormat { + OptionValueType value_type; + OptionType type; +}; + +union OptionValue { + const std::string* str_value; + uint64_t uint_value; + double double_value; +}; + +struct OptionValueMap { + std::multimap<OptionName, OptionValue> values; + + bool PullBoolValue(const OptionName& name) { + return PullValue(name).has_value(); + } + + template <typename T> + bool PullUintValue(const OptionName& name, T* value, uint64_t min = 0, + uint64_t max = std::numeric_limits<T>::max()) { + if (auto option_value = PullValue(name); option_value) { + if (option_value->uint_value < min || option_value->uint_value > max) { + LOG(ERROR) << "invalid " << name << ": " << option_value->uint_value; + return false; + } + *value = option_value->uint_value; + } + return true; + } + + bool PullDoubleValue(const OptionName& name, double* value, + double min = std::numeric_limits<double>::lowest(), + double max = std::numeric_limits<double>::max()) { + if (auto option_value = PullValue(name); option_value) { + if (option_value->double_value < min || option_value->double_value > max) { + LOG(ERROR) << "invalid " << name << ": " << option_value->double_value; + return false; + } + *value = option_value->double_value; + } + return true; + } + + std::optional<OptionValue> PullValue(const OptionName& name) { + std::optional<OptionValue> res; + if (auto it = values.find(name); it != values.end()) { + res.emplace(it->second); + values.erase(it); + } + return res; + } + + std::optional<std::vector<OptionValue>> PullValues(const OptionName& name) { + auto pair = values.equal_range(name); + if (pair.first != pair.second) { + std::vector<OptionValue> res; + for (auto it = pair.first; it != pair.second; ++it) { + res.emplace_back(it->second); + } + values.erase(name); + return res; + } + return {}; + } +}; + class Command { public: Command(const std::string& name, const std::string& short_help_string, @@ -51,6 +139,12 @@ class Command { virtual bool Run(const std::vector<std::string>& args) = 0; + bool PreprocessOptions(const std::vector<std::string>& args, + const std::unordered_map<OptionName, OptionFormat>& option_formats, + OptionValueMap* options, + std::vector<std::pair<OptionName, OptionValue>>* ordered_options, + std::vector<std::string>* non_option_args = nullptr); + template <typename T> bool GetUintOption(const std::vector<std::string>& args, size_t* pi, T* value, uint64_t min = 0, uint64_t max = std::numeric_limits<T>::max(), bool allow_suffixes = false) { @@ -88,8 +182,8 @@ std::unique_ptr<Command> CreateCommandInstance(const std::string& cmd_name); const std::vector<std::string> GetAllCommandNames(); bool RunSimpleperfCmd(int argc, char** argv); -namespace simpleperf { extern bool log_to_android_buffer; -} + +} // namespace simpleperf #endif // SIMPLE_PERF_COMMAND_H_ |