mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
[Support][CommandLine] Add cl::getRegisteredSubcommands()
This should allow users of the library to get a range to iterate through all the subcommands that are registered to the global parser. This allows users to define subcommands in libraries that self-register to have dispatch done at a different stage (like main). It allows for writing code like the following: for (auto *S : cl::getRegisteredSubcommands()) { if (*S) { // Dispatch on S->getName(). } } This change also contains tests that show this usage pattern. Reviewers: zturner, dblaikie, echristo Subscribers: llvm-commits, mehdi_amini Differential Revision: https://reviews.llvm.org/D24489 llvm-svn: 281290
This commit is contained in:
parent
c66bb3ef24
commit
7d7d82f567
@ -1736,6 +1736,28 @@ void PrintHelpMessage(bool Hidden = false, bool Categorized = false);
|
||||
/// than just handing around a global list.
|
||||
StringMap<Option *> &getRegisteredOptions(SubCommand &Sub = *TopLevelSubCommand);
|
||||
|
||||
/// \brief Use this to get all registered SubCommands from the provided parser.
|
||||
///
|
||||
/// \return A range of all SubCommand pointers registered with the parser.
|
||||
///
|
||||
/// Typical usage:
|
||||
/// \code
|
||||
/// main(int argc, char* argv[]) {
|
||||
/// llvm::cl::ParseCommandLineOptions(argc, argv);
|
||||
/// for (auto* S : llvm::cl::getRegisteredSubcommands()) {
|
||||
/// if (*S) {
|
||||
/// std::cout << "Executing subcommand: " << S->getName() << std::endl;
|
||||
/// // Execute some function based on the name...
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// \endcode
|
||||
///
|
||||
/// This interface is useful for defining subcommands in libraries and
|
||||
/// the dispatch from a single point (like in the main function).
|
||||
iterator_range<typename SmallPtrSet<SubCommand *, 4>::iterator>
|
||||
getRegisteredSubcommands();
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Standalone command line processing utilities.
|
||||
//
|
||||
|
@ -309,6 +309,12 @@ public:
|
||||
RegisteredSubCommands.erase(sub);
|
||||
}
|
||||
|
||||
iterator_range<typename SmallPtrSet<SubCommand *, 4>::iterator>
|
||||
getRegisteredSubcommands() {
|
||||
return make_range(RegisteredSubCommands.begin(),
|
||||
RegisteredSubCommands.end());
|
||||
}
|
||||
|
||||
void reset() {
|
||||
ActiveSubCommand = nullptr;
|
||||
ProgramName.clear();
|
||||
@ -2105,6 +2111,11 @@ StringMap<Option *> &cl::getRegisteredOptions(SubCommand &Sub) {
|
||||
return Sub.OptionsMap;
|
||||
}
|
||||
|
||||
iterator_range<typename SmallPtrSet<SubCommand *, 4>::iterator>
|
||||
cl::getRegisteredSubcommands() {
|
||||
return GlobalParser->getRegisteredSubcommands();
|
||||
}
|
||||
|
||||
void cl::HideUnrelatedOptions(cl::OptionCategory &Category, SubCommand &Sub) {
|
||||
for (auto &I : Sub.OptionsMap) {
|
||||
if (I.second->Category != &Category &&
|
||||
|
@ -476,4 +476,27 @@ TEST(CommandLineTest, RemoveFromAllSubCommands) {
|
||||
EXPECT_FALSE(cl::ParseCommandLineOptions(3, args2, nullptr, true));
|
||||
}
|
||||
|
||||
TEST(CommandLineTest, GetRegisteredSubcommands) {
|
||||
cl::ResetCommandLineParser();
|
||||
|
||||
StackSubCommand SC1("sc1", "First Subcommand");
|
||||
StackSubCommand SC2("sc2", "Second subcommand");
|
||||
|
||||
const char *args0[] = {"prog", "sc1"};
|
||||
const char *args1[] = {"prog", "sc2"};
|
||||
|
||||
EXPECT_TRUE(cl::ParseCommandLineOptions(2, args0, nullptr, true));
|
||||
for (auto *S : cl::getRegisteredSubcommands()) {
|
||||
if (*S)
|
||||
EXPECT_STREQ("sc1", S->getName());
|
||||
}
|
||||
|
||||
cl::ResetAllOptionOccurrences();
|
||||
EXPECT_TRUE(cl::ParseCommandLineOptions(2, args1, nullptr, true));
|
||||
for (auto *S : cl::getRegisteredSubcommands()) {
|
||||
if (*S)
|
||||
EXPECT_STREQ("sc2", S->getName());
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
Loading…
Reference in New Issue
Block a user