| // Copyright 2017-2020 The Verible Authors. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #ifndef VERIBLE_COMMON_UTIL_SUBCOMMAND_H_ |
| #define VERIBLE_COMMON_UTIL_SUBCOMMAND_H_ |
| |
| #include <functional> |
| #include <iosfwd> |
| #include <map> |
| #include <string> |
| #include <vector> |
| |
| #include "absl/status/status.h" |
| #include "absl/strings/string_view.h" |
| #include "common/strings/compare.h" |
| #include "common/util/container_iterator_range.h" |
| |
| namespace verible { |
| |
| // This should be the same type returned by InitCommandLine in |
| // common/util/init_command_line.h |
| using SubcommandArgs = std::vector<char*>; |
| using SubcommandArgsIterator = SubcommandArgs::const_iterator; |
| using SubcommandArgsRange = |
| verible::container_iterator_range<SubcommandArgsIterator>; |
| |
| // Currently this function type is hard-coded, but this could eventually |
| // become a template parameter. |
| using SubcommandFunction = |
| std::function<absl::Status(const SubcommandArgsRange&, std::istream& ins, |
| std::ostream& outs, std::ostream& errs)>; |
| |
| // Represents a function selected by the user. |
| struct SubcommandEntry { |
| SubcommandEntry(SubcommandFunction fun, absl::string_view usage, |
| bool show_in_help = true) |
| : main(fun), usage(usage), show_in_help(show_in_help) {} |
| |
| // sub-main function |
| const SubcommandFunction main; |
| |
| // maybe a const std::string 'brief' for a half-line description |
| |
| // full description of command |
| const std::string usage; |
| |
| // If true, display this subcommand in 'help'. |
| const bool show_in_help; |
| }; |
| |
| // SubcommandRegistry is a structure for holding a map of functions. |
| class SubcommandRegistry { |
| public: |
| SubcommandRegistry(); |
| |
| // Not intended for copy/move-ing. |
| SubcommandRegistry(const SubcommandRegistry&) = delete; |
| SubcommandRegistry(SubcommandRegistry&&) = delete; |
| SubcommandRegistry& operator=(const SubcommandRegistry&) = delete; |
| SubcommandRegistry& operator=(SubcommandRegistry&&) = delete; |
| |
| // Add a function to this map. |
| // Returned status is an error if a function already exists with the given |
| // name. |
| absl::Status RegisterCommand(absl::string_view name, const SubcommandEntry&); |
| |
| // Lookup a function in this map by name. |
| const SubcommandEntry& GetSubcommandEntry(absl::string_view command) const; |
| |
| // Print a help summary of all registered commands. |
| std::string ListCommands() const; |
| |
| protected: |
| // Every command map comes with a built-in 'help' command. |
| absl::Status Help(const SubcommandArgsRange& args, std::istream&, |
| std::ostream&, std::ostream& errs) const; |
| |
| private: |
| using SubcommandMap = |
| std::map<std::string, SubcommandEntry, StringViewCompare>; |
| |
| // The map of names to functions. |
| SubcommandMap subcommand_map_; |
| }; // class SubcommandRegistry |
| |
| } // namespace verible |
| |
| #endif // VERIBLE_COMMON_UTIL_SUBCOMMAND_H_ |