blob: 191aab624eec2110109df49920151b57dcf7535d [file] [log] [blame]
// 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_