File: | lib/Support/CommandLine.cpp |
Location: | line 326, column 15 |
Description: | Array access (from variable 'argv') results in a null pointer dereference |
1 | //===-- CommandLine.cpp - Command line parser implementation --------------===// | |||
2 | // | |||
3 | // The LLVM Compiler Infrastructure | |||
4 | // | |||
5 | // This file is distributed under the University of Illinois Open Source | |||
6 | // License. See LICENSE.TXT for details. | |||
7 | // | |||
8 | //===----------------------------------------------------------------------===// | |||
9 | // | |||
10 | // This class implements a command line argument processor that is useful when | |||
11 | // creating a tool. It provides a simple, minimalistic interface that is easily | |||
12 | // extensible and supports nonlocal (library) command line options. | |||
13 | // | |||
14 | // Note that rather than trying to figure out what this code does, you could try | |||
15 | // reading the library documentation located in docs/CommandLine.html | |||
16 | // | |||
17 | //===----------------------------------------------------------------------===// | |||
18 | ||||
19 | #include "llvm/Support/CommandLine.h" | |||
20 | #include "llvm-c/Support.h" | |||
21 | #include "llvm/ADT/ArrayRef.h" | |||
22 | #include "llvm/ADT/SmallPtrSet.h" | |||
23 | #include "llvm/ADT/SmallString.h" | |||
24 | #include "llvm/ADT/StringMap.h" | |||
25 | #include "llvm/ADT/Twine.h" | |||
26 | #include "llvm/Config/config.h" | |||
27 | #include "llvm/Support/ConvertUTF.h" | |||
28 | #include "llvm/Support/Debug.h" | |||
29 | #include "llvm/Support/ErrorHandling.h" | |||
30 | #include "llvm/Support/Host.h" | |||
31 | #include "llvm/Support/ManagedStatic.h" | |||
32 | #include "llvm/Support/MemoryBuffer.h" | |||
33 | #include "llvm/Support/Path.h" | |||
34 | #include "llvm/Support/raw_ostream.h" | |||
35 | #include <cerrno> | |||
36 | #include <cstdlib> | |||
37 | #include <map> | |||
38 | #include <system_error> | |||
39 | using namespace llvm; | |||
40 | using namespace cl; | |||
41 | ||||
42 | #define DEBUG_TYPE"commandline" "commandline" | |||
43 | ||||
44 | //===----------------------------------------------------------------------===// | |||
45 | // Template instantiations and anchors. | |||
46 | // | |||
47 | namespace llvm { namespace cl { | |||
48 | TEMPLATE_INSTANTIATION(class basic_parser<bool>)template class basic_parser<bool>; | |||
49 | TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>)template class basic_parser<boolOrDefault>; | |||
50 | TEMPLATE_INSTANTIATION(class basic_parser<int>)template class basic_parser<int>; | |||
51 | TEMPLATE_INSTANTIATION(class basic_parser<unsigned>)template class basic_parser<unsigned>; | |||
52 | TEMPLATE_INSTANTIATION(class basic_parser<unsigned long long>)template class basic_parser<unsigned long long>; | |||
53 | TEMPLATE_INSTANTIATION(class basic_parser<double>)template class basic_parser<double>; | |||
54 | TEMPLATE_INSTANTIATION(class basic_parser<float>)template class basic_parser<float>; | |||
55 | TEMPLATE_INSTANTIATION(class basic_parser<std::string>)template class basic_parser<std::string>; | |||
56 | TEMPLATE_INSTANTIATION(class basic_parser<char>)template class basic_parser<char>; | |||
57 | ||||
58 | TEMPLATE_INSTANTIATION(class opt<unsigned>)template class opt<unsigned>; | |||
59 | TEMPLATE_INSTANTIATION(class opt<int>)template class opt<int>; | |||
60 | TEMPLATE_INSTANTIATION(class opt<std::string>)template class opt<std::string>; | |||
61 | TEMPLATE_INSTANTIATION(class opt<char>)template class opt<char>; | |||
62 | TEMPLATE_INSTANTIATION(class opt<bool>)template class opt<bool>; | |||
63 | } } // end namespace llvm::cl | |||
64 | ||||
65 | // Pin the vtables to this file. | |||
66 | void GenericOptionValue::anchor() {} | |||
67 | void OptionValue<boolOrDefault>::anchor() {} | |||
68 | void OptionValue<std::string>::anchor() {} | |||
69 | void Option::anchor() {} | |||
70 | void basic_parser_impl::anchor() {} | |||
71 | void parser<bool>::anchor() {} | |||
72 | void parser<boolOrDefault>::anchor() {} | |||
73 | void parser<int>::anchor() {} | |||
74 | void parser<unsigned>::anchor() {} | |||
75 | void parser<unsigned long long>::anchor() {} | |||
76 | void parser<double>::anchor() {} | |||
77 | void parser<float>::anchor() {} | |||
78 | void parser<std::string>::anchor() {} | |||
79 | void parser<char>::anchor() {} | |||
80 | void StringSaver::anchor() {} | |||
81 | ||||
82 | //===----------------------------------------------------------------------===// | |||
83 | ||||
84 | // Globals for name and overview of program. Program name is not a string to | |||
85 | // avoid static ctor/dtor issues. | |||
86 | static char ProgramName[80] = "<premain>"; | |||
87 | static const char *ProgramOverview = nullptr; | |||
88 | ||||
89 | // This collects additional help to be printed. | |||
90 | static ManagedStatic<std::vector<const char*> > MoreHelp; | |||
91 | ||||
92 | extrahelp::extrahelp(const char *Help) | |||
93 | : morehelp(Help) { | |||
94 | MoreHelp->push_back(Help); | |||
95 | } | |||
96 | ||||
97 | static bool OptionListChanged = false; | |||
98 | ||||
99 | // MarkOptionsChanged - Internal helper function. | |||
100 | void cl::MarkOptionsChanged() { | |||
101 | OptionListChanged = true; | |||
102 | } | |||
103 | ||||
104 | /// RegisteredOptionList - This is the list of the command line options that | |||
105 | /// have statically constructed themselves. | |||
106 | static Option *RegisteredOptionList = nullptr; | |||
107 | ||||
108 | void Option::addArgument() { | |||
109 | assert(!NextRegistered && "argument multiply registered!")((!NextRegistered && "argument multiply registered!") ? static_cast<void> (0) : __assert_fail ("!NextRegistered && \"argument multiply registered!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224007/lib/Support/CommandLine.cpp" , 109, __PRETTY_FUNCTION__)); | |||
110 | ||||
111 | NextRegistered = RegisteredOptionList; | |||
112 | RegisteredOptionList = this; | |||
113 | MarkOptionsChanged(); | |||
114 | } | |||
115 | ||||
116 | void Option::removeArgument() { | |||
117 | if (RegisteredOptionList == this) { | |||
118 | RegisteredOptionList = NextRegistered; | |||
119 | MarkOptionsChanged(); | |||
120 | return; | |||
121 | } | |||
122 | Option *O = RegisteredOptionList; | |||
123 | for (; O->NextRegistered != this; O = O->NextRegistered) | |||
124 | ; | |||
125 | O->NextRegistered = NextRegistered; | |||
126 | MarkOptionsChanged(); | |||
127 | } | |||
128 | ||||
129 | // This collects the different option categories that have been registered. | |||
130 | typedef SmallPtrSet<OptionCategory*,16> OptionCatSet; | |||
131 | static ManagedStatic<OptionCatSet> RegisteredOptionCategories; | |||
132 | ||||
133 | // Initialise the general option category. | |||
134 | OptionCategory llvm::cl::GeneralCategory("General options"); | |||
135 | ||||
136 | void OptionCategory::registerCategory() { | |||
137 | assert(std::count_if(RegisteredOptionCategories->begin(),((std::count_if(RegisteredOptionCategories->begin(), RegisteredOptionCategories ->end(), [this](const OptionCategory *Category) { return getName () == Category->getName(); }) == 0 && "Duplicate option categories" ) ? static_cast<void> (0) : __assert_fail ("std::count_if(RegisteredOptionCategories->begin(), RegisteredOptionCategories->end(), [this](const OptionCategory *Category) { return getName() == Category->getName(); }) == 0 && \"Duplicate option categories\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224007/lib/Support/CommandLine.cpp" , 141, __PRETTY_FUNCTION__)) | |||
138 | RegisteredOptionCategories->end(),((std::count_if(RegisteredOptionCategories->begin(), RegisteredOptionCategories ->end(), [this](const OptionCategory *Category) { return getName () == Category->getName(); }) == 0 && "Duplicate option categories" ) ? static_cast<void> (0) : __assert_fail ("std::count_if(RegisteredOptionCategories->begin(), RegisteredOptionCategories->end(), [this](const OptionCategory *Category) { return getName() == Category->getName(); }) == 0 && \"Duplicate option categories\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224007/lib/Support/CommandLine.cpp" , 141, __PRETTY_FUNCTION__)) | |||
139 | [this](const OptionCategory *Category) {((std::count_if(RegisteredOptionCategories->begin(), RegisteredOptionCategories ->end(), [this](const OptionCategory *Category) { return getName () == Category->getName(); }) == 0 && "Duplicate option categories" ) ? static_cast<void> (0) : __assert_fail ("std::count_if(RegisteredOptionCategories->begin(), RegisteredOptionCategories->end(), [this](const OptionCategory *Category) { return getName() == Category->getName(); }) == 0 && \"Duplicate option categories\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224007/lib/Support/CommandLine.cpp" , 141, __PRETTY_FUNCTION__)) | |||
140 | return getName() == Category->getName();((std::count_if(RegisteredOptionCategories->begin(), RegisteredOptionCategories ->end(), [this](const OptionCategory *Category) { return getName () == Category->getName(); }) == 0 && "Duplicate option categories" ) ? static_cast<void> (0) : __assert_fail ("std::count_if(RegisteredOptionCategories->begin(), RegisteredOptionCategories->end(), [this](const OptionCategory *Category) { return getName() == Category->getName(); }) == 0 && \"Duplicate option categories\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224007/lib/Support/CommandLine.cpp" , 141, __PRETTY_FUNCTION__)) | |||
141 | }) == 0 && "Duplicate option categories")((std::count_if(RegisteredOptionCategories->begin(), RegisteredOptionCategories ->end(), [this](const OptionCategory *Category) { return getName () == Category->getName(); }) == 0 && "Duplicate option categories" ) ? static_cast<void> (0) : __assert_fail ("std::count_if(RegisteredOptionCategories->begin(), RegisteredOptionCategories->end(), [this](const OptionCategory *Category) { return getName() == Category->getName(); }) == 0 && \"Duplicate option categories\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224007/lib/Support/CommandLine.cpp" , 141, __PRETTY_FUNCTION__)); | |||
142 | ||||
143 | RegisteredOptionCategories->insert(this); | |||
144 | } | |||
145 | ||||
146 | //===----------------------------------------------------------------------===// | |||
147 | // Basic, shared command line option processing machinery. | |||
148 | // | |||
149 | ||||
150 | /// GetOptionInfo - Scan the list of registered options, turning them into data | |||
151 | /// structures that are easier to handle. | |||
152 | static void GetOptionInfo(SmallVectorImpl<Option*> &PositionalOpts, | |||
153 | SmallVectorImpl<Option*> &SinkOpts, | |||
154 | StringMap<Option*> &OptionsMap) { | |||
155 | bool HadErrors = false; | |||
156 | SmallVector<const char*, 16> OptionNames; | |||
157 | Option *CAOpt = nullptr; // The ConsumeAfter option if it exists. | |||
158 | for (Option *O = RegisteredOptionList; O; O = O->getNextRegisteredOption()) { | |||
159 | // If this option wants to handle multiple option names, get the full set. | |||
160 | // This handles enum options like "-O1 -O2" etc. | |||
161 | O->getExtraOptionNames(OptionNames); | |||
162 | if (O->ArgStr[0]) | |||
163 | OptionNames.push_back(O->ArgStr); | |||
164 | ||||
165 | // Handle named options. | |||
166 | for (size_t i = 0, e = OptionNames.size(); i != e; ++i) { | |||
167 | // Add argument to the argument map! | |||
168 | if (!OptionsMap.insert(std::make_pair(OptionNames[i], O)).second) { | |||
169 | errs() << ProgramName << ": CommandLine Error: Option '" | |||
170 | << OptionNames[i] << "' registered more than once!\n"; | |||
171 | HadErrors = true; | |||
172 | } | |||
173 | } | |||
174 | ||||
175 | OptionNames.clear(); | |||
176 | ||||
177 | // Remember information about positional options. | |||
178 | if (O->getFormattingFlag() == cl::Positional) | |||
179 | PositionalOpts.push_back(O); | |||
180 | else if (O->getMiscFlags() & cl::Sink) // Remember sink options | |||
181 | SinkOpts.push_back(O); | |||
182 | else if (O->getNumOccurrencesFlag() == cl::ConsumeAfter) { | |||
183 | if (CAOpt) { | |||
184 | O->error("Cannot specify more than one option with cl::ConsumeAfter!"); | |||
185 | HadErrors = true; | |||
186 | } | |||
187 | CAOpt = O; | |||
188 | } | |||
189 | } | |||
190 | ||||
191 | if (CAOpt) | |||
192 | PositionalOpts.push_back(CAOpt); | |||
193 | ||||
194 | // Make sure that they are in order of registration not backwards. | |||
195 | std::reverse(PositionalOpts.begin(), PositionalOpts.end()); | |||
196 | ||||
197 | // Fail hard if there were errors. These are strictly unrecoverable and | |||
198 | // indicate serious issues such as conflicting option names or an incorrectly | |||
199 | // linked LLVM distribution. | |||
200 | if (HadErrors) | |||
201 | report_fatal_error("inconsistency in registered CommandLine options"); | |||
202 | } | |||
203 | ||||
204 | ||||
205 | /// LookupOption - Lookup the option specified by the specified option on the | |||
206 | /// command line. If there is a value specified (after an equal sign) return | |||
207 | /// that as well. This assumes that leading dashes have already been stripped. | |||
208 | static Option *LookupOption(StringRef &Arg, StringRef &Value, | |||
209 | const StringMap<Option*> &OptionsMap) { | |||
210 | // Reject all dashes. | |||
211 | if (Arg.empty()) return nullptr; | |||
212 | ||||
213 | size_t EqualPos = Arg.find('='); | |||
214 | ||||
215 | // If we have an equals sign, remember the value. | |||
216 | if (EqualPos == StringRef::npos) { | |||
217 | // Look up the option. | |||
218 | StringMap<Option*>::const_iterator I = OptionsMap.find(Arg); | |||
219 | return I != OptionsMap.end() ? I->second : nullptr; | |||
220 | } | |||
221 | ||||
222 | // If the argument before the = is a valid option name, we match. If not, | |||
223 | // return Arg unmolested. | |||
224 | StringMap<Option*>::const_iterator I = | |||
225 | OptionsMap.find(Arg.substr(0, EqualPos)); | |||
226 | if (I == OptionsMap.end()) return nullptr; | |||
227 | ||||
228 | Value = Arg.substr(EqualPos+1); | |||
229 | Arg = Arg.substr(0, EqualPos); | |||
230 | return I->second; | |||
231 | } | |||
232 | ||||
233 | /// LookupNearestOption - Lookup the closest match to the option specified by | |||
234 | /// the specified option on the command line. If there is a value specified | |||
235 | /// (after an equal sign) return that as well. This assumes that leading dashes | |||
236 | /// have already been stripped. | |||
237 | static Option *LookupNearestOption(StringRef Arg, | |||
238 | const StringMap<Option*> &OptionsMap, | |||
239 | std::string &NearestString) { | |||
240 | // Reject all dashes. | |||
241 | if (Arg.empty()) return nullptr; | |||
242 | ||||
243 | // Split on any equal sign. | |||
244 | std::pair<StringRef, StringRef> SplitArg = Arg.split('='); | |||
245 | StringRef &LHS = SplitArg.first; // LHS == Arg when no '=' is present. | |||
246 | StringRef &RHS = SplitArg.second; | |||
247 | ||||
248 | // Find the closest match. | |||
249 | Option *Best = nullptr; | |||
250 | unsigned BestDistance = 0; | |||
251 | for (StringMap<Option*>::const_iterator it = OptionsMap.begin(), | |||
252 | ie = OptionsMap.end(); it != ie; ++it) { | |||
253 | Option *O = it->second; | |||
254 | SmallVector<const char*, 16> OptionNames; | |||
255 | O->getExtraOptionNames(OptionNames); | |||
256 | if (O->ArgStr[0]) | |||
257 | OptionNames.push_back(O->ArgStr); | |||
258 | ||||
259 | bool PermitValue = O->getValueExpectedFlag() != cl::ValueDisallowed; | |||
260 | StringRef Flag = PermitValue ? LHS : Arg; | |||
261 | for (size_t i = 0, e = OptionNames.size(); i != e; ++i) { | |||
262 | StringRef Name = OptionNames[i]; | |||
263 | unsigned Distance = StringRef(Name).edit_distance( | |||
264 | Flag, /*AllowReplacements=*/true, /*MaxEditDistance=*/BestDistance); | |||
265 | if (!Best || Distance < BestDistance) { | |||
266 | Best = O; | |||
267 | BestDistance = Distance; | |||
268 | if (RHS.empty() || !PermitValue) | |||
269 | NearestString = OptionNames[i]; | |||
270 | else | |||
271 | NearestString = std::string(OptionNames[i]) + "=" + RHS.str(); | |||
272 | } | |||
273 | } | |||
274 | } | |||
275 | ||||
276 | return Best; | |||
277 | } | |||
278 | ||||
279 | /// CommaSeparateAndAddOccurrence - A wrapper around Handler->addOccurrence() | |||
280 | /// that does special handling of cl::CommaSeparated options. | |||
281 | static bool CommaSeparateAndAddOccurrence(Option *Handler, unsigned pos, | |||
282 | StringRef ArgName, StringRef Value, | |||
283 | bool MultiArg = false) { | |||
284 | // Check to see if this option accepts a comma separated list of values. If | |||
285 | // it does, we have to split up the value into multiple values. | |||
286 | if (Handler->getMiscFlags() & CommaSeparated) { | |||
287 | StringRef Val(Value); | |||
288 | StringRef::size_type Pos = Val.find(','); | |||
289 | ||||
290 | while (Pos != StringRef::npos) { | |||
291 | // Process the portion before the comma. | |||
292 | if (Handler->addOccurrence(pos, ArgName, Val.substr(0, Pos), MultiArg)) | |||
293 | return true; | |||
294 | // Erase the portion before the comma, AND the comma. | |||
295 | Val = Val.substr(Pos+1); | |||
296 | Value.substr(Pos+1); // Increment the original value pointer as well. | |||
297 | // Check for another comma. | |||
298 | Pos = Val.find(','); | |||
299 | } | |||
300 | ||||
301 | Value = Val; | |||
302 | } | |||
303 | ||||
304 | if (Handler->addOccurrence(pos, ArgName, Value, MultiArg)) | |||
305 | return true; | |||
306 | ||||
307 | return false; | |||
308 | } | |||
309 | ||||
310 | /// ProvideOption - For Value, this differentiates between an empty value ("") | |||
311 | /// and a null value (StringRef()). The later is accepted for arguments that | |||
312 | /// don't allow a value (-foo) the former is rejected (-foo=). | |||
313 | static inline bool ProvideOption(Option *Handler, StringRef ArgName, | |||
314 | StringRef Value, int argc, | |||
315 | const char *const *argv, int &i) { | |||
316 | // Is this a multi-argument option? | |||
317 | unsigned NumAdditionalVals = Handler->getNumAdditionalVals(); | |||
318 | ||||
319 | // Enforce value requirements | |||
320 | switch (Handler->getValueExpectedFlag()) { | |||
321 | case ValueRequired: | |||
322 | if (!Value.data()) { // No value specified? | |||
323 | if (i+1 >= argc) | |||
324 | return Handler->error("requires a value!"); | |||
325 | // Steal the next argument, like for '-o filename' | |||
326 | Value = argv[++i]; | |||
| ||||
327 | } | |||
328 | break; | |||
329 | case ValueDisallowed: | |||
330 | if (NumAdditionalVals > 0) | |||
331 | return Handler->error("multi-valued option specified" | |||
332 | " with ValueDisallowed modifier!"); | |||
333 | ||||
334 | if (Value.data()) | |||
335 | return Handler->error("does not allow a value! '" + | |||
336 | Twine(Value) + "' specified."); | |||
337 | break; | |||
338 | case ValueOptional: | |||
339 | break; | |||
340 | } | |||
341 | ||||
342 | // If this isn't a multi-arg option, just run the handler. | |||
343 | if (NumAdditionalVals == 0) | |||
344 | return CommaSeparateAndAddOccurrence(Handler, i, ArgName, Value); | |||
345 | ||||
346 | // If it is, run the handle several times. | |||
347 | bool MultiArg = false; | |||
348 | ||||
349 | if (Value.data()) { | |||
350 | if (CommaSeparateAndAddOccurrence(Handler, i, ArgName, Value, MultiArg)) | |||
351 | return true; | |||
352 | --NumAdditionalVals; | |||
353 | MultiArg = true; | |||
354 | } | |||
355 | ||||
356 | while (NumAdditionalVals > 0) { | |||
357 | if (i+1 >= argc) | |||
358 | return Handler->error("not enough values!"); | |||
359 | Value = argv[++i]; | |||
360 | ||||
361 | if (CommaSeparateAndAddOccurrence(Handler, i, ArgName, Value, MultiArg)) | |||
362 | return true; | |||
363 | MultiArg = true; | |||
364 | --NumAdditionalVals; | |||
365 | } | |||
366 | return false; | |||
367 | } | |||
368 | ||||
369 | static bool ProvidePositionalOption(Option *Handler, StringRef Arg, int i) { | |||
370 | int Dummy = i; | |||
371 | return ProvideOption(Handler, Handler->ArgStr, Arg, 0, nullptr, Dummy); | |||
372 | } | |||
373 | ||||
374 | ||||
375 | // Option predicates... | |||
376 | static inline bool isGrouping(const Option *O) { | |||
377 | return O->getFormattingFlag() == cl::Grouping; | |||
378 | } | |||
379 | static inline bool isPrefixedOrGrouping(const Option *O) { | |||
380 | return isGrouping(O) || O->getFormattingFlag() == cl::Prefix; | |||
381 | } | |||
382 | ||||
383 | // getOptionPred - Check to see if there are any options that satisfy the | |||
384 | // specified predicate with names that are the prefixes in Name. This is | |||
385 | // checked by progressively stripping characters off of the name, checking to | |||
386 | // see if there options that satisfy the predicate. If we find one, return it, | |||
387 | // otherwise return null. | |||
388 | // | |||
389 | static Option *getOptionPred(StringRef Name, size_t &Length, | |||
390 | bool (*Pred)(const Option*), | |||
391 | const StringMap<Option*> &OptionsMap) { | |||
392 | ||||
393 | StringMap<Option*>::const_iterator OMI = OptionsMap.find(Name); | |||
394 | ||||
395 | // Loop while we haven't found an option and Name still has at least two | |||
396 | // characters in it (so that the next iteration will not be the empty | |||
397 | // string. | |||
398 | while (OMI == OptionsMap.end() && Name.size() > 1) { | |||
399 | Name = Name.substr(0, Name.size()-1); // Chop off the last character. | |||
400 | OMI = OptionsMap.find(Name); | |||
401 | } | |||
402 | ||||
403 | if (OMI != OptionsMap.end() && Pred(OMI->second)) { | |||
404 | Length = Name.size(); | |||
405 | return OMI->second; // Found one! | |||
406 | } | |||
407 | return nullptr; // No option found! | |||
408 | } | |||
409 | ||||
410 | /// HandlePrefixedOrGroupedOption - The specified argument string (which started | |||
411 | /// with at least one '-') does not fully match an available option. Check to | |||
412 | /// see if this is a prefix or grouped option. If so, split arg into output an | |||
413 | /// Arg/Value pair and return the Option to parse it with. | |||
414 | static Option *HandlePrefixedOrGroupedOption(StringRef &Arg, StringRef &Value, | |||
415 | bool &ErrorParsing, | |||
416 | const StringMap<Option*> &OptionsMap) { | |||
417 | if (Arg.size() == 1) return nullptr; | |||
418 | ||||
419 | // Do the lookup! | |||
420 | size_t Length = 0; | |||
421 | Option *PGOpt = getOptionPred(Arg, Length, isPrefixedOrGrouping, OptionsMap); | |||
422 | if (!PGOpt) return nullptr; | |||
423 | ||||
424 | // If the option is a prefixed option, then the value is simply the | |||
425 | // rest of the name... so fall through to later processing, by | |||
426 | // setting up the argument name flags and value fields. | |||
427 | if (PGOpt->getFormattingFlag() == cl::Prefix) { | |||
428 | Value = Arg.substr(Length); | |||
429 | Arg = Arg.substr(0, Length); | |||
430 | assert(OptionsMap.count(Arg) && OptionsMap.find(Arg)->second == PGOpt)((OptionsMap.count(Arg) && OptionsMap.find(Arg)->second == PGOpt) ? static_cast<void> (0) : __assert_fail ("OptionsMap.count(Arg) && OptionsMap.find(Arg)->second == PGOpt" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224007/lib/Support/CommandLine.cpp" , 430, __PRETTY_FUNCTION__)); | |||
431 | return PGOpt; | |||
432 | } | |||
433 | ||||
434 | // This must be a grouped option... handle them now. Grouping options can't | |||
435 | // have values. | |||
436 | assert(isGrouping(PGOpt) && "Broken getOptionPred!")((isGrouping(PGOpt) && "Broken getOptionPred!") ? static_cast <void> (0) : __assert_fail ("isGrouping(PGOpt) && \"Broken getOptionPred!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224007/lib/Support/CommandLine.cpp" , 436, __PRETTY_FUNCTION__)); | |||
437 | ||||
438 | do { | |||
439 | // Move current arg name out of Arg into OneArgName. | |||
440 | StringRef OneArgName = Arg.substr(0, Length); | |||
441 | Arg = Arg.substr(Length); | |||
442 | ||||
443 | // Because ValueRequired is an invalid flag for grouped arguments, | |||
444 | // we don't need to pass argc/argv in. | |||
445 | assert(PGOpt->getValueExpectedFlag() != cl::ValueRequired &&((PGOpt->getValueExpectedFlag() != cl::ValueRequired && "Option can not be cl::Grouping AND cl::ValueRequired!") ? static_cast <void> (0) : __assert_fail ("PGOpt->getValueExpectedFlag() != cl::ValueRequired && \"Option can not be cl::Grouping AND cl::ValueRequired!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224007/lib/Support/CommandLine.cpp" , 446, __PRETTY_FUNCTION__)) | |||
446 | "Option can not be cl::Grouping AND cl::ValueRequired!")((PGOpt->getValueExpectedFlag() != cl::ValueRequired && "Option can not be cl::Grouping AND cl::ValueRequired!") ? static_cast <void> (0) : __assert_fail ("PGOpt->getValueExpectedFlag() != cl::ValueRequired && \"Option can not be cl::Grouping AND cl::ValueRequired!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224007/lib/Support/CommandLine.cpp" , 446, __PRETTY_FUNCTION__)); | |||
447 | int Dummy = 0; | |||
448 | ErrorParsing |= ProvideOption(PGOpt, OneArgName, | |||
449 | StringRef(), 0, nullptr, Dummy); | |||
450 | ||||
451 | // Get the next grouping option. | |||
452 | PGOpt = getOptionPred(Arg, Length, isGrouping, OptionsMap); | |||
453 | } while (PGOpt && Length != Arg.size()); | |||
454 | ||||
455 | // Return the last option with Arg cut down to just the last one. | |||
456 | return PGOpt; | |||
457 | } | |||
458 | ||||
459 | ||||
460 | ||||
461 | static bool RequiresValue(const Option *O) { | |||
462 | return O->getNumOccurrencesFlag() == cl::Required || | |||
463 | O->getNumOccurrencesFlag() == cl::OneOrMore; | |||
464 | } | |||
465 | ||||
466 | static bool EatsUnboundedNumberOfValues(const Option *O) { | |||
467 | return O->getNumOccurrencesFlag() == cl::ZeroOrMore || | |||
468 | O->getNumOccurrencesFlag() == cl::OneOrMore; | |||
469 | } | |||
470 | ||||
471 | static bool isWhitespace(char C) { | |||
472 | return strchr(" \t\n\r\f\v", C); | |||
473 | } | |||
474 | ||||
475 | static bool isQuote(char C) { | |||
476 | return C == '\"' || C == '\''; | |||
477 | } | |||
478 | ||||
479 | static bool isGNUSpecial(char C) { | |||
480 | return strchr("\\\"\' ", C); | |||
481 | } | |||
482 | ||||
483 | void cl::TokenizeGNUCommandLine(StringRef Src, StringSaver &Saver, | |||
484 | SmallVectorImpl<const char *> &NewArgv, | |||
485 | bool MarkEOLs) { | |||
486 | SmallString<128> Token; | |||
487 | for (size_t I = 0, E = Src.size(); I != E; ++I) { | |||
488 | // Consume runs of whitespace. | |||
489 | if (Token.empty()) { | |||
490 | while (I != E && isWhitespace(Src[I])) { | |||
491 | // Mark the end of lines in response files | |||
492 | if (MarkEOLs && Src[I] == '\n') | |||
493 | NewArgv.push_back(nullptr); | |||
494 | ++I; | |||
495 | } | |||
496 | if (I == E) break; | |||
497 | } | |||
498 | ||||
499 | // Backslashes can escape backslashes, spaces, and other quotes. Otherwise | |||
500 | // they are literal. This makes it much easier to read Windows file paths. | |||
501 | if (I + 1 < E && Src[I] == '\\' && isGNUSpecial(Src[I + 1])) { | |||
502 | ++I; // Skip the escape. | |||
503 | Token.push_back(Src[I]); | |||
504 | continue; | |||
505 | } | |||
506 | ||||
507 | // Consume a quoted string. | |||
508 | if (isQuote(Src[I])) { | |||
509 | char Quote = Src[I++]; | |||
510 | while (I != E && Src[I] != Quote) { | |||
511 | // Backslashes are literal, unless they escape a special character. | |||
512 | if (Src[I] == '\\' && I + 1 != E && isGNUSpecial(Src[I + 1])) | |||
513 | ++I; | |||
514 | Token.push_back(Src[I]); | |||
515 | ++I; | |||
516 | } | |||
517 | if (I == E) break; | |||
518 | continue; | |||
519 | } | |||
520 | ||||
521 | // End the token if this is whitespace. | |||
522 | if (isWhitespace(Src[I])) { | |||
523 | if (!Token.empty()) | |||
524 | NewArgv.push_back(Saver.SaveString(Token.c_str())); | |||
525 | Token.clear(); | |||
526 | continue; | |||
527 | } | |||
528 | ||||
529 | // This is a normal character. Append it. | |||
530 | Token.push_back(Src[I]); | |||
531 | } | |||
532 | ||||
533 | // Append the last token after hitting EOF with no whitespace. | |||
534 | if (!Token.empty()) | |||
535 | NewArgv.push_back(Saver.SaveString(Token.c_str())); | |||
536 | // Mark the end of response files | |||
537 | if (MarkEOLs) | |||
538 | NewArgv.push_back(nullptr); | |||
539 | } | |||
540 | ||||
541 | /// Backslashes are interpreted in a rather complicated way in the Windows-style | |||
542 | /// command line, because backslashes are used both to separate path and to | |||
543 | /// escape double quote. This method consumes runs of backslashes as well as the | |||
544 | /// following double quote if it's escaped. | |||
545 | /// | |||
546 | /// * If an even number of backslashes is followed by a double quote, one | |||
547 | /// backslash is output for every pair of backslashes, and the last double | |||
548 | /// quote remains unconsumed. The double quote will later be interpreted as | |||
549 | /// the start or end of a quoted string in the main loop outside of this | |||
550 | /// function. | |||
551 | /// | |||
552 | /// * If an odd number of backslashes is followed by a double quote, one | |||
553 | /// backslash is output for every pair of backslashes, and a double quote is | |||
554 | /// output for the last pair of backslash-double quote. The double quote is | |||
555 | /// consumed in this case. | |||
556 | /// | |||
557 | /// * Otherwise, backslashes are interpreted literally. | |||
558 | static size_t parseBackslash(StringRef Src, size_t I, SmallString<128> &Token) { | |||
559 | size_t E = Src.size(); | |||
560 | int BackslashCount = 0; | |||
561 | // Skip the backslashes. | |||
562 | do { | |||
563 | ++I; | |||
564 | ++BackslashCount; | |||
565 | } while (I != E && Src[I] == '\\'); | |||
566 | ||||
567 | bool FollowedByDoubleQuote = (I != E && Src[I] == '"'); | |||
568 | if (FollowedByDoubleQuote) { | |||
569 | Token.append(BackslashCount / 2, '\\'); | |||
570 | if (BackslashCount % 2 == 0) | |||
571 | return I - 1; | |||
572 | Token.push_back('"'); | |||
573 | return I; | |||
574 | } | |||
575 | Token.append(BackslashCount, '\\'); | |||
576 | return I - 1; | |||
577 | } | |||
578 | ||||
579 | void cl::TokenizeWindowsCommandLine(StringRef Src, StringSaver &Saver, | |||
580 | SmallVectorImpl<const char *> &NewArgv, | |||
581 | bool MarkEOLs) { | |||
582 | SmallString<128> Token; | |||
583 | ||||
584 | // This is a small state machine to consume characters until it reaches the | |||
585 | // end of the source string. | |||
586 | enum { INIT, UNQUOTED, QUOTED } State = INIT; | |||
587 | for (size_t I = 0, E = Src.size(); I != E; ++I) { | |||
588 | // INIT state indicates that the current input index is at the start of | |||
589 | // the string or between tokens. | |||
590 | if (State == INIT) { | |||
591 | if (isWhitespace(Src[I])) { | |||
592 | // Mark the end of lines in response files | |||
593 | if (MarkEOLs && Src[I] == '\n') | |||
594 | NewArgv.push_back(nullptr); | |||
595 | continue; | |||
596 | } | |||
597 | if (Src[I] == '"') { | |||
598 | State = QUOTED; | |||
599 | continue; | |||
600 | } | |||
601 | if (Src[I] == '\\') { | |||
602 | I = parseBackslash(Src, I, Token); | |||
603 | State = UNQUOTED; | |||
604 | continue; | |||
605 | } | |||
606 | Token.push_back(Src[I]); | |||
607 | State = UNQUOTED; | |||
608 | continue; | |||
609 | } | |||
610 | ||||
611 | // UNQUOTED state means that it's reading a token not quoted by double | |||
612 | // quotes. | |||
613 | if (State == UNQUOTED) { | |||
614 | // Whitespace means the end of the token. | |||
615 | if (isWhitespace(Src[I])) { | |||
616 | NewArgv.push_back(Saver.SaveString(Token.c_str())); | |||
617 | Token.clear(); | |||
618 | State = INIT; | |||
619 | // Mark the end of lines in response files | |||
620 | if (MarkEOLs && Src[I] == '\n') | |||
621 | NewArgv.push_back(nullptr); | |||
622 | continue; | |||
623 | } | |||
624 | if (Src[I] == '"') { | |||
625 | State = QUOTED; | |||
626 | continue; | |||
627 | } | |||
628 | if (Src[I] == '\\') { | |||
629 | I = parseBackslash(Src, I, Token); | |||
630 | continue; | |||
631 | } | |||
632 | Token.push_back(Src[I]); | |||
633 | continue; | |||
634 | } | |||
635 | ||||
636 | // QUOTED state means that it's reading a token quoted by double quotes. | |||
637 | if (State == QUOTED) { | |||
638 | if (Src[I] == '"') { | |||
639 | State = UNQUOTED; | |||
640 | continue; | |||
641 | } | |||
642 | if (Src[I] == '\\') { | |||
643 | I = parseBackslash(Src, I, Token); | |||
644 | continue; | |||
645 | } | |||
646 | Token.push_back(Src[I]); | |||
647 | } | |||
648 | } | |||
649 | // Append the last token after hitting EOF with no whitespace. | |||
650 | if (!Token.empty()) | |||
651 | NewArgv.push_back(Saver.SaveString(Token.c_str())); | |||
652 | // Mark the end of response files | |||
653 | if (MarkEOLs) | |||
654 | NewArgv.push_back(nullptr); | |||
655 | } | |||
656 | ||||
657 | static bool ExpandResponseFile(const char *FName, StringSaver &Saver, | |||
658 | TokenizerCallback Tokenizer, | |||
659 | SmallVectorImpl<const char *> &NewArgv, | |||
660 | bool MarkEOLs = false) { | |||
661 | ErrorOr<std::unique_ptr<MemoryBuffer>> MemBufOrErr = | |||
662 | MemoryBuffer::getFile(FName); | |||
663 | if (!MemBufOrErr) | |||
664 | return false; | |||
665 | MemoryBuffer &MemBuf = *MemBufOrErr.get(); | |||
666 | StringRef Str(MemBuf.getBufferStart(), MemBuf.getBufferSize()); | |||
667 | ||||
668 | // If we have a UTF-16 byte order mark, convert to UTF-8 for parsing. | |||
669 | ArrayRef<char> BufRef(MemBuf.getBufferStart(), MemBuf.getBufferEnd()); | |||
670 | std::string UTF8Buf; | |||
671 | if (hasUTF16ByteOrderMark(BufRef)) { | |||
672 | if (!convertUTF16ToUTF8String(BufRef, UTF8Buf)) | |||
673 | return false; | |||
674 | Str = StringRef(UTF8Buf); | |||
675 | } | |||
676 | ||||
677 | // Tokenize the contents into NewArgv. | |||
678 | Tokenizer(Str, Saver, NewArgv, MarkEOLs); | |||
679 | ||||
680 | return true; | |||
681 | } | |||
682 | ||||
683 | /// \brief Expand response files on a command line recursively using the given | |||
684 | /// StringSaver and tokenization strategy. | |||
685 | bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, | |||
686 | SmallVectorImpl<const char *> &Argv, | |||
687 | bool MarkEOLs) { | |||
688 | unsigned RspFiles = 0; | |||
689 | bool AllExpanded = true; | |||
690 | ||||
691 | // Don't cache Argv.size() because it can change. | |||
692 | for (unsigned I = 0; I != Argv.size(); ) { | |||
693 | const char *Arg = Argv[I]; | |||
694 | // Check if it is an EOL marker | |||
695 | if (Arg == nullptr) { | |||
696 | ++I; | |||
697 | continue; | |||
698 | } | |||
699 | if (Arg[0] != '@') { | |||
700 | ++I; | |||
701 | continue; | |||
702 | } | |||
703 | ||||
704 | // If we have too many response files, leave some unexpanded. This avoids | |||
705 | // crashing on self-referential response files. | |||
706 | if (RspFiles++ > 20) | |||
707 | return false; | |||
708 | ||||
709 | // Replace this response file argument with the tokenization of its | |||
710 | // contents. Nested response files are expanded in subsequent iterations. | |||
711 | // FIXME: If a nested response file uses a relative path, is it relative to | |||
712 | // the cwd of the process or the response file? | |||
713 | SmallVector<const char *, 0> ExpandedArgv; | |||
714 | if (!ExpandResponseFile(Arg + 1, Saver, Tokenizer, ExpandedArgv, | |||
715 | MarkEOLs)) { | |||
716 | // We couldn't read this file, so we leave it in the argument stream and | |||
717 | // move on. | |||
718 | AllExpanded = false; | |||
719 | ++I; | |||
720 | continue; | |||
721 | } | |||
722 | Argv.erase(Argv.begin() + I); | |||
723 | Argv.insert(Argv.begin() + I, ExpandedArgv.begin(), ExpandedArgv.end()); | |||
724 | } | |||
725 | return AllExpanded; | |||
726 | } | |||
727 | ||||
728 | namespace { | |||
729 | class StrDupSaver : public StringSaver { | |||
730 | std::vector<char*> Dups; | |||
731 | public: | |||
732 | ~StrDupSaver() { | |||
733 | for (std::vector<char *>::iterator I = Dups.begin(), E = Dups.end(); | |||
734 | I != E; ++I) { | |||
735 | char *Dup = *I; | |||
736 | free(Dup); | |||
737 | } | |||
738 | } | |||
739 | const char *SaveString(const char *Str) override { | |||
740 | char *Dup = strdup(Str); | |||
741 | Dups.push_back(Dup); | |||
742 | return Dup; | |||
743 | } | |||
744 | }; | |||
745 | } | |||
746 | ||||
747 | /// ParseEnvironmentOptions - An alternative entry point to the | |||
748 | /// CommandLine library, which allows you to read the program's name | |||
749 | /// from the caller (as PROGNAME) and its command-line arguments from | |||
750 | /// an environment variable (whose name is given in ENVVAR). | |||
751 | /// | |||
752 | void cl::ParseEnvironmentOptions(const char *progName, const char *envVar, | |||
753 | const char *Overview) { | |||
754 | // Check args. | |||
755 | assert(progName && "Program name not specified")((progName && "Program name not specified") ? static_cast <void> (0) : __assert_fail ("progName && \"Program name not specified\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224007/lib/Support/CommandLine.cpp" , 755, __PRETTY_FUNCTION__)); | |||
756 | assert(envVar && "Environment variable name missing")((envVar && "Environment variable name missing") ? static_cast <void> (0) : __assert_fail ("envVar && \"Environment variable name missing\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224007/lib/Support/CommandLine.cpp" , 756, __PRETTY_FUNCTION__)); | |||
757 | ||||
758 | // Get the environment variable they want us to parse options out of. | |||
759 | const char *envValue = getenv(envVar); | |||
760 | if (!envValue) | |||
761 | return; | |||
762 | ||||
763 | // Get program's "name", which we wouldn't know without the caller | |||
764 | // telling us. | |||
765 | SmallVector<const char *, 20> newArgv; | |||
766 | StrDupSaver Saver; | |||
767 | newArgv.push_back(Saver.SaveString(progName)); | |||
768 | ||||
769 | // Parse the value of the environment variable into a "command line" | |||
770 | // and hand it off to ParseCommandLineOptions(). | |||
771 | TokenizeGNUCommandLine(envValue, Saver, newArgv); | |||
772 | int newArgc = static_cast<int>(newArgv.size()); | |||
773 | ParseCommandLineOptions(newArgc, &newArgv[0], Overview); | |||
774 | } | |||
775 | ||||
776 | void cl::ParseCommandLineOptions(int argc, const char * const *argv, | |||
777 | const char *Overview) { | |||
778 | // Process all registered options. | |||
779 | SmallVector<Option*, 4> PositionalOpts; | |||
780 | SmallVector<Option*, 4> SinkOpts; | |||
781 | StringMap<Option*> Opts; | |||
782 | GetOptionInfo(PositionalOpts, SinkOpts, Opts); | |||
783 | ||||
784 | assert((!Opts.empty() || !PositionalOpts.empty()) &&(((!Opts.empty() || !PositionalOpts.empty()) && "No options specified!" ) ? static_cast<void> (0) : __assert_fail ("(!Opts.empty() || !PositionalOpts.empty()) && \"No options specified!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224007/lib/Support/CommandLine.cpp" , 785, __PRETTY_FUNCTION__)) | |||
785 | "No options specified!")(((!Opts.empty() || !PositionalOpts.empty()) && "No options specified!" ) ? static_cast<void> (0) : __assert_fail ("(!Opts.empty() || !PositionalOpts.empty()) && \"No options specified!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224007/lib/Support/CommandLine.cpp" , 785, __PRETTY_FUNCTION__)); | |||
786 | ||||
787 | // Expand response files. | |||
788 | SmallVector<const char *, 20> newArgv; | |||
789 | for (int i = 0; i != argc; ++i) | |||
| ||||
790 | newArgv.push_back(argv[i]); | |||
791 | StrDupSaver Saver; | |||
792 | ExpandResponseFiles(Saver, TokenizeGNUCommandLine, newArgv); | |||
793 | argv = &newArgv[0]; | |||
794 | argc = static_cast<int>(newArgv.size()); | |||
795 | ||||
796 | // Copy the program name into ProgName, making sure not to overflow it. | |||
797 | StringRef ProgName = sys::path::filename(argv[0]); | |||
798 | size_t Len = std::min(ProgName.size(), size_t(79)); | |||
799 | memcpy(ProgramName, ProgName.data(), Len); | |||
800 | ProgramName[Len] = '\0'; | |||
801 | ||||
802 | ProgramOverview = Overview; | |||
803 | bool ErrorParsing = false; | |||
804 | ||||
805 | // Check out the positional arguments to collect information about them. | |||
806 | unsigned NumPositionalRequired = 0; | |||
807 | ||||
808 | // Determine whether or not there are an unlimited number of positionals | |||
809 | bool HasUnlimitedPositionals = false; | |||
810 | ||||
811 | Option *ConsumeAfterOpt = nullptr; | |||
812 | if (!PositionalOpts.empty()) { | |||
813 | if (PositionalOpts[0]->getNumOccurrencesFlag() == cl::ConsumeAfter) { | |||
814 | assert(PositionalOpts.size() > 1 &&((PositionalOpts.size() > 1 && "Cannot specify cl::ConsumeAfter without a positional argument!" ) ? static_cast<void> (0) : __assert_fail ("PositionalOpts.size() > 1 && \"Cannot specify cl::ConsumeAfter without a positional argument!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224007/lib/Support/CommandLine.cpp" , 815, __PRETTY_FUNCTION__)) | |||
815 | "Cannot specify cl::ConsumeAfter without a positional argument!")((PositionalOpts.size() > 1 && "Cannot specify cl::ConsumeAfter without a positional argument!" ) ? static_cast<void> (0) : __assert_fail ("PositionalOpts.size() > 1 && \"Cannot specify cl::ConsumeAfter without a positional argument!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224007/lib/Support/CommandLine.cpp" , 815, __PRETTY_FUNCTION__)); | |||
816 | ConsumeAfterOpt = PositionalOpts[0]; | |||
817 | } | |||
818 | ||||
819 | // Calculate how many positional values are _required_. | |||
820 | bool UnboundedFound = false; | |||
821 | for (size_t i = ConsumeAfterOpt ? 1 : 0, e = PositionalOpts.size(); | |||
822 | i != e; ++i) { | |||
823 | Option *Opt = PositionalOpts[i]; | |||
824 | if (RequiresValue(Opt)) | |||
825 | ++NumPositionalRequired; | |||
826 | else if (ConsumeAfterOpt) { | |||
827 | // ConsumeAfter cannot be combined with "optional" positional options | |||
828 | // unless there is only one positional argument... | |||
829 | if (PositionalOpts.size() > 2) | |||
830 | ErrorParsing |= | |||
831 | Opt->error("error - this positional option will never be matched, " | |||
832 | "because it does not Require a value, and a " | |||
833 | "cl::ConsumeAfter option is active!"); | |||
834 | } else if (UnboundedFound && !Opt->ArgStr[0]) { | |||
835 | // This option does not "require" a value... Make sure this option is | |||
836 | // not specified after an option that eats all extra arguments, or this | |||
837 | // one will never get any! | |||
838 | // | |||
839 | ErrorParsing |= Opt->error("error - option can never match, because " | |||
840 | "another positional argument will match an " | |||
841 | "unbounded number of values, and this option" | |||
842 | " does not require a value!"); | |||
843 | } | |||
844 | UnboundedFound |= EatsUnboundedNumberOfValues(Opt); | |||
845 | } | |||
846 | HasUnlimitedPositionals = UnboundedFound || ConsumeAfterOpt; | |||
847 | } | |||
848 | ||||
849 | // PositionalVals - A vector of "positional" arguments we accumulate into | |||
850 | // the process at the end. | |||
851 | // | |||
852 | SmallVector<std::pair<StringRef,unsigned>, 4> PositionalVals; | |||
853 | ||||
854 | // If the program has named positional arguments, and the name has been run | |||
855 | // across, keep track of which positional argument was named. Otherwise put | |||
856 | // the positional args into the PositionalVals list... | |||
857 | Option *ActivePositionalArg = nullptr; | |||
858 | ||||
859 | // Loop over all of the arguments... processing them. | |||
860 | bool DashDashFound = false; // Have we read '--'? | |||
861 | for (int i = 1; i < argc; ++i) { | |||
862 | Option *Handler = nullptr; | |||
863 | Option *NearestHandler = nullptr; | |||
864 | std::string NearestHandlerString; | |||
865 | StringRef Value; | |||
866 | StringRef ArgName = ""; | |||
867 | ||||
868 | // If the option list changed, this means that some command line | |||
869 | // option has just been registered or deregistered. This can occur in | |||
870 | // response to things like -load, etc. If this happens, rescan the options. | |||
871 | if (OptionListChanged) { | |||
872 | PositionalOpts.clear(); | |||
873 | SinkOpts.clear(); | |||
874 | Opts.clear(); | |||
875 | GetOptionInfo(PositionalOpts, SinkOpts, Opts); | |||
876 | OptionListChanged = false; | |||
877 | } | |||
878 | ||||
879 | // Check to see if this is a positional argument. This argument is | |||
880 | // considered to be positional if it doesn't start with '-', if it is "-" | |||
881 | // itself, or if we have seen "--" already. | |||
882 | // | |||
883 | if (argv[i][0] != '-' || argv[i][1] == 0 || DashDashFound) { | |||
884 | // Positional argument! | |||
885 | if (ActivePositionalArg) { | |||
886 | ProvidePositionalOption(ActivePositionalArg, argv[i], i); | |||
887 | continue; // We are done! | |||
888 | } | |||
889 | ||||
890 | if (!PositionalOpts.empty()) { | |||
891 | PositionalVals.push_back(std::make_pair(argv[i],i)); | |||
892 | ||||
893 | // All of the positional arguments have been fulfulled, give the rest to | |||
894 | // the consume after option... if it's specified... | |||
895 | // | |||
896 | if (PositionalVals.size() >= NumPositionalRequired && ConsumeAfterOpt) { | |||
897 | for (++i; i < argc; ++i) | |||
898 | PositionalVals.push_back(std::make_pair(argv[i],i)); | |||
899 | break; // Handle outside of the argument processing loop... | |||
900 | } | |||
901 | ||||
902 | // Delay processing positional arguments until the end... | |||
903 | continue; | |||
904 | } | |||
905 | } else if (argv[i][0] == '-' && argv[i][1] == '-' && argv[i][2] == 0 && | |||
906 | !DashDashFound) { | |||
907 | DashDashFound = true; // This is the mythical "--"? | |||
908 | continue; // Don't try to process it as an argument itself. | |||
909 | } else if (ActivePositionalArg && | |||
910 | (ActivePositionalArg->getMiscFlags() & PositionalEatsArgs)) { | |||
911 | // If there is a positional argument eating options, check to see if this | |||
912 | // option is another positional argument. If so, treat it as an argument, | |||
913 | // otherwise feed it to the eating positional. | |||
914 | ArgName = argv[i]+1; | |||
915 | // Eat leading dashes. | |||
916 | while (!ArgName.empty() && ArgName[0] == '-') | |||
917 | ArgName = ArgName.substr(1); | |||
918 | ||||
919 | Handler = LookupOption(ArgName, Value, Opts); | |||
920 | if (!Handler || Handler->getFormattingFlag() != cl::Positional) { | |||
921 | ProvidePositionalOption(ActivePositionalArg, argv[i], i); | |||
922 | continue; // We are done! | |||
923 | } | |||
924 | ||||
925 | } else { // We start with a '-', must be an argument. | |||
926 | ArgName = argv[i]+1; | |||
927 | // Eat leading dashes. | |||
928 | while (!ArgName.empty() && ArgName[0] == '-') | |||
929 | ArgName = ArgName.substr(1); | |||
930 | ||||
931 | Handler = LookupOption(ArgName, Value, Opts); | |||
932 | ||||
933 | // Check to see if this "option" is really a prefixed or grouped argument. | |||
934 | if (!Handler) | |||
935 | Handler = HandlePrefixedOrGroupedOption(ArgName, Value, | |||
936 | ErrorParsing, Opts); | |||
937 | ||||
938 | // Otherwise, look for the closest available option to report to the user | |||
939 | // in the upcoming error. | |||
940 | if (!Handler && SinkOpts.empty()) | |||
941 | NearestHandler = LookupNearestOption(ArgName, Opts, | |||
942 | NearestHandlerString); | |||
943 | } | |||
944 | ||||
945 | if (!Handler) { | |||
946 | if (SinkOpts.empty()) { | |||
947 | errs() << ProgramName << ": Unknown command line argument '" | |||
948 | << argv[i] << "'. Try: '" << argv[0] << " -help'\n"; | |||
949 | ||||
950 | if (NearestHandler) { | |||
951 | // If we know a near match, report it as well. | |||
952 | errs() << ProgramName << ": Did you mean '-" | |||
953 | << NearestHandlerString << "'?\n"; | |||
954 | } | |||
955 | ||||
956 | ErrorParsing = true; | |||
957 | } else { | |||
958 | for (SmallVectorImpl<Option*>::iterator I = SinkOpts.begin(), | |||
959 | E = SinkOpts.end(); I != E ; ++I) | |||
960 | (*I)->addOccurrence(i, "", argv[i]); | |||
961 | } | |||
962 | continue; | |||
963 | } | |||
964 | ||||
965 | // If this is a named positional argument, just remember that it is the | |||
966 | // active one... | |||
967 | if (Handler->getFormattingFlag() == cl::Positional) | |||
968 | ActivePositionalArg = Handler; | |||
969 | else | |||
970 | ErrorParsing |= ProvideOption(Handler, ArgName, Value, argc, argv, i); | |||
971 | } | |||
972 | ||||
973 | // Check and handle positional arguments now... | |||
974 | if (NumPositionalRequired > PositionalVals.size()) { | |||
975 | errs() << ProgramName | |||
976 | << ": Not enough positional command line arguments specified!\n" | |||
977 | << "Must specify at least " << NumPositionalRequired | |||
978 | << " positional arguments: See: " << argv[0] << " -help\n"; | |||
979 | ||||
980 | ErrorParsing = true; | |||
981 | } else if (!HasUnlimitedPositionals && | |||
982 | PositionalVals.size() > PositionalOpts.size()) { | |||
983 | errs() << ProgramName | |||
984 | << ": Too many positional arguments specified!\n" | |||
985 | << "Can specify at most " << PositionalOpts.size() | |||
986 | << " positional arguments: See: " << argv[0] << " -help\n"; | |||
987 | ErrorParsing = true; | |||
988 | ||||
989 | } else if (!ConsumeAfterOpt) { | |||
990 | // Positional args have already been handled if ConsumeAfter is specified. | |||
991 | unsigned ValNo = 0, NumVals = static_cast<unsigned>(PositionalVals.size()); | |||
992 | for (size_t i = 0, e = PositionalOpts.size(); i != e; ++i) { | |||
993 | if (RequiresValue(PositionalOpts[i])) { | |||
994 | ProvidePositionalOption(PositionalOpts[i], PositionalVals[ValNo].first, | |||
995 | PositionalVals[ValNo].second); | |||
996 | ValNo++; | |||
997 | --NumPositionalRequired; // We fulfilled our duty... | |||
998 | } | |||
999 | ||||
1000 | // If we _can_ give this option more arguments, do so now, as long as we | |||
1001 | // do not give it values that others need. 'Done' controls whether the | |||
1002 | // option even _WANTS_ any more. | |||
1003 | // | |||
1004 | bool Done = PositionalOpts[i]->getNumOccurrencesFlag() == cl::Required; | |||
1005 | while (NumVals-ValNo > NumPositionalRequired && !Done) { | |||
1006 | switch (PositionalOpts[i]->getNumOccurrencesFlag()) { | |||
1007 | case cl::Optional: | |||
1008 | Done = true; // Optional arguments want _at most_ one value | |||
1009 | // FALL THROUGH | |||
1010 | case cl::ZeroOrMore: // Zero or more will take all they can get... | |||
1011 | case cl::OneOrMore: // One or more will take all they can get... | |||
1012 | ProvidePositionalOption(PositionalOpts[i], | |||
1013 | PositionalVals[ValNo].first, | |||
1014 | PositionalVals[ValNo].second); | |||
1015 | ValNo++; | |||
1016 | break; | |||
1017 | default: | |||
1018 | llvm_unreachable("Internal error, unexpected NumOccurrences flag in "::llvm::llvm_unreachable_internal("Internal error, unexpected NumOccurrences flag in " "positional argument processing!", "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224007/lib/Support/CommandLine.cpp" , 1019) | |||
1019 | "positional argument processing!")::llvm::llvm_unreachable_internal("Internal error, unexpected NumOccurrences flag in " "positional argument processing!", "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224007/lib/Support/CommandLine.cpp" , 1019); | |||
1020 | } | |||
1021 | } | |||
1022 | } | |||
1023 | } else { | |||
1024 | assert(ConsumeAfterOpt && NumPositionalRequired <= PositionalVals.size())((ConsumeAfterOpt && NumPositionalRequired <= PositionalVals .size()) ? static_cast<void> (0) : __assert_fail ("ConsumeAfterOpt && NumPositionalRequired <= PositionalVals.size()" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224007/lib/Support/CommandLine.cpp" , 1024, __PRETTY_FUNCTION__)); | |||
1025 | unsigned ValNo = 0; | |||
1026 | for (size_t j = 1, e = PositionalOpts.size(); j != e; ++j) | |||
1027 | if (RequiresValue(PositionalOpts[j])) { | |||
1028 | ErrorParsing |= ProvidePositionalOption(PositionalOpts[j], | |||
1029 | PositionalVals[ValNo].first, | |||
1030 | PositionalVals[ValNo].second); | |||
1031 | ValNo++; | |||
1032 | } | |||
1033 | ||||
1034 | // Handle the case where there is just one positional option, and it's | |||
1035 | // optional. In this case, we want to give JUST THE FIRST option to the | |||
1036 | // positional option and keep the rest for the consume after. The above | |||
1037 | // loop would have assigned no values to positional options in this case. | |||
1038 | // | |||
1039 | if (PositionalOpts.size() == 2 && ValNo == 0 && !PositionalVals.empty()) { | |||
1040 | ErrorParsing |= ProvidePositionalOption(PositionalOpts[1], | |||
1041 | PositionalVals[ValNo].first, | |||
1042 | PositionalVals[ValNo].second); | |||
1043 | ValNo++; | |||
1044 | } | |||
1045 | ||||
1046 | // Handle over all of the rest of the arguments to the | |||
1047 | // cl::ConsumeAfter command line option... | |||
1048 | for (; ValNo != PositionalVals.size(); ++ValNo) | |||
1049 | ErrorParsing |= ProvidePositionalOption(ConsumeAfterOpt, | |||
1050 | PositionalVals[ValNo].first, | |||
1051 | PositionalVals[ValNo].second); | |||
1052 | } | |||
1053 | ||||
1054 | // Loop over args and make sure all required args are specified! | |||
1055 | for (const auto &Opt : Opts) { | |||
1056 | switch (Opt.second->getNumOccurrencesFlag()) { | |||
1057 | case Required: | |||
1058 | case OneOrMore: | |||
1059 | if (Opt.second->getNumOccurrences() == 0) { | |||
1060 | Opt.second->error("must be specified at least once!"); | |||
1061 | ErrorParsing = true; | |||
1062 | } | |||
1063 | // Fall through | |||
1064 | default: | |||
1065 | break; | |||
1066 | } | |||
1067 | } | |||
1068 | ||||
1069 | // Now that we know if -debug is specified, we can use it. | |||
1070 | // Note that if ReadResponseFiles == true, this must be done before the | |||
1071 | // memory allocated for the expanded command line is free()d below. | |||
1072 | DEBUG(dbgs() << "Args: ";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("commandline")) { dbgs() << "Args: "; for (int i = 0; i < argc; ++i) dbgs() << argv[i] << ' '; dbgs() << '\n';; } } while (0) | |||
1073 | for (int i = 0; i < argc; ++i)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("commandline")) { dbgs() << "Args: "; for (int i = 0; i < argc; ++i) dbgs() << argv[i] << ' '; dbgs() << '\n';; } } while (0) | |||
1074 | dbgs() << argv[i] << ' ';do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("commandline")) { dbgs() << "Args: "; for (int i = 0; i < argc; ++i) dbgs() << argv[i] << ' '; dbgs() << '\n';; } } while (0) | |||
1075 | dbgs() << '\n';do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("commandline")) { dbgs() << "Args: "; for (int i = 0; i < argc; ++i) dbgs() << argv[i] << ' '; dbgs() << '\n';; } } while (0) | |||
1076 | )do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("commandline")) { dbgs() << "Args: "; for (int i = 0; i < argc; ++i) dbgs() << argv[i] << ' '; dbgs() << '\n';; } } while (0); | |||
1077 | ||||
1078 | // Free all of the memory allocated to the map. Command line options may only | |||
1079 | // be processed once! | |||
1080 | Opts.clear(); | |||
1081 | PositionalOpts.clear(); | |||
1082 | MoreHelp->clear(); | |||
1083 | ||||
1084 | // If we had an error processing our arguments, don't let the program execute | |||
1085 | if (ErrorParsing) exit(1); | |||
1086 | } | |||
1087 | ||||
1088 | //===----------------------------------------------------------------------===// | |||
1089 | // Option Base class implementation | |||
1090 | // | |||
1091 | ||||
1092 | bool Option::error(const Twine &Message, StringRef ArgName) { | |||
1093 | if (!ArgName.data()) ArgName = ArgStr; | |||
1094 | if (ArgName.empty()) | |||
1095 | errs() << HelpStr; // Be nice for positional arguments | |||
1096 | else | |||
1097 | errs() << ProgramName << ": for the -" << ArgName; | |||
1098 | ||||
1099 | errs() << " option: " << Message << "\n"; | |||
1100 | return true; | |||
1101 | } | |||
1102 | ||||
1103 | bool Option::addOccurrence(unsigned pos, StringRef ArgName, | |||
1104 | StringRef Value, bool MultiArg) { | |||
1105 | if (!MultiArg) | |||
1106 | NumOccurrences++; // Increment the number of times we have been seen | |||
1107 | ||||
1108 | switch (getNumOccurrencesFlag()) { | |||
1109 | case Optional: | |||
1110 | if (NumOccurrences > 1) | |||
1111 | return error("may only occur zero or one times!", ArgName); | |||
1112 | break; | |||
1113 | case Required: | |||
1114 | if (NumOccurrences > 1) | |||
1115 | return error("must occur exactly one time!", ArgName); | |||
1116 | // Fall through | |||
1117 | case OneOrMore: | |||
1118 | case ZeroOrMore: | |||
1119 | case ConsumeAfter: break; | |||
1120 | } | |||
1121 | ||||
1122 | return handleOccurrence(pos, ArgName, Value); | |||
1123 | } | |||
1124 | ||||
1125 | ||||
1126 | // getValueStr - Get the value description string, using "DefaultMsg" if nothing | |||
1127 | // has been specified yet. | |||
1128 | // | |||
1129 | static const char *getValueStr(const Option &O, const char *DefaultMsg) { | |||
1130 | if (O.ValueStr[0] == 0) return DefaultMsg; | |||
1131 | return O.ValueStr; | |||
1132 | } | |||
1133 | ||||
1134 | //===----------------------------------------------------------------------===// | |||
1135 | // cl::alias class implementation | |||
1136 | // | |||
1137 | ||||
1138 | // Return the width of the option tag for printing... | |||
1139 | size_t alias::getOptionWidth() const { | |||
1140 | return std::strlen(ArgStr)+6; | |||
1141 | } | |||
1142 | ||||
1143 | static void printHelpStr(StringRef HelpStr, size_t Indent, | |||
1144 | size_t FirstLineIndentedBy) { | |||
1145 | std::pair<StringRef, StringRef> Split = HelpStr.split('\n'); | |||
1146 | outs().indent(Indent - FirstLineIndentedBy) << " - " << Split.first << "\n"; | |||
1147 | while (!Split.second.empty()) { | |||
1148 | Split = Split.second.split('\n'); | |||
1149 | outs().indent(Indent) << Split.first << "\n"; | |||
1150 | } | |||
1151 | } | |||
1152 | ||||
1153 | // Print out the option for the alias. | |||
1154 | void alias::printOptionInfo(size_t GlobalWidth) const { | |||
1155 | outs() << " -" << ArgStr; | |||
1156 | printHelpStr(HelpStr, GlobalWidth, std::strlen(ArgStr) + 6); | |||
1157 | } | |||
1158 | ||||
1159 | //===----------------------------------------------------------------------===// | |||
1160 | // Parser Implementation code... | |||
1161 | // | |||
1162 | ||||
1163 | // basic_parser implementation | |||
1164 | // | |||
1165 | ||||
1166 | // Return the width of the option tag for printing... | |||
1167 | size_t basic_parser_impl::getOptionWidth(const Option &O) const { | |||
1168 | size_t Len = std::strlen(O.ArgStr); | |||
1169 | if (const char *ValName = getValueName()) | |||
1170 | Len += std::strlen(getValueStr(O, ValName))+3; | |||
1171 | ||||
1172 | return Len + 6; | |||
1173 | } | |||
1174 | ||||
1175 | // printOptionInfo - Print out information about this option. The | |||
1176 | // to-be-maintained width is specified. | |||
1177 | // | |||
1178 | void basic_parser_impl::printOptionInfo(const Option &O, | |||
1179 | size_t GlobalWidth) const { | |||
1180 | outs() << " -" << O.ArgStr; | |||
1181 | ||||
1182 | if (const char *ValName = getValueName()) | |||
1183 | outs() << "=<" << getValueStr(O, ValName) << '>'; | |||
1184 | ||||
1185 | printHelpStr(O.HelpStr, GlobalWidth, getOptionWidth(O)); | |||
1186 | } | |||
1187 | ||||
1188 | void basic_parser_impl::printOptionName(const Option &O, | |||
1189 | size_t GlobalWidth) const { | |||
1190 | outs() << " -" << O.ArgStr; | |||
1191 | outs().indent(GlobalWidth-std::strlen(O.ArgStr)); | |||
1192 | } | |||
1193 | ||||
1194 | ||||
1195 | // parser<bool> implementation | |||
1196 | // | |||
1197 | bool parser<bool>::parse(Option &O, StringRef ArgName, | |||
1198 | StringRef Arg, bool &Value) { | |||
1199 | if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" || | |||
1200 | Arg == "1") { | |||
1201 | Value = true; | |||
1202 | return false; | |||
1203 | } | |||
1204 | ||||
1205 | if (Arg == "false" || Arg == "FALSE" || Arg == "False" || Arg == "0") { | |||
1206 | Value = false; | |||
1207 | return false; | |||
1208 | } | |||
1209 | return O.error("'" + Arg + | |||
1210 | "' is invalid value for boolean argument! Try 0 or 1"); | |||
1211 | } | |||
1212 | ||||
1213 | // parser<boolOrDefault> implementation | |||
1214 | // | |||
1215 | bool parser<boolOrDefault>::parse(Option &O, StringRef ArgName, | |||
1216 | StringRef Arg, boolOrDefault &Value) { | |||
1217 | if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" || | |||
1218 | Arg == "1") { | |||
1219 | Value = BOU_TRUE; | |||
1220 | return false; | |||
1221 | } | |||
1222 | if (Arg == "false" || Arg == "FALSE" || Arg == "False" || Arg == "0") { | |||
1223 | Value = BOU_FALSE; | |||
1224 | return false; | |||
1225 | } | |||
1226 | ||||
1227 | return O.error("'" + Arg + | |||
1228 | "' is invalid value for boolean argument! Try 0 or 1"); | |||
1229 | } | |||
1230 | ||||
1231 | // parser<int> implementation | |||
1232 | // | |||
1233 | bool parser<int>::parse(Option &O, StringRef ArgName, | |||
1234 | StringRef Arg, int &Value) { | |||
1235 | if (Arg.getAsInteger(0, Value)) | |||
1236 | return O.error("'" + Arg + "' value invalid for integer argument!"); | |||
1237 | return false; | |||
1238 | } | |||
1239 | ||||
1240 | // parser<unsigned> implementation | |||
1241 | // | |||
1242 | bool parser<unsigned>::parse(Option &O, StringRef ArgName, | |||
1243 | StringRef Arg, unsigned &Value) { | |||
1244 | ||||
1245 | if (Arg.getAsInteger(0, Value)) | |||
1246 | return O.error("'" + Arg + "' value invalid for uint argument!"); | |||
1247 | return false; | |||
1248 | } | |||
1249 | ||||
1250 | // parser<unsigned long long> implementation | |||
1251 | // | |||
1252 | bool parser<unsigned long long>::parse(Option &O, StringRef ArgName, | |||
1253 | StringRef Arg, unsigned long long &Value){ | |||
1254 | ||||
1255 | if (Arg.getAsInteger(0, Value)) | |||
1256 | return O.error("'" + Arg + "' value invalid for uint argument!"); | |||
1257 | return false; | |||
1258 | } | |||
1259 | ||||
1260 | // parser<double>/parser<float> implementation | |||
1261 | // | |||
1262 | static bool parseDouble(Option &O, StringRef Arg, double &Value) { | |||
1263 | SmallString<32> TmpStr(Arg.begin(), Arg.end()); | |||
1264 | const char *ArgStart = TmpStr.c_str(); | |||
1265 | char *End; | |||
1266 | Value = strtod(ArgStart, &End); | |||
1267 | if (*End != 0) | |||
1268 | return O.error("'" + Arg + "' value invalid for floating point argument!"); | |||
1269 | return false; | |||
1270 | } | |||
1271 | ||||
1272 | bool parser<double>::parse(Option &O, StringRef ArgName, | |||
1273 | StringRef Arg, double &Val) { | |||
1274 | return parseDouble(O, Arg, Val); | |||
1275 | } | |||
1276 | ||||
1277 | bool parser<float>::parse(Option &O, StringRef ArgName, | |||
1278 | StringRef Arg, float &Val) { | |||
1279 | double dVal; | |||
1280 | if (parseDouble(O, Arg, dVal)) | |||
1281 | return true; | |||
1282 | Val = (float)dVal; | |||
1283 | return false; | |||
1284 | } | |||
1285 | ||||
1286 | ||||
1287 | ||||
1288 | // generic_parser_base implementation | |||
1289 | // | |||
1290 | ||||
1291 | // findOption - Return the option number corresponding to the specified | |||
1292 | // argument string. If the option is not found, getNumOptions() is returned. | |||
1293 | // | |||
1294 | unsigned generic_parser_base::findOption(const char *Name) { | |||
1295 | unsigned e = getNumOptions(); | |||
1296 | ||||
1297 | for (unsigned i = 0; i != e; ++i) { | |||
1298 | if (strcmp(getOption(i), Name) == 0) | |||
1299 | return i; | |||
1300 | } | |||
1301 | return e; | |||
1302 | } | |||
1303 | ||||
1304 | ||||
1305 | // Return the width of the option tag for printing... | |||
1306 | size_t generic_parser_base::getOptionWidth(const Option &O) const { | |||
1307 | if (O.hasArgStr()) { | |||
1308 | size_t Size = std::strlen(O.ArgStr)+6; | |||
1309 | for (unsigned i = 0, e = getNumOptions(); i != e; ++i) | |||
1310 | Size = std::max(Size, std::strlen(getOption(i))+8); | |||
1311 | return Size; | |||
1312 | } else { | |||
1313 | size_t BaseSize = 0; | |||
1314 | for (unsigned i = 0, e = getNumOptions(); i != e; ++i) | |||
1315 | BaseSize = std::max(BaseSize, std::strlen(getOption(i))+8); | |||
1316 | return BaseSize; | |||
1317 | } | |||
1318 | } | |||
1319 | ||||
1320 | // printOptionInfo - Print out information about this option. The | |||
1321 | // to-be-maintained width is specified. | |||
1322 | // | |||
1323 | void generic_parser_base::printOptionInfo(const Option &O, | |||
1324 | size_t GlobalWidth) const { | |||
1325 | if (O.hasArgStr()) { | |||
1326 | outs() << " -" << O.ArgStr; | |||
1327 | printHelpStr(O.HelpStr, GlobalWidth, std::strlen(O.ArgStr) + 6); | |||
1328 | ||||
1329 | for (unsigned i = 0, e = getNumOptions(); i != e; ++i) { | |||
1330 | size_t NumSpaces = GlobalWidth-strlen(getOption(i))-8; | |||
1331 | outs() << " =" << getOption(i); | |||
1332 | outs().indent(NumSpaces) << " - " << getDescription(i) << '\n'; | |||
1333 | } | |||
1334 | } else { | |||
1335 | if (O.HelpStr[0]) | |||
1336 | outs() << " " << O.HelpStr << '\n'; | |||
1337 | for (unsigned i = 0, e = getNumOptions(); i != e; ++i) { | |||
1338 | const char *Option = getOption(i); | |||
1339 | outs() << " -" << Option; | |||
1340 | printHelpStr(getDescription(i), GlobalWidth, std::strlen(Option) + 8); | |||
1341 | } | |||
1342 | } | |||
1343 | } | |||
1344 | ||||
1345 | static const size_t MaxOptWidth = 8; // arbitrary spacing for printOptionDiff | |||
1346 | ||||
1347 | // printGenericOptionDiff - Print the value of this option and it's default. | |||
1348 | // | |||
1349 | // "Generic" options have each value mapped to a name. | |||
1350 | void generic_parser_base:: | |||
1351 | printGenericOptionDiff(const Option &O, const GenericOptionValue &Value, | |||
1352 | const GenericOptionValue &Default, | |||
1353 | size_t GlobalWidth) const { | |||
1354 | outs() << " -" << O.ArgStr; | |||
1355 | outs().indent(GlobalWidth-std::strlen(O.ArgStr)); | |||
1356 | ||||
1357 | unsigned NumOpts = getNumOptions(); | |||
1358 | for (unsigned i = 0; i != NumOpts; ++i) { | |||
1359 | if (Value.compare(getOptionValue(i))) | |||
1360 | continue; | |||
1361 | ||||
1362 | outs() << "= " << getOption(i); | |||
1363 | size_t L = std::strlen(getOption(i)); | |||
1364 | size_t NumSpaces = MaxOptWidth > L ? MaxOptWidth - L : 0; | |||
1365 | outs().indent(NumSpaces) << " (default: "; | |||
1366 | for (unsigned j = 0; j != NumOpts; ++j) { | |||
1367 | if (Default.compare(getOptionValue(j))) | |||
1368 | continue; | |||
1369 | outs() << getOption(j); | |||
1370 | break; | |||
1371 | } | |||
1372 | outs() << ")\n"; | |||
1373 | return; | |||
1374 | } | |||
1375 | outs() << "= *unknown option value*\n"; | |||
1376 | } | |||
1377 | ||||
1378 | // printOptionDiff - Specializations for printing basic value types. | |||
1379 | // | |||
1380 | #define PRINT_OPT_DIFF(T)void parser<T>:: printOptionDiff(const Option &O, T V, OptionValue<T> D, size_t GlobalWidth) const { printOptionName (O, GlobalWidth); std::string Str; { raw_string_ostream SS(Str ); SS << V; } outs() << "= " << Str; size_t NumSpaces = MaxOptWidth > Str.size() ? MaxOptWidth - Str. size() : 0; outs().indent(NumSpaces) << " (default: "; if (D.hasValue()) outs() << D.getValue(); else outs() << "*no default*"; outs() << ")\n"; } \ | |||
1381 | void parser<T>:: \ | |||
1382 | printOptionDiff(const Option &O, T V, OptionValue<T> D, \ | |||
1383 | size_t GlobalWidth) const { \ | |||
1384 | printOptionName(O, GlobalWidth); \ | |||
1385 | std::string Str; \ | |||
1386 | { \ | |||
1387 | raw_string_ostream SS(Str); \ | |||
1388 | SS << V; \ | |||
1389 | } \ | |||
1390 | outs() << "= " << Str; \ | |||
1391 | size_t NumSpaces = MaxOptWidth > Str.size() ? MaxOptWidth - Str.size() : 0;\ | |||
1392 | outs().indent(NumSpaces) << " (default: "; \ | |||
1393 | if (D.hasValue()) \ | |||
1394 | outs() << D.getValue(); \ | |||
1395 | else \ | |||
1396 | outs() << "*no default*"; \ | |||
1397 | outs() << ")\n"; \ | |||
1398 | } \ | |||
1399 | ||||
1400 | PRINT_OPT_DIFF(bool)void parser<bool>:: printOptionDiff(const Option &O , bool V, OptionValue<bool> D, size_t GlobalWidth) const { printOptionName(O, GlobalWidth); std::string Str; { raw_string_ostream SS(Str); SS << V; } outs() << "= " << Str; size_t NumSpaces = MaxOptWidth > Str.size() ? MaxOptWidth - Str.size() : 0; outs().indent(NumSpaces) << " (default: " ; if (D.hasValue()) outs() << D.getValue(); else outs() << "*no default*"; outs() << ")\n"; } | |||
1401 | PRINT_OPT_DIFF(boolOrDefault)void parser<boolOrDefault>:: printOptionDiff(const Option &O, boolOrDefault V, OptionValue<boolOrDefault> D, size_t GlobalWidth) const { printOptionName(O, GlobalWidth); std::string Str; { raw_string_ostream SS(Str); SS << V ; } outs() << "= " << Str; size_t NumSpaces = MaxOptWidth > Str.size() ? MaxOptWidth - Str.size() : 0; outs().indent (NumSpaces) << " (default: "; if (D.hasValue()) outs() << D.getValue(); else outs() << "*no default*"; outs() << ")\n"; } | |||
1402 | PRINT_OPT_DIFF(int)void parser<int>:: printOptionDiff(const Option &O, int V, OptionValue<int> D, size_t GlobalWidth) const { printOptionName(O, GlobalWidth); std::string Str; { raw_string_ostream SS(Str); SS << V; } outs() << "= " << Str; size_t NumSpaces = MaxOptWidth > Str.size() ? MaxOptWidth - Str.size() : 0; outs().indent(NumSpaces) << " (default: " ; if (D.hasValue()) outs() << D.getValue(); else outs() << "*no default*"; outs() << ")\n"; } | |||
1403 | PRINT_OPT_DIFF(unsigned)void parser<unsigned>:: printOptionDiff(const Option & O, unsigned V, OptionValue<unsigned> D, size_t GlobalWidth ) const { printOptionName(O, GlobalWidth); std::string Str; { raw_string_ostream SS(Str); SS << V; } outs() << "= " << Str; size_t NumSpaces = MaxOptWidth > Str.size () ? MaxOptWidth - Str.size() : 0; outs().indent(NumSpaces) << " (default: "; if (D.hasValue()) outs() << D.getValue( ); else outs() << "*no default*"; outs() << ")\n" ; } | |||
1404 | PRINT_OPT_DIFF(unsigned long long)void parser<unsigned long long>:: printOptionDiff(const Option &O, unsigned long long V, OptionValue<unsigned long long> D, size_t GlobalWidth) const { printOptionName (O, GlobalWidth); std::string Str; { raw_string_ostream SS(Str ); SS << V; } outs() << "= " << Str; size_t NumSpaces = MaxOptWidth > Str.size() ? MaxOptWidth - Str. size() : 0; outs().indent(NumSpaces) << " (default: "; if (D.hasValue()) outs() << D.getValue(); else outs() << "*no default*"; outs() << ")\n"; } | |||
1405 | PRINT_OPT_DIFF(double)void parser<double>:: printOptionDiff(const Option & O, double V, OptionValue<double> D, size_t GlobalWidth) const { printOptionName(O, GlobalWidth); std::string Str; { raw_string_ostream SS(Str); SS << V; } outs() << "= " << Str; size_t NumSpaces = MaxOptWidth > Str.size() ? MaxOptWidth - Str.size() : 0; outs().indent(NumSpaces) << " (default: " ; if (D.hasValue()) outs() << D.getValue(); else outs() << "*no default*"; outs() << ")\n"; } | |||
1406 | PRINT_OPT_DIFF(float)void parser<float>:: printOptionDiff(const Option & O, float V, OptionValue<float> D, size_t GlobalWidth) const { printOptionName(O, GlobalWidth); std::string Str; { raw_string_ostream SS(Str); SS << V; } outs() << "= " << Str; size_t NumSpaces = MaxOptWidth > Str.size() ? MaxOptWidth - Str.size() : 0; outs().indent(NumSpaces) << " (default: " ; if (D.hasValue()) outs() << D.getValue(); else outs() << "*no default*"; outs() << ")\n"; } | |||
1407 | PRINT_OPT_DIFF(char)void parser<char>:: printOptionDiff(const Option &O , char V, OptionValue<char> D, size_t GlobalWidth) const { printOptionName(O, GlobalWidth); std::string Str; { raw_string_ostream SS(Str); SS << V; } outs() << "= " << Str; size_t NumSpaces = MaxOptWidth > Str.size() ? MaxOptWidth - Str.size() : 0; outs().indent(NumSpaces) << " (default: " ; if (D.hasValue()) outs() << D.getValue(); else outs() << "*no default*"; outs() << ")\n"; } | |||
1408 | ||||
1409 | void parser<std::string>:: | |||
1410 | printOptionDiff(const Option &O, StringRef V, OptionValue<std::string> D, | |||
1411 | size_t GlobalWidth) const { | |||
1412 | printOptionName(O, GlobalWidth); | |||
1413 | outs() << "= " << V; | |||
1414 | size_t NumSpaces = MaxOptWidth > V.size() ? MaxOptWidth - V.size() : 0; | |||
1415 | outs().indent(NumSpaces) << " (default: "; | |||
1416 | if (D.hasValue()) | |||
1417 | outs() << D.getValue(); | |||
1418 | else | |||
1419 | outs() << "*no default*"; | |||
1420 | outs() << ")\n"; | |||
1421 | } | |||
1422 | ||||
1423 | // Print a placeholder for options that don't yet support printOptionDiff(). | |||
1424 | void basic_parser_impl:: | |||
1425 | printOptionNoValue(const Option &O, size_t GlobalWidth) const { | |||
1426 | printOptionName(O, GlobalWidth); | |||
1427 | outs() << "= *cannot print option value*\n"; | |||
1428 | } | |||
1429 | ||||
1430 | //===----------------------------------------------------------------------===// | |||
1431 | // -help and -help-hidden option implementation | |||
1432 | // | |||
1433 | ||||
1434 | static int OptNameCompare(const void *LHS, const void *RHS) { | |||
1435 | typedef std::pair<const char *, Option*> pair_ty; | |||
1436 | ||||
1437 | return strcmp(((const pair_ty*)LHS)->first, ((const pair_ty*)RHS)->first); | |||
1438 | } | |||
1439 | ||||
1440 | // Copy Options into a vector so we can sort them as we like. | |||
1441 | static void | |||
1442 | sortOpts(StringMap<Option*> &OptMap, | |||
1443 | SmallVectorImpl< std::pair<const char *, Option*> > &Opts, | |||
1444 | bool ShowHidden) { | |||
1445 | SmallPtrSet<Option*, 128> OptionSet; // Duplicate option detection. | |||
1446 | ||||
1447 | for (StringMap<Option*>::iterator I = OptMap.begin(), E = OptMap.end(); | |||
1448 | I != E; ++I) { | |||
1449 | // Ignore really-hidden options. | |||
1450 | if (I->second->getOptionHiddenFlag() == ReallyHidden) | |||
1451 | continue; | |||
1452 | ||||
1453 | // Unless showhidden is set, ignore hidden flags. | |||
1454 | if (I->second->getOptionHiddenFlag() == Hidden && !ShowHidden) | |||
1455 | continue; | |||
1456 | ||||
1457 | // If we've already seen this option, don't add it to the list again. | |||
1458 | if (!OptionSet.insert(I->second).second) | |||
1459 | continue; | |||
1460 | ||||
1461 | Opts.push_back(std::pair<const char *, Option*>(I->getKey().data(), | |||
1462 | I->second)); | |||
1463 | } | |||
1464 | ||||
1465 | // Sort the options list alphabetically. | |||
1466 | qsort(Opts.data(), Opts.size(), sizeof(Opts[0]), OptNameCompare); | |||
1467 | } | |||
1468 | ||||
1469 | namespace { | |||
1470 | ||||
1471 | class HelpPrinter { | |||
1472 | protected: | |||
1473 | const bool ShowHidden; | |||
1474 | typedef SmallVector<std::pair<const char *, Option*>,128> StrOptionPairVector; | |||
1475 | // Print the options. Opts is assumed to be alphabetically sorted. | |||
1476 | virtual void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) { | |||
1477 | for (size_t i = 0, e = Opts.size(); i != e; ++i) | |||
1478 | Opts[i].second->printOptionInfo(MaxArgLen); | |||
1479 | } | |||
1480 | ||||
1481 | public: | |||
1482 | explicit HelpPrinter(bool showHidden) : ShowHidden(showHidden) {} | |||
1483 | virtual ~HelpPrinter() {} | |||
1484 | ||||
1485 | // Invoke the printer. | |||
1486 | void operator=(bool Value) { | |||
1487 | if (Value == false) return; | |||
1488 | ||||
1489 | // Get all the options. | |||
1490 | SmallVector<Option*, 4> PositionalOpts; | |||
1491 | SmallVector<Option*, 4> SinkOpts; | |||
1492 | StringMap<Option*> OptMap; | |||
1493 | GetOptionInfo(PositionalOpts, SinkOpts, OptMap); | |||
1494 | ||||
1495 | StrOptionPairVector Opts; | |||
1496 | sortOpts(OptMap, Opts, ShowHidden); | |||
1497 | ||||
1498 | if (ProgramOverview) | |||
1499 | outs() << "OVERVIEW: " << ProgramOverview << "\n"; | |||
1500 | ||||
1501 | outs() << "USAGE: " << ProgramName << " [options]"; | |||
1502 | ||||
1503 | // Print out the positional options. | |||
1504 | Option *CAOpt = nullptr; // The cl::ConsumeAfter option, if it exists... | |||
1505 | if (!PositionalOpts.empty() && | |||
1506 | PositionalOpts[0]->getNumOccurrencesFlag() == ConsumeAfter) | |||
1507 | CAOpt = PositionalOpts[0]; | |||
1508 | ||||
1509 | for (size_t i = CAOpt != nullptr, e = PositionalOpts.size(); i != e; ++i) { | |||
1510 | if (PositionalOpts[i]->ArgStr[0]) | |||
1511 | outs() << " --" << PositionalOpts[i]->ArgStr; | |||
1512 | outs() << " " << PositionalOpts[i]->HelpStr; | |||
1513 | } | |||
1514 | ||||
1515 | // Print the consume after option info if it exists... | |||
1516 | if (CAOpt) outs() << " " << CAOpt->HelpStr; | |||
1517 | ||||
1518 | outs() << "\n\n"; | |||
1519 | ||||
1520 | // Compute the maximum argument length... | |||
1521 | size_t MaxArgLen = 0; | |||
1522 | for (size_t i = 0, e = Opts.size(); i != e; ++i) | |||
1523 | MaxArgLen = std::max(MaxArgLen, Opts[i].second->getOptionWidth()); | |||
1524 | ||||
1525 | outs() << "OPTIONS:\n"; | |||
1526 | printOptions(Opts, MaxArgLen); | |||
1527 | ||||
1528 | // Print any extra help the user has declared. | |||
1529 | for (std::vector<const char *>::iterator I = MoreHelp->begin(), | |||
1530 | E = MoreHelp->end(); | |||
1531 | I != E; ++I) | |||
1532 | outs() << *I; | |||
1533 | MoreHelp->clear(); | |||
1534 | ||||
1535 | // Halt the program since help information was printed | |||
1536 | exit(0); | |||
1537 | } | |||
1538 | }; | |||
1539 | ||||
1540 | class CategorizedHelpPrinter : public HelpPrinter { | |||
1541 | public: | |||
1542 | explicit CategorizedHelpPrinter(bool showHidden) : HelpPrinter(showHidden) {} | |||
1543 | ||||
1544 | // Helper function for printOptions(). | |||
1545 | // It shall return true if A's name should be lexographically | |||
1546 | // ordered before B's name. It returns false otherwise. | |||
1547 | static bool OptionCategoryCompare(OptionCategory *A, OptionCategory *B) { | |||
1548 | return strcmp(A->getName(), B->getName()) < 0; | |||
1549 | } | |||
1550 | ||||
1551 | // Make sure we inherit our base class's operator=() | |||
1552 | using HelpPrinter::operator= ; | |||
1553 | ||||
1554 | protected: | |||
1555 | void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) override { | |||
1556 | std::vector<OptionCategory *> SortedCategories; | |||
1557 | std::map<OptionCategory *, std::vector<Option *> > CategorizedOptions; | |||
1558 | ||||
1559 | // Collect registered option categories into vector in preparation for | |||
1560 | // sorting. | |||
1561 | for (OptionCatSet::const_iterator I = RegisteredOptionCategories->begin(), | |||
1562 | E = RegisteredOptionCategories->end(); | |||
1563 | I != E; ++I) { | |||
1564 | SortedCategories.push_back(*I); | |||
1565 | } | |||
1566 | ||||
1567 | // Sort the different option categories alphabetically. | |||
1568 | assert(SortedCategories.size() > 0 && "No option categories registered!")((SortedCategories.size() > 0 && "No option categories registered!" ) ? static_cast<void> (0) : __assert_fail ("SortedCategories.size() > 0 && \"No option categories registered!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224007/lib/Support/CommandLine.cpp" , 1568, __PRETTY_FUNCTION__)); | |||
1569 | std::sort(SortedCategories.begin(), SortedCategories.end(), | |||
1570 | OptionCategoryCompare); | |||
1571 | ||||
1572 | // Create map to empty vectors. | |||
1573 | for (std::vector<OptionCategory *>::const_iterator | |||
1574 | I = SortedCategories.begin(), | |||
1575 | E = SortedCategories.end(); | |||
1576 | I != E; ++I) | |||
1577 | CategorizedOptions[*I] = std::vector<Option *>(); | |||
1578 | ||||
1579 | // Walk through pre-sorted options and assign into categories. | |||
1580 | // Because the options are already alphabetically sorted the | |||
1581 | // options within categories will also be alphabetically sorted. | |||
1582 | for (size_t I = 0, E = Opts.size(); I != E; ++I) { | |||
1583 | Option *Opt = Opts[I].second; | |||
1584 | assert(CategorizedOptions.count(Opt->Category) > 0 &&((CategorizedOptions.count(Opt->Category) > 0 && "Option has an unregistered category") ? static_cast<void > (0) : __assert_fail ("CategorizedOptions.count(Opt->Category) > 0 && \"Option has an unregistered category\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224007/lib/Support/CommandLine.cpp" , 1585, __PRETTY_FUNCTION__)) | |||
1585 | "Option has an unregistered category")((CategorizedOptions.count(Opt->Category) > 0 && "Option has an unregistered category") ? static_cast<void > (0) : __assert_fail ("CategorizedOptions.count(Opt->Category) > 0 && \"Option has an unregistered category\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224007/lib/Support/CommandLine.cpp" , 1585, __PRETTY_FUNCTION__)); | |||
1586 | CategorizedOptions[Opt->Category].push_back(Opt); | |||
1587 | } | |||
1588 | ||||
1589 | // Now do printing. | |||
1590 | for (std::vector<OptionCategory *>::const_iterator | |||
1591 | Category = SortedCategories.begin(), | |||
1592 | E = SortedCategories.end(); | |||
1593 | Category != E; ++Category) { | |||
1594 | // Hide empty categories for -help, but show for -help-hidden. | |||
1595 | bool IsEmptyCategory = CategorizedOptions[*Category].size() == 0; | |||
1596 | if (!ShowHidden && IsEmptyCategory) | |||
1597 | continue; | |||
1598 | ||||
1599 | // Print category information. | |||
1600 | outs() << "\n"; | |||
1601 | outs() << (*Category)->getName() << ":\n"; | |||
1602 | ||||
1603 | // Check if description is set. | |||
1604 | if ((*Category)->getDescription() != nullptr) | |||
1605 | outs() << (*Category)->getDescription() << "\n\n"; | |||
1606 | else | |||
1607 | outs() << "\n"; | |||
1608 | ||||
1609 | // When using -help-hidden explicitly state if the category has no | |||
1610 | // options associated with it. | |||
1611 | if (IsEmptyCategory) { | |||
1612 | outs() << " This option category has no options.\n"; | |||
1613 | continue; | |||
1614 | } | |||
1615 | // Loop over the options in the category and print. | |||
1616 | for (std::vector<Option *>::const_iterator | |||
1617 | Opt = CategorizedOptions[*Category].begin(), | |||
1618 | E = CategorizedOptions[*Category].end(); | |||
1619 | Opt != E; ++Opt) | |||
1620 | (*Opt)->printOptionInfo(MaxArgLen); | |||
1621 | } | |||
1622 | } | |||
1623 | }; | |||
1624 | ||||
1625 | // This wraps the Uncategorizing and Categorizing printers and decides | |||
1626 | // at run time which should be invoked. | |||
1627 | class HelpPrinterWrapper { | |||
1628 | private: | |||
1629 | HelpPrinter &UncategorizedPrinter; | |||
1630 | CategorizedHelpPrinter &CategorizedPrinter; | |||
1631 | ||||
1632 | public: | |||
1633 | explicit HelpPrinterWrapper(HelpPrinter &UncategorizedPrinter, | |||
1634 | CategorizedHelpPrinter &CategorizedPrinter) : | |||
1635 | UncategorizedPrinter(UncategorizedPrinter), | |||
1636 | CategorizedPrinter(CategorizedPrinter) { } | |||
1637 | ||||
1638 | // Invoke the printer. | |||
1639 | void operator=(bool Value); | |||
1640 | }; | |||
1641 | ||||
1642 | } // End anonymous namespace | |||
1643 | ||||
1644 | // Declare the four HelpPrinter instances that are used to print out help, or | |||
1645 | // help-hidden as an uncategorized list or in categories. | |||
1646 | static HelpPrinter UncategorizedNormalPrinter(false); | |||
1647 | static HelpPrinter UncategorizedHiddenPrinter(true); | |||
1648 | static CategorizedHelpPrinter CategorizedNormalPrinter(false); | |||
1649 | static CategorizedHelpPrinter CategorizedHiddenPrinter(true); | |||
1650 | ||||
1651 | ||||
1652 | // Declare HelpPrinter wrappers that will decide whether or not to invoke | |||
1653 | // a categorizing help printer | |||
1654 | static HelpPrinterWrapper WrappedNormalPrinter(UncategorizedNormalPrinter, | |||
1655 | CategorizedNormalPrinter); | |||
1656 | static HelpPrinterWrapper WrappedHiddenPrinter(UncategorizedHiddenPrinter, | |||
1657 | CategorizedHiddenPrinter); | |||
1658 | ||||
1659 | // Define uncategorized help printers. | |||
1660 | // -help-list is hidden by default because if Option categories are being used | |||
1661 | // then -help behaves the same as -help-list. | |||
1662 | static cl::opt<HelpPrinter, true, parser<bool> > | |||
1663 | HLOp("help-list", | |||
1664 | cl::desc("Display list of available options (-help-list-hidden for more)"), | |||
1665 | cl::location(UncategorizedNormalPrinter), cl::Hidden, cl::ValueDisallowed); | |||
1666 | ||||
1667 | static cl::opt<HelpPrinter, true, parser<bool> > | |||
1668 | HLHOp("help-list-hidden", | |||
1669 | cl::desc("Display list of all available options"), | |||
1670 | cl::location(UncategorizedHiddenPrinter), cl::Hidden, cl::ValueDisallowed); | |||
1671 | ||||
1672 | // Define uncategorized/categorized help printers. These printers change their | |||
1673 | // behaviour at runtime depending on whether one or more Option categories have | |||
1674 | // been declared. | |||
1675 | static cl::opt<HelpPrinterWrapper, true, parser<bool> > | |||
1676 | HOp("help", cl::desc("Display available options (-help-hidden for more)"), | |||
1677 | cl::location(WrappedNormalPrinter), cl::ValueDisallowed); | |||
1678 | ||||
1679 | static cl::opt<HelpPrinterWrapper, true, parser<bool> > | |||
1680 | HHOp("help-hidden", cl::desc("Display all available options"), | |||
1681 | cl::location(WrappedHiddenPrinter), cl::Hidden, cl::ValueDisallowed); | |||
1682 | ||||
1683 | ||||
1684 | ||||
1685 | static cl::opt<bool> | |||
1686 | PrintOptions("print-options", | |||
1687 | cl::desc("Print non-default options after command line parsing"), | |||
1688 | cl::Hidden, cl::init(false)); | |||
1689 | ||||
1690 | static cl::opt<bool> | |||
1691 | PrintAllOptions("print-all-options", | |||
1692 | cl::desc("Print all option values after command line parsing"), | |||
1693 | cl::Hidden, cl::init(false)); | |||
1694 | ||||
1695 | void HelpPrinterWrapper::operator=(bool Value) { | |||
1696 | if (Value == false) | |||
1697 | return; | |||
1698 | ||||
1699 | // Decide which printer to invoke. If more than one option category is | |||
1700 | // registered then it is useful to show the categorized help instead of | |||
1701 | // uncategorized help. | |||
1702 | if (RegisteredOptionCategories->size() > 1) { | |||
1703 | // unhide -help-list option so user can have uncategorized output if they | |||
1704 | // want it. | |||
1705 | HLOp.setHiddenFlag(NotHidden); | |||
1706 | ||||
1707 | CategorizedPrinter = true; // Invoke categorized printer | |||
1708 | } | |||
1709 | else | |||
1710 | UncategorizedPrinter = true; // Invoke uncategorized printer | |||
1711 | } | |||
1712 | ||||
1713 | // Print the value of each option. | |||
1714 | void cl::PrintOptionValues() { | |||
1715 | if (!PrintOptions && !PrintAllOptions) return; | |||
1716 | ||||
1717 | // Get all the options. | |||
1718 | SmallVector<Option*, 4> PositionalOpts; | |||
1719 | SmallVector<Option*, 4> SinkOpts; | |||
1720 | StringMap<Option*> OptMap; | |||
1721 | GetOptionInfo(PositionalOpts, SinkOpts, OptMap); | |||
1722 | ||||
1723 | SmallVector<std::pair<const char *, Option*>, 128> Opts; | |||
1724 | sortOpts(OptMap, Opts, /*ShowHidden*/true); | |||
1725 | ||||
1726 | // Compute the maximum argument length... | |||
1727 | size_t MaxArgLen = 0; | |||
1728 | for (size_t i = 0, e = Opts.size(); i != e; ++i) | |||
1729 | MaxArgLen = std::max(MaxArgLen, Opts[i].second->getOptionWidth()); | |||
1730 | ||||
1731 | for (size_t i = 0, e = Opts.size(); i != e; ++i) | |||
1732 | Opts[i].second->printOptionValue(MaxArgLen, PrintAllOptions); | |||
1733 | } | |||
1734 | ||||
1735 | static void (*OverrideVersionPrinter)() = nullptr; | |||
1736 | ||||
1737 | static std::vector<void (*)()>* ExtraVersionPrinters = nullptr; | |||
1738 | ||||
1739 | namespace { | |||
1740 | class VersionPrinter { | |||
1741 | public: | |||
1742 | void print() { | |||
1743 | raw_ostream &OS = outs(); | |||
1744 | OS << "LLVM (http://llvm.org/):\n" | |||
1745 | << " " << PACKAGE_NAME"LLVM" << " version " << PACKAGE_VERSION"3.6.0"; | |||
1746 | #ifdef LLVM_VERSION_INFO | |||
1747 | OS << " " << LLVM_VERSION_INFO; | |||
1748 | #endif | |||
1749 | OS << "\n "; | |||
1750 | #ifdef LLVM_DEBIAN_INFO | |||
1751 | OS << LLVM_DEBIAN_INFO; | |||
1752 | #endif | |||
1753 | OS << "\n "; | |||
1754 | #ifndef __OPTIMIZE__1 | |||
1755 | OS << "DEBUG build"; | |||
1756 | #else | |||
1757 | OS << "Optimized build"; | |||
1758 | #endif | |||
1759 | #ifndef NDEBUG | |||
1760 | OS << " with assertions"; | |||
1761 | #endif | |||
1762 | std::string CPU = sys::getHostCPUName(); | |||
1763 | if (CPU == "generic") CPU = "(unknown)"; | |||
1764 | OS << ".\n" | |||
1765 | #if (ENABLE_TIMESTAMPS1 == 1) | |||
1766 | << " Built " << __DATE__"Dec 11 2014" << " (" << __TIME__"14:40:13" << ").\n" | |||
1767 | #endif | |||
1768 | << " Default target: " << sys::getDefaultTargetTriple() << '\n' | |||
1769 | << " Host CPU: " << CPU << '\n'; | |||
1770 | } | |||
1771 | void operator=(bool OptionWasSpecified) { | |||
1772 | if (!OptionWasSpecified) return; | |||
1773 | ||||
1774 | if (OverrideVersionPrinter != nullptr) { | |||
1775 | (*OverrideVersionPrinter)(); | |||
1776 | exit(0); | |||
1777 | } | |||
1778 | print(); | |||
1779 | ||||
1780 | // Iterate over any registered extra printers and call them to add further | |||
1781 | // information. | |||
1782 | if (ExtraVersionPrinters != nullptr) { | |||
1783 | outs() << '\n'; | |||
1784 | for (std::vector<void (*)()>::iterator I = ExtraVersionPrinters->begin(), | |||
1785 | E = ExtraVersionPrinters->end(); | |||
1786 | I != E; ++I) | |||
1787 | (*I)(); | |||
1788 | } | |||
1789 | ||||
1790 | exit(0); | |||
1791 | } | |||
1792 | }; | |||
1793 | } // End anonymous namespace | |||
1794 | ||||
1795 | ||||
1796 | // Define the --version option that prints out the LLVM version for the tool | |||
1797 | static VersionPrinter VersionPrinterInstance; | |||
1798 | ||||
1799 | static cl::opt<VersionPrinter, true, parser<bool> > | |||
1800 | VersOp("version", cl::desc("Display the version of this program"), | |||
1801 | cl::location(VersionPrinterInstance), cl::ValueDisallowed); | |||
1802 | ||||
1803 | // Utility function for printing the help message. | |||
1804 | void cl::PrintHelpMessage(bool Hidden, bool Categorized) { | |||
1805 | // This looks weird, but it actually prints the help message. The Printers are | |||
1806 | // types of HelpPrinter and the help gets printed when its operator= is | |||
1807 | // invoked. That's because the "normal" usages of the help printer is to be | |||
1808 | // assigned true/false depending on whether -help or -help-hidden was given or | |||
1809 | // not. Since we're circumventing that we have to make it look like -help or | |||
1810 | // -help-hidden were given, so we assign true. | |||
1811 | ||||
1812 | if (!Hidden && !Categorized) | |||
1813 | UncategorizedNormalPrinter = true; | |||
1814 | else if (!Hidden && Categorized) | |||
1815 | CategorizedNormalPrinter = true; | |||
1816 | else if (Hidden && !Categorized) | |||
1817 | UncategorizedHiddenPrinter = true; | |||
1818 | else | |||
1819 | CategorizedHiddenPrinter = true; | |||
1820 | } | |||
1821 | ||||
1822 | /// Utility function for printing version number. | |||
1823 | void cl::PrintVersionMessage() { | |||
1824 | VersionPrinterInstance.print(); | |||
1825 | } | |||
1826 | ||||
1827 | void cl::SetVersionPrinter(void (*func)()) { | |||
1828 | OverrideVersionPrinter = func; | |||
1829 | } | |||
1830 | ||||
1831 | void cl::AddExtraVersionPrinter(void (*func)()) { | |||
1832 | if (!ExtraVersionPrinters) | |||
1833 | ExtraVersionPrinters = new std::vector<void (*)()>; | |||
1834 | ||||
1835 | ExtraVersionPrinters->push_back(func); | |||
1836 | } | |||
1837 | ||||
1838 | void cl::getRegisteredOptions(StringMap<Option*> &Map) | |||
1839 | { | |||
1840 | // Get all the options. | |||
1841 | SmallVector<Option*, 4> PositionalOpts; //NOT USED | |||
1842 | SmallVector<Option*, 4> SinkOpts; //NOT USED | |||
1843 | assert(Map.size() == 0 && "StringMap must be empty")((Map.size() == 0 && "StringMap must be empty") ? static_cast <void> (0) : __assert_fail ("Map.size() == 0 && \"StringMap must be empty\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn224007/lib/Support/CommandLine.cpp" , 1843, __PRETTY_FUNCTION__)); | |||
1844 | GetOptionInfo(PositionalOpts, SinkOpts, Map); | |||
1845 | return; | |||
1846 | } | |||
1847 | ||||
1848 | void LLVMParseCommandLineOptions(int argc, const char *const *argv, | |||
1849 | const char *Overview) { | |||
1850 | llvm::cl::ParseCommandLineOptions(argc, argv, Overview); | |||
1851 | } |