llvm.org GIT mirror llvm / d6a559c
Update llvm command line parser to support subcommands. This allows command line tools to use syntaxes like the following: llvm-foo.exe command1 -o1 -o2 llvm-foo.exe command2 -p1 -p2 Where command1 and command2 contain completely different sets of valid options. This is backwards compatible with previous uses of llvm cl which did not support subcommands, as any option which specifies no optional subcommand (e.g. all existing code) goes into a special "top level" subcommand that expects dashed options to appear immediately after the program name. For example, code which is subcommand unaware would generate a command line such as the following, where no subcommand is specified: llvm-foo.exe -q1 -q2 The top level subcommand can co-exist with actual subcommands, as it is implemented as an actual subcommand which is searched if no explicit subcommand is specified. So llvm-foo.exe as specified above could be written so as to support all three aforementioned command lines simultaneously. There is one additional "special" subcommand called AllSubCommands, which can be used to inject an option into every subcommand. This is useful to support things like help, so that commands such as: llvm-foo.exe --help llvm-foo.exe command1 --help llvm-foo.exe command2 --help All work and display the help for the selected subcommand without having to explicitly go and write code to handle each one separately. This patch is submitted without an example of anything actually using subcommands, but a followup patch will convert the llvm-pdbdump tool to use subcommands. Reviewed By: beanz Differential Revision: http://reviews.llvm.org/D21485 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@274054 91177308-0d34-0410-b5e6-96231b3b80d8 Zachary Turner 4 years ago
4 changed file(s) with 670 addition(s) and 124 deletion(s). Raw diff Collapse all Expand all
2020 #define LLVM_SUPPORT_COMMANDLINE_H
2121
2222 #include "llvm/ADT/ArrayRef.h"
23 #include "llvm/ADT/SmallPtrSet.h"
2324 #include "llvm/ADT/SmallVector.h"
2425 #include "llvm/ADT/StringMap.h"
2526 #include "llvm/ADT/Twine.h"
2627 #include "llvm/Support/Compiler.h"
28 #include "llvm/Support/ManagedStatic.h"
2729 #include
2830 #include
2931 #include
4244 //===----------------------------------------------------------------------===//
4345 // ParseCommandLineOptions - Command line option processing entry point.
4446 //
45 void ParseCommandLineOptions(int argc, const char *const *argv,
46 const char *Overview = nullptr);
47 bool ParseCommandLineOptions(int argc, const char *const *argv,
48 const char *Overview = nullptr,
49 bool IgnoreErrors = false);
4750
4851 //===----------------------------------------------------------------------===//
4952 // ParseEnvironmentOptions - Environment variable option processing alternate
168171
169172 // The general Option Category (used as default category).
170173 extern OptionCategory GeneralCategory;
174
175 //===----------------------------------------------------------------------===//
176 // SubCommand class
177 //
178 class SubCommand {
179 private:
180 const char *const Name = nullptr;
181 const char *const Description = nullptr;
182
183 protected:
184 void registerSubCommand();
185 void unregisterSubCommand();
186
187 public:
188 SubCommand(const char *const Name, const char *const Description = nullptr)
189 : Name(Name), Description(Description) {
190 registerSubCommand();
191 }
192 SubCommand() {}
193
194 void reset();
195
196 operator bool() const;
197
198 const char *getName() const { return Name; }
199 const char *getDescription() const { return Description; }
200
201 SmallVector
202 SmallVector
203 StringMap
204
205 Option *ConsumeAfterOpt = nullptr; // The ConsumeAfter option if it exists.
206 };
207
208 // A special subcommand representing no subcommand
209 extern ManagedStatic TopLevelSubCommand;
210
211 // A special subcommand that can be used to put an option into all subcommands.
212 extern ManagedStatic AllSubCommands;
171213
172214 //===----------------------------------------------------------------------===//
173215 // Option Base class
208250 StringRef HelpStr; // The descriptive text message for -help
209251 StringRef ValueStr; // String describing what the value of this option is
210252 OptionCategory *Category; // The Category this option belongs to
253 SmallPtrSet Subs; // The subcommands this option belongs to.
211254 bool FullyInitialized; // Has addArguemnt been called?
212255
213256 inline enum NumOccurrencesFlag getNumOccurrencesFlag() const {
228271
229272 // hasArgStr - Return true if the argstr != ""
230273 bool hasArgStr() const { return !ArgStr.empty(); }
274 bool isPositional() const { return getFormattingFlag() == cl::Positional; }
275 bool isSink() const { return getMiscFlags() & cl::Sink; }
276 bool isConsumeAfter() const {
277 return getNumOccurrencesFlag() == cl::ConsumeAfter;
278 }
279 bool isInAllSubCommands() const {
280 return std::any_of(Subs.begin(), Subs.end(), [](const SubCommand *SC) {
281 return SC == &*AllSubCommands;
282 });
283 }
231284
232285 //-------------------------------------------------------------------------===
233286 // Accessor functions set by OptionModifiers
242295 void setMiscFlag(enum MiscFlags M) { Misc |= M; }
243296 void setPosition(unsigned pos) { Position = pos; }
244297 void setCategory(OptionCategory &C) { Category = &C; }
298 void addSubCommand(SubCommand &S) { Subs.insert(&S); }
245299
246300 protected:
247301 explicit Option(enum NumOccurrencesFlag OccurrencesFlag,
286340
287341 public:
288342 inline int getNumOccurrences() const { return NumOccurrences; }
343 inline void reset() { NumOccurrences = 0; }
289344 virtual ~Option() {}
290345 };
291346
346401 cat(OptionCategory &c) : Category(c) {}
347402
348403 template void apply(Opt &O) const { O.setCategory(Category); }
404 };
405
406 // sub - Specify the subcommand that this option belongs to.
407 struct sub {
408 SubCommand ⋐
409 sub(SubCommand &S) : Sub(S) {}
410
411 template void apply(Opt &O) const { O.addSubCommand(Sub); }
349412 };
350413
351414 //===----------------------------------------------------------------------===//
15881651 error("cl::alias must have argument name specified!");
15891652 if (!AliasFor)
15901653 error("cl::alias must have an cl::aliasopt(option) specified!");
1654 Subs = AliasFor->Subs;
15911655 addArgument();
15921656 }
15931657
16681732 /// Hopefully this API can be depricated soon. Any situation where options need
16691733 /// to be modified by tools or libraries should be handled by sane APIs rather
16701734 /// than just handing around a global list.
1671 StringMap
1735 StringMap
16721736
16731737 //===----------------------------------------------------------------------===//
16741738 // Standalone command line processing utilities.
17361800 /// Some tools (like clang-format) like to be able to hide all options that are
17371801 /// not specific to the tool. This function allows a tool to specify a single
17381802 /// option category to display in the -help output.
1739 void HideUnrelatedOptions(cl::OptionCategory &Category);
1803 void HideUnrelatedOptions(cl::OptionCategory &Category,
1804 SubCommand &Sub = *TopLevelSubCommand);
17401805
17411806 /// \brief Mark all options not part of the categories as cl::ReallyHidden.
17421807 ///
17451810 /// Some tools (like clang-format) like to be able to hide all options that are
17461811 /// not specific to the tool. This function allows a tool to specify a single
17471812 /// option category to display in the -help output.
1748 void HideUnrelatedOptions(ArrayRef Categories);
1813 void HideUnrelatedOptions(ArrayRef Categories,
1814 SubCommand &Sub = *TopLevelSubCommand);
1815
1816 void ResetCommandLineOptions();
17491817
17501818 } // End namespace cl
17511819
1818 #include "llvm/Support/CommandLine.h"
1919 #include "llvm-c/Support.h"
2020 #include "llvm/ADT/ArrayRef.h"
21 #include "llvm/ADT/DenseMap.h"
2122 #include "llvm/ADT/STLExtras.h"
2223 #include "llvm/ADT/SmallPtrSet.h"
2324 #include "llvm/ADT/SmallString.h"
9394 // This collects additional help to be printed.
9495 std::vector MoreHelp;
9596
96 SmallVector
97 SmallVector
98 StringMap
99
100 Option *ConsumeAfterOpt; // The ConsumeAfter option if it exists.
101
10297 // This collects the different option categories that have been registered.
10398 SmallPtrSet RegisteredOptionCategories;
10499
105 CommandLineParser() : ProgramOverview(nullptr), ConsumeAfterOpt(nullptr) {}
106
107 void ParseCommandLineOptions(int argc, const char *const *argv,
108 const char *Overview);
100 // This collects the different subcommands that have been registered.
101 SmallPtrSet RegisteredSubCommands;
102
103 CommandLineParser() : ProgramOverview(nullptr), ActiveSubCommand(nullptr) {
104 registerSubCommand(&*TopLevelSubCommand);
105 registerSubCommand(&*AllSubCommands);
106 }
107
108 bool ParseCommandLineOptions(int argc, const char *const *argv,
109 const char *Overview, bool IgnoreErrors);
110
111 void addLiteralOption(Option &Opt, SubCommand *SC, const char *Name) {
112 if (Opt.hasArgStr())
113 return;
114 if (!SC->OptionsMap.insert(std::make_pair(Name, &Opt)).second) {
115 errs() << ProgramName << ": CommandLine Error: Option '" << Name
116 << "' registered more than once!\n";
117 report_fatal_error("inconsistency in registered CommandLine options");
118 }
119
120 // If we're adding this to all sub-commands, add it to the ones that have
121 // already been registered.
122 if (SC == &*AllSubCommands) {
123 for (const auto &Sub : RegisteredSubCommands) {
124 if (SC == Sub)
125 continue;
126 addLiteralOption(Opt, Sub, Name);
127 }
128 }
129 }
109130
110131 void addLiteralOption(Option &Opt, const char *Name) {
111 if (!Opt.hasArgStr()) {
112 if (!OptionsMap.insert(std::make_pair(Name, &Opt)).second) {
113 errs() << ProgramName << ": CommandLine Error: Option '" << Name
114 << "' registered more than once!\n";
115 report_fatal_error("inconsistency in registered CommandLine options");
116 }
117 }
118 }
119
120 void addOption(Option *O) {
132 if (Opt.Subs.empty())
133 addLiteralOption(Opt, &*TopLevelSubCommand, Name);
134 else {
135 for (auto SC : Opt.Subs)
136 addLiteralOption(Opt, SC, Name);
137 }
138 }
139
140 void addOption(Option *O, SubCommand *SC) {
121141 bool HadErrors = false;
122142 if (O->hasArgStr()) {
123143 // Add argument to the argument map!
124 if (!OptionsMap.insert(std::make_pair(O->ArgStr, O)).second) {
144 if (!SC->OptionsMap.insert(std::make_pair(O->ArgStr, O)).second) {
125145 errs() << ProgramName << ": CommandLine Error: Option '" << O->ArgStr
126146 << "' registered more than once!\n";
127147 HadErrors = true;
130150
131151 // Remember information about positional options.
132152 if (O->getFormattingFlag() == cl::Positional)
133 PositionalOpts.push_back(O);
153 SC->PositionalOpts.push_back(O);
134154 else if (O->getMiscFlags() & cl::Sink) // Remember sink options
135 SinkOpts.push_back(O);
155 SC->SinkOpts.push_back(O);
136156 else if (O->getNumOccurrencesFlag() == cl::ConsumeAfter) {
137 if (ConsumeAfterOpt) {
157 if (SC->ConsumeAfterOpt) {
138158 O->error("Cannot specify more than one option with cl::ConsumeAfter!");
139159 HadErrors = true;
140160 }
141 ConsumeAfterOpt = O;
161 SC->ConsumeAfterOpt = O;
142162 }
143163
144164 // Fail hard if there were errors. These are strictly unrecoverable and
147167 // linked LLVM distribution.
148168 if (HadErrors)
149169 report_fatal_error("inconsistency in registered CommandLine options");
150 }
151
152 void removeOption(Option *O) {
170
171 // If we're adding this to all sub-commands, add it to the ones that have
172 // already been registered.
173 if (SC == &*AllSubCommands) {
174 for (const auto &Sub : RegisteredSubCommands) {
175 if (SC == Sub)
176 continue;
177 addOption(O, Sub);
178 }
179 }
180 }
181
182 void addOption(Option *O) {
183 if (O->Subs.empty()) {
184 addOption(O, &*TopLevelSubCommand);
185 } else {
186 for (auto SC : O->Subs)
187 addOption(O, SC);
188 }
189 }
190
191 void removeOption(Option *O, SubCommand *SC) {
153192 SmallVector OptionNames;
154193 O->getExtraOptionNames(OptionNames);
155194 if (O->hasArgStr())
156195 OptionNames.push_back(O->ArgStr);
196
197 SubCommand &Sub = *SC;
157198 for (auto Name : OptionNames)
158 OptionsMap.erase(Name);
199 Sub.OptionsMap.erase(Name);
159200
160201 if (O->getFormattingFlag() == cl::Positional)
161 for (auto Opt = PositionalOpts.begin(); Opt != PositionalOpts.end();
162 ++Opt) {
202 for (auto Opt = Sub.PositionalOpts.begin();
203 Opt != Sub.PositionalOpts.end(); ++Opt) {
163204 if (*Opt == O) {
164 PositionalOpts.erase(Opt);
205 Sub.PositionalOpts.erase(Opt);
165206 break;
166207 }
167208 }
168209 else if (O->getMiscFlags() & cl::Sink)
169 for (auto Opt = SinkOpts.begin(); Opt != SinkOpts.end(); ++Opt) {
210 for (auto Opt = Sub.SinkOpts.begin(); Opt != Sub.SinkOpts.end(); ++Opt) {
170211 if (*Opt == O) {
171 SinkOpts.erase(Opt);
212 Sub.SinkOpts.erase(Opt);
172213 break;
173214 }
174215 }
175 else if (O == ConsumeAfterOpt)
176 ConsumeAfterOpt = nullptr;
177 }
178
179 bool hasOptions() {
180 return (!OptionsMap.empty() || !PositionalOpts.empty() ||
181 nullptr != ConsumeAfterOpt);
182 }
183
184 void updateArgStr(Option *O, StringRef NewName) {
185 if (!OptionsMap.insert(std::make_pair(NewName, O)).second) {
216 else if (O == Sub.ConsumeAfterOpt)
217 Sub.ConsumeAfterOpt = nullptr;
218 }
219
220 void removeOption(Option *O) {
221 if (O->Subs.empty())
222 removeOption(O, &*TopLevelSubCommand);
223 else {
224 if (O->isInAllSubCommands()) {
225 for (auto SC : RegisteredSubCommands)
226 removeOption(O, SC);
227 } else {
228 for (auto SC : O->Subs)
229 removeOption(O, SC);
230 }
231 }
232 }
233
234 bool hasOptions(const SubCommand &Sub) const {
235 return (!Sub.OptionsMap.empty() || !Sub.PositionalOpts.empty() ||
236 nullptr != Sub.ConsumeAfterOpt);
237 }
238
239 bool hasOptions() const {
240 for (const auto &S : RegisteredSubCommands) {
241 if (hasOptions(*S))
242 return true;
243 }
244 return false;
245 }
246
247 SubCommand *getActiveSubCommand() { return ActiveSubCommand; }
248
249 void updateArgStr(Option *O, StringRef NewName, SubCommand *SC) {
250 SubCommand &Sub = *SC;
251 if (!Sub.OptionsMap.insert(std::make_pair(NewName, O)).second) {
186252 errs() << ProgramName << ": CommandLine Error: Option '" << O->ArgStr
187253 << "' registered more than once!\n";
188254 report_fatal_error("inconsistency in registered CommandLine options");
189255 }
190 OptionsMap.erase(O->ArgStr);
256 Sub.OptionsMap.erase(O->ArgStr);
257 }
258
259 void updateArgStr(Option *O, StringRef NewName) {
260 if (O->Subs.empty())
261 updateArgStr(O, NewName, &*TopLevelSubCommand);
262 else {
263 for (auto SC : O->Subs)
264 updateArgStr(O, NewName, SC);
265 }
191266 }
192267
193268 void printOptionValues();
202277 RegisteredOptionCategories.insert(cat);
203278 }
204279
280 void registerSubCommand(SubCommand *sub) {
281 assert(count_if(RegisteredSubCommands,
282 [sub](const SubCommand *Sub) {
283 return (sub->getName() != nullptr) &&
284 (Sub->getName() == sub->getName());
285 }) == 0 &&
286 "Duplicate subcommands");
287 RegisteredSubCommands.insert(sub);
288
289 // For all options that have been registered for all subcommands, add the
290 // option to this subcommand now.
291 if (sub != &*AllSubCommands) {
292 for (auto &E : AllSubCommands->OptionsMap) {
293 Option *O = E.second;
294 if ((O->isPositional() || O->isSink() || O->isConsumeAfter()) ||
295 O->hasArgStr())
296 addOption(O, sub);
297 else
298 addLiteralOption(*O, sub, E.first().str().c_str());
299 }
300 }
301 }
302
303 void unregisterSubCommand(SubCommand *sub) {
304 RegisteredSubCommands.erase(sub);
305 }
306
307 void reset() {
308 ActiveSubCommand = nullptr;
309 ProgramName.clear();
310 ProgramOverview = nullptr;
311
312 MoreHelp.clear();
313 RegisteredOptionCategories.clear();
314
315 for (auto SC : RegisteredSubCommands) {
316 for (auto &O : SC->OptionsMap)
317 O.second->reset();
318 }
319 RegisteredSubCommands.clear();
320
321 TopLevelSubCommand->reset();
322 AllSubCommands->reset();
323 registerSubCommand(&*TopLevelSubCommand);
324 registerSubCommand(&*AllSubCommands);
325 }
326
205327 private:
206 Option *LookupOption(StringRef &Arg, StringRef &Value);
328 SubCommand *ActiveSubCommand;
329
330 Option *LookupOption(SubCommand &Sub, StringRef &Arg, StringRef &Value);
331 SubCommand *LookupSubCommand(const char *Name);
207332 };
208333
209334 } // namespace
238363 GlobalParser->registerCategory(this);
239364 }
240365
366 // A special subcommand representing no subcommand
367 ManagedStatic llvm::cl::TopLevelSubCommand;
368
369 // A special subcommand that can be used to put an option into all subcommands.
370 ManagedStatic llvm::cl::AllSubCommands;
371
372 void SubCommand::registerSubCommand() {
373 GlobalParser->registerSubCommand(this);
374 }
375
376 void SubCommand::unregisterSubCommand() {
377 GlobalParser->unregisterSubCommand(this);
378 }
379
380 void SubCommand::reset() {
381 PositionalOpts.clear();
382 SinkOpts.clear();
383 OptionsMap.clear();
384
385 ConsumeAfterOpt = nullptr;
386 }
387
388 SubCommand::operator bool() const {
389 return (GlobalParser->getActiveSubCommand() == this);
390 }
391
241392 //===----------------------------------------------------------------------===//
242393 // Basic, shared command line option processing machinery.
243394 //
245396 /// LookupOption - Lookup the option specified by the specified option on the
246397 /// command line. If there is a value specified (after an equal sign) return
247398 /// that as well. This assumes that leading dashes have already been stripped.
248 Option *CommandLineParser::LookupOption(StringRef &Arg, StringRef &Value) {
399 Option *CommandLineParser::LookupOption(SubCommand &Sub, StringRef &Arg,
400 StringRef &Value) {
249401 // Reject all dashes.
250402 if (Arg.empty())
251403 return nullptr;
404 assert(&Sub != &*AllSubCommands);
252405
253406 size_t EqualPos = Arg.find('=');
254407
255408 // If we have an equals sign, remember the value.
256409 if (EqualPos == StringRef::npos) {
257410 // Look up the option.
258 StringMap
259 return I != OptionsMap.end() ? I->second : nullptr;
411 auto I = Sub.OptionsMap.find(Arg);
412 if (I == Sub.OptionsMap.end())
413 return nullptr;
414
415 return I != Sub.OptionsMap.end() ? I->second : nullptr;
260416 }
261417
262418 // If the argument before the = is a valid option name, we match. If not,
263419 // return Arg unmolested.
264 StringMap
265 OptionsMap.find(Arg.substr(0, EqualPos));
266 if (I == OptionsMap.end())
420 auto I = Sub.OptionsMap.find(Arg.substr(0, EqualPos));
421 if (I == Sub.OptionsMap.end())
267422 return nullptr;
268423
269424 Value = Arg.substr(EqualPos + 1);
270425 Arg = Arg.substr(0, EqualPos);
271426 return I->second;
427 }
428
429 SubCommand *CommandLineParser::LookupSubCommand(const char *Name) {
430 if (Name == nullptr)
431 return &*TopLevelSubCommand;
432 for (auto S : RegisteredSubCommands) {
433 if (S == &*AllSubCommands)
434 continue;
435 if (S->getName() == nullptr)
436 continue;
437
438 if (StringRef(S->getName()) == StringRef(Name))
439 return S;
440 }
441 return &*TopLevelSubCommand;
272442 }
273443
274444 /// LookupNearestOption - Lookup the closest match to the option specified by
819989 ParseCommandLineOptions(newArgc, &newArgv[0], Overview);
820990 }
821991
822 void cl::ParseCommandLineOptions(int argc, const char *const *argv,
823 const char *Overview) {
824 GlobalParser->ParseCommandLineOptions(argc, argv, Overview);
825 }
826
827 void CommandLineParser::ParseCommandLineOptions(int argc,
992 bool cl::ParseCommandLineOptions(int argc, const char *const *argv,
993 const char *Overview, bool IgnoreErrors) {
994 return GlobalParser->ParseCommandLineOptions(argc, argv, Overview,
995 IgnoreErrors);
996 }
997
998 bool CommandLineParser::ParseCommandLineOptions(int argc,
828999 const char *const *argv,
829 const char *Overview) {
1000 const char *Overview,
1001 bool IgnoreErrors) {
8301002 assert(hasOptions() && "No options specified!");
8311003
8321004 // Expand response files.
8481020
8491021 // Determine whether or not there are an unlimited number of positionals
8501022 bool HasUnlimitedPositionals = false;
1023
1024 // So that we can parse different command lines multiple times in succession
1025 // we reset all option values to look like they have never been seen before.
1026 for (auto SC : RegisteredSubCommands) {
1027 for (auto &O : SC->OptionsMap)
1028 O.second->reset();
1029 }
1030
1031 int FirstArg = 1;
1032 SubCommand *ChosenSubCommand = &*TopLevelSubCommand;
1033 if (argc >= 2 && argv[FirstArg][0] != '-') {
1034 // If the first argument specifies a valid subcommand, start processing
1035 // options from the second argument.
1036 ChosenSubCommand = LookupSubCommand(argv[FirstArg]);
1037 if (ChosenSubCommand != &*TopLevelSubCommand)
1038 FirstArg = 2;
1039 }
1040 GlobalParser->ActiveSubCommand = ChosenSubCommand;
1041
1042 assert(ChosenSubCommand);
1043 auto &ConsumeAfterOpt = ChosenSubCommand->ConsumeAfterOpt;
1044 auto &PositionalOpts = ChosenSubCommand->PositionalOpts;
1045 auto &SinkOpts = ChosenSubCommand->SinkOpts;
1046 auto &OptionsMap = ChosenSubCommand->OptionsMap;
8511047
8521048 if (ConsumeAfterOpt) {
8531049 assert(PositionalOpts.size() > 0 &&
8641060 else if (ConsumeAfterOpt) {
8651061 // ConsumeAfter cannot be combined with "optional" positional options
8661062 // unless there is only one positional argument...
867 if (PositionalOpts.size() > 1)
868 ErrorParsing |= Opt->error(
869 "error - this positional option will never be matched, "
870 "because it does not Require a value, and a "
871 "cl::ConsumeAfter option is active!");
1063 if (PositionalOpts.size() > 1) {
1064 if (!IgnoreErrors)
1065 Opt->error("error - this positional option will never be matched, "
1066 "because it does not Require a value, and a "
1067 "cl::ConsumeAfter option is active!");
1068 ErrorParsing = true;
1069 }
8721070 } else if (UnboundedFound && !Opt->hasArgStr()) {
8731071 // This option does not "require" a value... Make sure this option is
8741072 // not specified after an option that eats all extra arguments, or this
8751073 // one will never get any!
8761074 //
877 ErrorParsing |= Opt->error("error - option can never match, because "
878 "another positional argument will match an "
879 "unbounded number of values, and this option"
880 " does not require a value!");
881 errs() << ProgramName << ": CommandLine Error: Option '" << Opt->ArgStr
882 << "' is all messed up!\n";
883 errs() << PositionalOpts.size();
1075 if (!IgnoreErrors) {
1076 Opt->error("error - option can never match, because "
1077 "another positional argument will match an "
1078 "unbounded number of values, and this option"
1079 " does not require a value!");
1080 errs() << ProgramName << ": CommandLine Error: Option '"
1081 << Opt->ArgStr << "' is all messed up!\n";
1082 errs() << PositionalOpts.size();
1083 }
1084 ErrorParsing = true;
8841085 }
8851086 UnboundedFound |= EatsUnboundedNumberOfValues(Opt);
8861087 }
8991100
9001101 // Loop over all of the arguments... processing them.
9011102 bool DashDashFound = false; // Have we read '--'?
902 for (int i = 1; i < argc; ++i) {
1103 for (int i = FirstArg; i < argc; ++i) {
9031104 Option *Handler = nullptr;
9041105 Option *NearestHandler = nullptr;
9051106 std::string NearestHandlerString;
9461147 while (!ArgName.empty() && ArgName[0] == '-')
9471148 ArgName = ArgName.substr(1);
9481149
949 Handler = LookupOption(ArgName, Value);
1150 Handler = LookupOption(*ChosenSubCommand, ArgName, Value);
9501151 if (!Handler || Handler->getFormattingFlag() != cl::Positional) {
9511152 ProvidePositionalOption(ActivePositionalArg, argv[i], i);
9521153 continue; // We are done!
9581159 while (!ArgName.empty() && ArgName[0] == '-')
9591160 ArgName = ArgName.substr(1);
9601161
961 Handler = LookupOption(ArgName, Value);
1162 Handler = LookupOption(*ChosenSubCommand, ArgName, Value);
9621163
9631164 // Check to see if this "option" is really a prefixed or grouped argument.
9641165 if (!Handler)
9741175
9751176 if (!Handler) {
9761177 if (SinkOpts.empty()) {
977 errs() << ProgramName << ": Unknown command line argument '" << argv[i]
978 << "'. Try: '" << argv[0] << " -help'\n";
979
980 if (NearestHandler) {
981 // If we know a near match, report it as well.
982 errs() << ProgramName << ": Did you mean '-" << NearestHandlerString
983 << "'?\n";
1178 if (!IgnoreErrors) {
1179 errs() << ProgramName << ": Unknown command line argument '"
1180 << argv[i] << "'. Try: '" << argv[0] << " -help'\n";
1181
1182 if (NearestHandler) {
1183 // If we know a near match, report it as well.
1184 errs() << ProgramName << ": Did you mean '-" << NearestHandlerString
1185 << "'?\n";
1186 }
9841187 }
9851188
9861189 ErrorParsing = true;
10031206
10041207 // Check and handle positional arguments now...
10051208 if (NumPositionalRequired > PositionalVals.size()) {
1006 errs() << ProgramName
1007 << ": Not enough positional command line arguments specified!\n"
1008 << "Must specify at least " << NumPositionalRequired
1009 << " positional arguments: See: " << argv[0] << " -help\n";
1209 if (!IgnoreErrors) {
1210 errs() << ProgramName
1211 << ": Not enough positional command line arguments specified!\n"
1212 << "Must specify at least " << NumPositionalRequired
1213 << " positional arguments: See: " << argv[0] << " -help\n";
1214 }
10101215
10111216 ErrorParsing = true;
10121217 } else if (!HasUnlimitedPositionals &&
10131218 PositionalVals.size() > PositionalOpts.size()) {
1014 errs() << ProgramName << ": Too many positional arguments specified!\n"
1015 << "Can specify at most " << PositionalOpts.size()
1016 << " positional arguments: See: " << argv[0] << " -help\n";
1219 if (!IgnoreErrors) {
1220 errs() << ProgramName << ": Too many positional arguments specified!\n"
1221 << "Can specify at most " << PositionalOpts.size()
1222 << " positional arguments: See: " << argv[0] << " -help\n";
1223 }
10171224 ErrorParsing = true;
10181225
10191226 } else if (!ConsumeAfterOpt) {
11081315 MoreHelp.clear();
11091316
11101317 // If we had an error processing our arguments, don't let the program execute
1111 if (ErrorParsing)
1112 exit(1);
1318 if (ErrorParsing) {
1319 if (!IgnoreErrors)
1320 exit(1);
1321 return false;
1322 }
1323 return true;
11131324 }
11141325
11151326 //===----------------------------------------------------------------------===//
14591670 return strcmp(LHS->first, RHS->first);
14601671 }
14611672
1673 static int SubNameCompare(const std::pair *LHS,
1674 const std::pair *RHS) {
1675 return strcmp(LHS->first, RHS->first);
1676 }
1677
14621678 // Copy Options into a vector so we can sort them as we like.
14631679 static void sortOpts(StringMap
14641680 SmallVectorImpl> &Opts,
14871703 array_pod_sort(Opts.begin(), Opts.end(), OptNameCompare);
14881704 }
14891705
1706 static void
1707 sortSubCommands(const SmallPtrSetImpl &SubMap,
1708 SmallVectorImpl> &Subs) {
1709 for (const auto &S : SubMap) {
1710 if (S->getName() == nullptr)
1711 continue;
1712 Subs.push_back(std::make_pair(S->getName(), S));
1713 }
1714 array_pod_sort(Subs.begin(), Subs.end(), SubNameCompare);
1715 }
1716
14901717 namespace {
14911718
14921719 class HelpPrinter {
14941721 const bool ShowHidden;
14951722 typedef SmallVector, 128>
14961723 StrOptionPairVector;
1724 typedef SmallVector, 128>
1725 StrSubCommandPairVector;
14971726 // Print the options. Opts is assumed to be alphabetically sorted.
14981727 virtual void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) {
14991728 for (size_t i = 0, e = Opts.size(); i != e; ++i)
15001729 Opts[i].second->printOptionInfo(MaxArgLen);
15011730 }
15021731
1732 void printSubCommands(StrSubCommandPairVector &Subs, size_t MaxSubLen) {
1733 for (const auto &S : Subs) {
1734 outs() << " " << S.first;
1735 if (S.second->getDescription()) {
1736 outs().indent(MaxSubLen - strlen(S.first));
1737 outs() << " - " << S.second->getDescription();
1738 }
1739 outs() << "\n";
1740 }
1741 }
1742
15031743 public:
15041744 explicit HelpPrinter(bool showHidden) : ShowHidden(showHidden) {}
15051745 virtual ~HelpPrinter() {}
15091749 if (!Value)
15101750 return;
15111751
1752 SubCommand *Sub = GlobalParser->getActiveSubCommand();
1753 auto &OptionsMap = Sub->OptionsMap;
1754 auto &PositionalOpts = Sub->PositionalOpts;
1755 auto &ConsumeAfterOpt = Sub->ConsumeAfterOpt;
1756
15121757 StrOptionPairVector Opts;
1513 sortOpts(GlobalParser->OptionsMap, Opts, ShowHidden);
1758 sortOpts(OptionsMap, Opts, ShowHidden);
1759
1760 StrSubCommandPairVector Subs;
1761 sortSubCommands(GlobalParser->RegisteredSubCommands, Subs);
15141762
15151763 if (GlobalParser->ProgramOverview)
15161764 outs() << "OVERVIEW: " << GlobalParser->ProgramOverview << "\n";
15171765
1518 outs() << "USAGE: " << GlobalParser->ProgramName << " [options]";
1519
1520 for (auto Opt : GlobalParser->PositionalOpts) {
1766 if (Sub == &*TopLevelSubCommand)
1767 outs() << "USAGE: " << GlobalParser->ProgramName
1768 << " [subcommand] [options]";
1769 else {
1770 if (Sub->getDescription() != nullptr) {
1771 outs() << "SUBCOMMAND '" << Sub->getName()
1772 << "': " << Sub->getDescription() << "\n\n";
1773 }
1774 outs() << "USAGE: " << GlobalParser->ProgramName << " " << Sub->getName()
1775 << " [options]";
1776 }
1777
1778 for (auto Opt : PositionalOpts) {
15211779 if (Opt->hasArgStr())
15221780 outs() << " --" << Opt->ArgStr;
15231781 outs() << " " << Opt->HelpStr;
15241782 }
15251783
15261784 // Print the consume after option info if it exists...
1527 if (GlobalParser->ConsumeAfterOpt)
1528 outs() << " " << GlobalParser->ConsumeAfterOpt->HelpStr;
1785 if (ConsumeAfterOpt)
1786 outs() << " " << ConsumeAfterOpt->HelpStr;
1787
1788 if (Sub == &*TopLevelSubCommand && Subs.size() > 2) {
1789 // Compute the maximum subcommand length...
1790 size_t MaxSubLen = 0;
1791 for (size_t i = 0, e = Subs.size(); i != e; ++i)
1792 MaxSubLen = std::max(MaxSubLen, strlen(Subs[i].first));
1793
1794 outs() << "\n\n";
1795 outs() << "SUBCOMMANDS:\n\n";
1796 printSubCommands(Subs, MaxSubLen);
1797 outs() << "\n";
1798 outs() << " Type \"" << GlobalParser->ProgramName
1799 << " -help\" to get more help on a specific "
1800 "subcommand";
1801 }
15291802
15301803 outs() << "\n\n";
15311804
16741947 "help-list",
16751948 cl::desc("Display list of available options (-help-list-hidden for more)"),
16761949 cl::location(UncategorizedNormalPrinter), cl::Hidden, cl::ValueDisallowed,
1677 cl::cat(GenericCategory));
1950 cl::cat(GenericCategory), cl::sub(*AllSubCommands));
16781951
16791952 static cl::opt>
16801953 HLHOp("help-list-hidden", cl::desc("Display list of all available options"),
16811954 cl::location(UncategorizedHiddenPrinter), cl::Hidden,
1682 cl::ValueDisallowed, cl::cat(GenericCategory));
1955 cl::ValueDisallowed, cl::cat(GenericCategory),
1956 cl::sub(*AllSubCommands));
16831957
16841958 // Define uncategorized/categorized help printers. These printers change their
16851959 // behaviour at runtime depending on whether one or more Option categories have
16871961 static cl::opt>
16881962 HOp("help", cl::desc("Display available options (-help-hidden for more)"),
16891963 cl::location(WrappedNormalPrinter), cl::ValueDisallowed,
1690 cl::cat(GenericCategory));
1964 cl::cat(GenericCategory), cl::sub(*AllSubCommands));
16911965
16921966 static cl::opt>
16931967 HHOp("help-hidden", cl::desc("Display all available options"),
16941968 cl::location(WrappedHiddenPrinter), cl::Hidden, cl::ValueDisallowed,
1695 cl::cat(GenericCategory));
1969 cl::cat(GenericCategory), cl::sub(*AllSubCommands));
16961970
16971971 static cl::opt PrintOptions(
16981972 "print-options",
16991973 cl::desc("Print non-default options after command line parsing"),
1700 cl::Hidden, cl::init(false), cl::cat(GenericCategory));
1974 cl::Hidden, cl::init(false), cl::cat(GenericCategory),
1975 cl::sub(*AllSubCommands));
17011976
17021977 static cl::opt PrintAllOptions(
17031978 "print-all-options",
17041979 cl::desc("Print all option values after command line parsing"), cl::Hidden,
1705 cl::init(false), cl::cat(GenericCategory));
1980 cl::init(false), cl::cat(GenericCategory), cl::sub(*AllSubCommands));
17061981
17071982 void HelpPrinterWrapper::operator=(bool Value) {
17081983 if (!Value)
17292004 return;
17302005
17312006 SmallVector, 128> Opts;
1732 sortOpts(OptionsMap, Opts, /*ShowHidden*/ true);
2007 sortOpts(ActiveSubCommand->OptionsMap, Opts, /*ShowHidden*/ true);
17332008
17342009 // Compute the maximum argument length...
17352010 size_t MaxArgLen = 0;
18382113 ExtraVersionPrinters->push_back(func);
18392114 }
18402115
1841 StringMap
1842 return GlobalParser->OptionsMap;
1843 }
1844
1845 void cl::HideUnrelatedOptions(cl::OptionCategory &Category) {
1846 for (auto &I : GlobalParser->OptionsMap) {
2116 StringMap) {
2117 auto &Subs = GlobalParser->RegisteredSubCommands;
2118 assert(std::find(Subs.begin(), Subs.end(), &Sub) != Subs.end());
2119 return Sub.OptionsMap;
2120 }
2121
2122 void cl::HideUnrelatedOptions(cl::OptionCategory &Category, SubCommand &Sub) {
2123 for (auto &I : Sub.OptionsMap) {
18472124 if (I.second->Category != &Category &&
18482125 I.second->Category != &GenericCategory)
18492126 I.second->setHiddenFlag(cl::ReallyHidden);
18502127 }
18512128 }
18522129
1853 void cl::HideUnrelatedOptions(ArrayRef Categories) {
2130 void cl::HideUnrelatedOptions(ArrayRef Categories,
2131 SubCommand &Sub) {
18542132 auto CategoriesBegin = Categories.begin();
18552133 auto CategoriesEnd = Categories.end();
1856 for (auto &I : GlobalParser->OptionsMap) {
2134 for (auto &I : Sub.OptionsMap) {
18572135 if (std::find(CategoriesBegin, CategoriesEnd, I.second->Category) ==
18582136 CategoriesEnd &&
18592137 I.second->Category != &GenericCategory)
18612139 }
18622140 }
18632141
2142 void cl::ResetCommandLineOptions() { GlobalParser->reset(); }
2143
18642144 void LLVMParseCommandLineOptions(int argc, const char *const *argv,
18652145 const char *Overview) {
1866 llvm::cl::ParseCommandLineOptions(argc, argv, Overview);
1867 }
2146 llvm::cl::ParseCommandLineOptions(argc, argv, Overview, true);
2147 }
6666 : Base(M0, M1, M2, M3) {}
6767
6868 ~StackOption() override { this->removeArgument(); }
69
70 template StackOption &operator=(const DT &V) {
71 this->setValue(V);
72 return *this;
73 }
74 };
75
76 class StackSubCommand : public cl::SubCommand {
77 public:
78 StackSubCommand(const char *const Name,
79 const char *const Description = nullptr)
80 : SubCommand(Name, Description) {}
81
82 StackSubCommand() : SubCommand() {}
83
84 ~StackSubCommand() { unregisterSubCommand(); }
6985 };
7086
7187
7793 const char ArgString[] = "new-test-option";
7894 const char ValueString[] = "Integer";
7995
80 StringMap &Map = cl::getRegisteredOptions();
96 StringMap &Map =
97 cl::getRegisteredOptions(*cl::TopLevelSubCommand);
8198
8299 ASSERT_TRUE(Map.count("test-option") == 1) <<
83100 "Could not find option in map.";
236253 ASSERT_EQ(cl::NotHidden, TestOption2.getOptionHiddenFlag())
237254 << "Hid extra option that should be visable.";
238255
239 StringMap &Map = cl::getRegisteredOptions();
256 StringMap &Map =
257 cl::getRegisteredOptions(*cl::TopLevelSubCommand);
240258 ASSERT_EQ(cl::NotHidden, Map["help"]->getOptionHiddenFlag())
241259 << "Hid default option that should be visable.";
242260 }
260278 ASSERT_EQ(cl::NotHidden, TestOption3.getOptionHiddenFlag())
261279 << "Hid extra option that should be visable.";
262280
263 StringMap &Map = cl::getRegisteredOptions();
281 StringMap &Map =
282 cl::getRegisteredOptions(*cl::TopLevelSubCommand);
264283 ASSERT_EQ(cl::NotHidden, Map["help"]->getOptionHiddenFlag())
265284 << "Hid default option that should be visable.";
266285 }
267286
287 TEST(CommandLineTest, SetValueInSubcategories) {
288 cl::ResetCommandLineOptions();
289
290 StackSubCommand SC1("sc1", "First subcommand");
291 StackSubCommand SC2("sc2", "Second subcommand");
292
293 StackOption TopLevelOpt("top-level", cl::init(false));
294 StackOption SC1Opt("sc1", cl::sub(SC1), cl::init(false));
295 StackOption SC2Opt("sc2", cl::sub(SC2), cl::init(false));
296
297 EXPECT_FALSE(TopLevelOpt);
298 EXPECT_FALSE(SC1Opt);
299 EXPECT_FALSE(SC2Opt);
300 const char *args[] = {"prog", "-top-level"};
301 EXPECT_TRUE(cl::ParseCommandLineOptions(2, args, nullptr, true));
302 EXPECT_TRUE(TopLevelOpt);
303 EXPECT_FALSE(SC1Opt);
304 EXPECT_FALSE(SC2Opt);
305
306 TopLevelOpt = false;
307
308 EXPECT_FALSE(TopLevelOpt);
309 EXPECT_FALSE(SC1Opt);
310 EXPECT_FALSE(SC2Opt);
311 const char *args2[] = {"prog", "sc1", "-sc1"};
312 EXPECT_TRUE(cl::ParseCommandLineOptions(3, args2, nullptr, true));
313 EXPECT_FALSE(TopLevelOpt);
314 EXPECT_TRUE(SC1Opt);
315 EXPECT_FALSE(SC2Opt);
316
317 SC1Opt = false;
318
319 EXPECT_FALSE(TopLevelOpt);
320 EXPECT_FALSE(SC1Opt);
321 EXPECT_FALSE(SC2Opt);
322 const char *args3[] = {"prog", "sc2", "-sc2"};
323 EXPECT_TRUE(cl::ParseCommandLineOptions(3, args3, nullptr, true));
324 EXPECT_FALSE(TopLevelOpt);
325 EXPECT_FALSE(SC1Opt);
326 EXPECT_TRUE(SC2Opt);
327 }
328
329 TEST(CommandLineTest, LookupFailsInWrongSubCommand) {
330 cl::ResetCommandLineOptions();
331
332 StackSubCommand SC1("sc1", "First subcommand");
333 StackSubCommand SC2("sc2", "Second subcommand");
334
335 StackOption SC1Opt("sc1", cl::sub(SC1), cl::init(false));
336 StackOption SC2Opt("sc2", cl::sub(SC2), cl::init(false));
337
338 const char *args[] = {"prog", "sc1", "-sc2"};
339 EXPECT_FALSE(cl::ParseCommandLineOptions(3, args, nullptr, true));
340 }
341
342 TEST(CommandLineTest, AddToAllSubCommands) {
343 cl::ResetCommandLineOptions();
344
345 StackSubCommand SC1("sc1", "First subcommand");
346 StackOption AllOpt("everywhere", cl::sub(*cl::AllSubCommands),
347 cl::init(false));
348 StackSubCommand SC2("sc2", "Second subcommand");
349
350 const char *args[] = {"prog", "-everywhere"};
351 const char *args2[] = {"prog", "sc1", "-everywhere"};
352 const char *args3[] = {"prog", "sc2", "-everywhere"};
353
354 EXPECT_FALSE(AllOpt);
355 EXPECT_TRUE(cl::ParseCommandLineOptions(2, args, nullptr, true));
356 EXPECT_TRUE(AllOpt);
357
358 AllOpt = false;
359
360 EXPECT_FALSE(AllOpt);
361 EXPECT_TRUE(cl::ParseCommandLineOptions(3, args2, nullptr, true));
362 EXPECT_TRUE(AllOpt);
363
364 AllOpt = false;
365
366 EXPECT_FALSE(AllOpt);
367 EXPECT_TRUE(cl::ParseCommandLineOptions(3, args3, nullptr, true));
368 EXPECT_TRUE(AllOpt);
369 }
370
371 TEST(CommandLineTest, ReparseCommandLineOptions) {
372 cl::ResetCommandLineOptions();
373
374 StackOption TopLevelOpt("top-level", cl::sub(*cl::TopLevelSubCommand),
375 cl::init(false));
376
377 const char *args[] = {"prog", "-top-level"};
378
379 EXPECT_FALSE(TopLevelOpt);
380 EXPECT_TRUE(cl::ParseCommandLineOptions(2, args, nullptr, true));
381 EXPECT_TRUE(TopLevelOpt);
382
383 TopLevelOpt = false;
384
385 EXPECT_FALSE(TopLevelOpt);
386 EXPECT_TRUE(cl::ParseCommandLineOptions(2, args, nullptr, true));
387 EXPECT_TRUE(TopLevelOpt);
388 }
389
390 TEST(CommandLineTest, RemoveFromRegularSubCommand) {
391 cl::ResetCommandLineOptions();
392
393 StackSubCommand SC("sc", "Subcommand");
394 StackOption RemoveOption("remove-option", cl::sub(SC), cl::init(false));
395 StackOption KeepOption("keep-option", cl::sub(SC), cl::init(false));
396
397 const char *args[] = {"prog", "sc", "-remove-option"};
398
399 EXPECT_FALSE(RemoveOption);
400 EXPECT_TRUE(cl::ParseCommandLineOptions(3, args, nullptr, true));
401 EXPECT_TRUE(RemoveOption);
402
403 RemoveOption.removeArgument();
404
405 EXPECT_FALSE(cl::ParseCommandLineOptions(3, args, nullptr, true));
406 }
407
408 TEST(CommandLineTest, RemoveFromTopLevelSubCommand) {
409 cl::ResetCommandLineOptions();
410
411 StackOption TopLevelRemove(
412 "top-level-remove", cl::sub(*cl::TopLevelSubCommand), cl::init(false));
413 StackOption TopLevelKeep(
414 "top-level-keep", cl::sub(*cl::TopLevelSubCommand), cl::init(false));
415
416 const char *args[] = {"prog", "-top-level-remove"};
417
418 EXPECT_FALSE(TopLevelRemove);
419 EXPECT_TRUE(cl::ParseCommandLineOptions(2, args, nullptr, true));
420 EXPECT_TRUE(TopLevelRemove);
421
422 TopLevelRemove.removeArgument();
423
424 EXPECT_FALSE(cl::ParseCommandLineOptions(2, args, nullptr, true));
425 }
426
427 TEST(CommandLineTest, RemoveFromAllSubCommands) {
428 cl::ResetCommandLineOptions();
429
430 StackSubCommand SC1("sc1", "First Subcommand");
431 StackSubCommand SC2("sc2", "Second Subcommand");
432 StackOption RemoveOption("remove-option", cl::sub(*cl::AllSubCommands),
433 cl::init(false));
434 StackOption KeepOption("keep-option", cl::sub(*cl::AllSubCommands),
435 cl::init(false));
436
437 const char *args0[] = {"prog", "-remove-option"};
438 const char *args1[] = {"prog", "sc1", "-remove-option"};
439 const char *args2[] = {"prog", "sc2", "-remove-option"};
440
441 // It should work for all subcommands including the top-level.
442 EXPECT_FALSE(RemoveOption);
443 EXPECT_TRUE(cl::ParseCommandLineOptions(2, args0, nullptr, true));
444 EXPECT_TRUE(RemoveOption);
445
446 RemoveOption = false;
447
448 EXPECT_FALSE(RemoveOption);
449 EXPECT_TRUE(cl::ParseCommandLineOptions(3, args1, nullptr, true));
450 EXPECT_TRUE(RemoveOption);
451
452 RemoveOption = false;
453
454 EXPECT_FALSE(RemoveOption);
455 EXPECT_TRUE(cl::ParseCommandLineOptions(3, args2, nullptr, true));
456 EXPECT_TRUE(RemoveOption);
457
458 RemoveOption.removeArgument();
459
460 // It should not work for any subcommands including the top-level.
461 EXPECT_FALSE(cl::ParseCommandLineOptions(2, args0, nullptr, true));
462 EXPECT_FALSE(cl::ParseCommandLineOptions(3, args1, nullptr, true));
463 EXPECT_FALSE(cl::ParseCommandLineOptions(3, args2, nullptr, true));
464 }
465
268466 } // anonymous namespace
230230 // LoopCount should only be incremented once.
231231 while (true) {
232232 ++LoopCount;
233 ProcessInfo WaitResult = Wait(PI1, 0, true, &Error);
233 ProcessInfo WaitResult = llvm::sys::Wait(PI1, 0, true, &Error);
234234 ASSERT_TRUE(Error.empty());
235235 if (WaitResult.Pid == PI1.Pid)
236236 break;
247247 // cse, LoopCount should be greater than 1 (more than one increment occurs).
248248 while (true) {
249249 ++LoopCount;
250 ProcessInfo WaitResult = Wait(PI2, 0, false, &Error);
250 ProcessInfo WaitResult = llvm::sys::Wait(PI2, 0, false, &Error);
251251 ASSERT_TRUE(Error.empty());
252252 if (WaitResult.Pid == PI2.Pid)
253253 break;