CommandLine.cpp revision 218893
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/Support/Debug.h"
21#include "llvm/Support/ErrorHandling.h"
22#include "llvm/Support/MemoryBuffer.h"
23#include "llvm/Support/ManagedStatic.h"
24#include "llvm/Support/raw_ostream.h"
25#include "llvm/Support/system_error.h"
26#include "llvm/Target/TargetRegistry.h"
27#include "llvm/Support/Host.h"
28#include "llvm/Support/Path.h"
29#include "llvm/ADT/OwningPtr.h"
30#include "llvm/ADT/SmallPtrSet.h"
31#include "llvm/ADT/SmallString.h"
32#include "llvm/ADT/StringMap.h"
33#include "llvm/ADT/Twine.h"
34#include "llvm/Config/config.h"
35#include <cerrno>
36#include <cstdlib>
37using namespace llvm;
38using namespace cl;
39
40//===----------------------------------------------------------------------===//
41// Template instantiations and anchors.
42//
43namespace llvm { namespace cl {
44TEMPLATE_INSTANTIATION(class basic_parser<bool>);
45TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
46TEMPLATE_INSTANTIATION(class basic_parser<int>);
47TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
48TEMPLATE_INSTANTIATION(class basic_parser<double>);
49TEMPLATE_INSTANTIATION(class basic_parser<float>);
50TEMPLATE_INSTANTIATION(class basic_parser<std::string>);
51TEMPLATE_INSTANTIATION(class basic_parser<char>);
52
53TEMPLATE_INSTANTIATION(class opt<unsigned>);
54TEMPLATE_INSTANTIATION(class opt<int>);
55TEMPLATE_INSTANTIATION(class opt<std::string>);
56TEMPLATE_INSTANTIATION(class opt<char>);
57TEMPLATE_INSTANTIATION(class opt<bool>);
58} } // end namespace llvm::cl
59
60void Option::anchor() {}
61void basic_parser_impl::anchor() {}
62void parser<bool>::anchor() {}
63void parser<boolOrDefault>::anchor() {}
64void parser<int>::anchor() {}
65void parser<unsigned>::anchor() {}
66void parser<double>::anchor() {}
67void parser<float>::anchor() {}
68void parser<std::string>::anchor() {}
69void parser<char>::anchor() {}
70
71//===----------------------------------------------------------------------===//
72
73// Globals for name and overview of program.  Program name is not a string to
74// avoid static ctor/dtor issues.
75static char ProgramName[80] = "<premain>";
76static const char *ProgramOverview = 0;
77
78// This collects additional help to be printed.
79static ManagedStatic<std::vector<const char*> > MoreHelp;
80
81extrahelp::extrahelp(const char *Help)
82  : morehelp(Help) {
83  MoreHelp->push_back(Help);
84}
85
86static bool OptionListChanged = false;
87
88// MarkOptionsChanged - Internal helper function.
89void cl::MarkOptionsChanged() {
90  OptionListChanged = true;
91}
92
93/// RegisteredOptionList - This is the list of the command line options that
94/// have statically constructed themselves.
95static Option *RegisteredOptionList = 0;
96
97void Option::addArgument() {
98  assert(NextRegistered == 0 && "argument multiply registered!");
99
100  NextRegistered = RegisteredOptionList;
101  RegisteredOptionList = this;
102  MarkOptionsChanged();
103}
104
105
106//===----------------------------------------------------------------------===//
107// Basic, shared command line option processing machinery.
108//
109
110/// GetOptionInfo - Scan the list of registered options, turning them into data
111/// structures that are easier to handle.
112static void GetOptionInfo(SmallVectorImpl<Option*> &PositionalOpts,
113                          SmallVectorImpl<Option*> &SinkOpts,
114                          StringMap<Option*> &OptionsMap) {
115  SmallVector<const char*, 16> OptionNames;
116  Option *CAOpt = 0;  // The ConsumeAfter option if it exists.
117  for (Option *O = RegisteredOptionList; O; O = O->getNextRegisteredOption()) {
118    // If this option wants to handle multiple option names, get the full set.
119    // This handles enum options like "-O1 -O2" etc.
120    O->getExtraOptionNames(OptionNames);
121    if (O->ArgStr[0])
122      OptionNames.push_back(O->ArgStr);
123
124    // Handle named options.
125    for (size_t i = 0, e = OptionNames.size(); i != e; ++i) {
126      // Add argument to the argument map!
127      if (OptionsMap.GetOrCreateValue(OptionNames[i], O).second != O) {
128        errs() << ProgramName << ": CommandLine Error: Argument '"
129             << OptionNames[i] << "' defined more than once!\n";
130      }
131    }
132
133    OptionNames.clear();
134
135    // Remember information about positional options.
136    if (O->getFormattingFlag() == cl::Positional)
137      PositionalOpts.push_back(O);
138    else if (O->getMiscFlags() & cl::Sink) // Remember sink options
139      SinkOpts.push_back(O);
140    else if (O->getNumOccurrencesFlag() == cl::ConsumeAfter) {
141      if (CAOpt)
142        O->error("Cannot specify more than one option with cl::ConsumeAfter!");
143      CAOpt = O;
144    }
145  }
146
147  if (CAOpt)
148    PositionalOpts.push_back(CAOpt);
149
150  // Make sure that they are in order of registration not backwards.
151  std::reverse(PositionalOpts.begin(), PositionalOpts.end());
152}
153
154
155/// LookupOption - Lookup the option specified by the specified option on the
156/// command line.  If there is a value specified (after an equal sign) return
157/// that as well.  This assumes that leading dashes have already been stripped.
158static Option *LookupOption(StringRef &Arg, StringRef &Value,
159                            const StringMap<Option*> &OptionsMap) {
160  // Reject all dashes.
161  if (Arg.empty()) return 0;
162
163  size_t EqualPos = Arg.find('=');
164
165  // If we have an equals sign, remember the value.
166  if (EqualPos == StringRef::npos) {
167    // Look up the option.
168    StringMap<Option*>::const_iterator I = OptionsMap.find(Arg);
169    return I != OptionsMap.end() ? I->second : 0;
170  }
171
172  // If the argument before the = is a valid option name, we match.  If not,
173  // return Arg unmolested.
174  StringMap<Option*>::const_iterator I =
175    OptionsMap.find(Arg.substr(0, EqualPos));
176  if (I == OptionsMap.end()) return 0;
177
178  Value = Arg.substr(EqualPos+1);
179  Arg = Arg.substr(0, EqualPos);
180  return I->second;
181}
182
183/// LookupNearestOption - Lookup the closest match to the option specified by
184/// the specified option on the command line.  If there is a value specified
185/// (after an equal sign) return that as well.  This assumes that leading dashes
186/// have already been stripped.
187static Option *LookupNearestOption(StringRef Arg,
188                                   const StringMap<Option*> &OptionsMap,
189                                   const char *&NearestString) {
190  // Reject all dashes.
191  if (Arg.empty()) return 0;
192
193  // Split on any equal sign.
194  StringRef LHS = Arg.split('=').first;
195
196  // Find the closest match.
197  Option *Best = 0;
198  unsigned BestDistance = 0;
199  for (StringMap<Option*>::const_iterator it = OptionsMap.begin(),
200         ie = OptionsMap.end(); it != ie; ++it) {
201    Option *O = it->second;
202    SmallVector<const char*, 16> OptionNames;
203    O->getExtraOptionNames(OptionNames);
204    if (O->ArgStr[0])
205      OptionNames.push_back(O->ArgStr);
206
207    for (size_t i = 0, e = OptionNames.size(); i != e; ++i) {
208      StringRef Name = OptionNames[i];
209      unsigned Distance = StringRef(Name).edit_distance(
210        Arg, /*AllowReplacements=*/true, /*MaxEditDistance=*/BestDistance);
211      if (!Best || Distance < BestDistance) {
212        Best = O;
213        NearestString = OptionNames[i];
214        BestDistance = Distance;
215      }
216    }
217  }
218
219  return Best;
220}
221
222/// CommaSeparateAndAddOccurence - A wrapper around Handler->addOccurence() that
223/// does special handling of cl::CommaSeparated options.
224static bool CommaSeparateAndAddOccurence(Option *Handler, unsigned pos,
225                                         StringRef ArgName,
226                                         StringRef Value, bool MultiArg = false)
227{
228  // Check to see if this option accepts a comma separated list of values.  If
229  // it does, we have to split up the value into multiple values.
230  if (Handler->getMiscFlags() & CommaSeparated) {
231    StringRef Val(Value);
232    StringRef::size_type Pos = Val.find(',');
233
234    while (Pos != StringRef::npos) {
235      // Process the portion before the comma.
236      if (Handler->addOccurrence(pos, ArgName, Val.substr(0, Pos), MultiArg))
237        return true;
238      // Erase the portion before the comma, AND the comma.
239      Val = Val.substr(Pos+1);
240      Value.substr(Pos+1);  // Increment the original value pointer as well.
241      // Check for another comma.
242      Pos = Val.find(',');
243    }
244
245    Value = Val;
246  }
247
248  if (Handler->addOccurrence(pos, ArgName, Value, MultiArg))
249    return true;
250
251  return false;
252}
253
254/// ProvideOption - For Value, this differentiates between an empty value ("")
255/// and a null value (StringRef()).  The later is accepted for arguments that
256/// don't allow a value (-foo) the former is rejected (-foo=).
257static inline bool ProvideOption(Option *Handler, StringRef ArgName,
258                                 StringRef Value, int argc, char **argv,
259                                 int &i) {
260  // Is this a multi-argument option?
261  unsigned NumAdditionalVals = Handler->getNumAdditionalVals();
262
263  // Enforce value requirements
264  switch (Handler->getValueExpectedFlag()) {
265  case ValueRequired:
266    if (Value.data() == 0) {       // No value specified?
267      if (i+1 >= argc)
268        return Handler->error("requires a value!");
269      // Steal the next argument, like for '-o filename'
270      Value = argv[++i];
271    }
272    break;
273  case ValueDisallowed:
274    if (NumAdditionalVals > 0)
275      return Handler->error("multi-valued option specified"
276                            " with ValueDisallowed modifier!");
277
278    if (Value.data())
279      return Handler->error("does not allow a value! '" +
280                            Twine(Value) + "' specified.");
281    break;
282  case ValueOptional:
283    break;
284
285  default:
286    errs() << ProgramName
287         << ": Bad ValueMask flag! CommandLine usage error:"
288         << Handler->getValueExpectedFlag() << "\n";
289    llvm_unreachable(0);
290  }
291
292  // If this isn't a multi-arg option, just run the handler.
293  if (NumAdditionalVals == 0)
294    return CommaSeparateAndAddOccurence(Handler, i, ArgName, Value);
295
296  // If it is, run the handle several times.
297  bool MultiArg = false;
298
299  if (Value.data()) {
300    if (CommaSeparateAndAddOccurence(Handler, i, ArgName, Value, MultiArg))
301      return true;
302    --NumAdditionalVals;
303    MultiArg = true;
304  }
305
306  while (NumAdditionalVals > 0) {
307    if (i+1 >= argc)
308      return Handler->error("not enough values!");
309    Value = argv[++i];
310
311    if (CommaSeparateAndAddOccurence(Handler, i, ArgName, Value, MultiArg))
312      return true;
313    MultiArg = true;
314    --NumAdditionalVals;
315  }
316  return false;
317}
318
319static bool ProvidePositionalOption(Option *Handler, StringRef Arg, int i) {
320  int Dummy = i;
321  return ProvideOption(Handler, Handler->ArgStr, Arg, 0, 0, Dummy);
322}
323
324
325// Option predicates...
326static inline bool isGrouping(const Option *O) {
327  return O->getFormattingFlag() == cl::Grouping;
328}
329static inline bool isPrefixedOrGrouping(const Option *O) {
330  return isGrouping(O) || O->getFormattingFlag() == cl::Prefix;
331}
332
333// getOptionPred - Check to see if there are any options that satisfy the
334// specified predicate with names that are the prefixes in Name.  This is
335// checked by progressively stripping characters off of the name, checking to
336// see if there options that satisfy the predicate.  If we find one, return it,
337// otherwise return null.
338//
339static Option *getOptionPred(StringRef Name, size_t &Length,
340                             bool (*Pred)(const Option*),
341                             const StringMap<Option*> &OptionsMap) {
342
343  StringMap<Option*>::const_iterator OMI = OptionsMap.find(Name);
344
345  // Loop while we haven't found an option and Name still has at least two
346  // characters in it (so that the next iteration will not be the empty
347  // string.
348  while (OMI == OptionsMap.end() && Name.size() > 1) {
349    Name = Name.substr(0, Name.size()-1);   // Chop off the last character.
350    OMI = OptionsMap.find(Name);
351  }
352
353  if (OMI != OptionsMap.end() && Pred(OMI->second)) {
354    Length = Name.size();
355    return OMI->second;    // Found one!
356  }
357  return 0;                // No option found!
358}
359
360/// HandlePrefixedOrGroupedOption - The specified argument string (which started
361/// with at least one '-') does not fully match an available option.  Check to
362/// see if this is a prefix or grouped option.  If so, split arg into output an
363/// Arg/Value pair and return the Option to parse it with.
364static Option *HandlePrefixedOrGroupedOption(StringRef &Arg, StringRef &Value,
365                                             bool &ErrorParsing,
366                                         const StringMap<Option*> &OptionsMap) {
367  if (Arg.size() == 1) return 0;
368
369  // Do the lookup!
370  size_t Length = 0;
371  Option *PGOpt = getOptionPred(Arg, Length, isPrefixedOrGrouping, OptionsMap);
372  if (PGOpt == 0) return 0;
373
374  // If the option is a prefixed option, then the value is simply the
375  // rest of the name...  so fall through to later processing, by
376  // setting up the argument name flags and value fields.
377  if (PGOpt->getFormattingFlag() == cl::Prefix) {
378    Value = Arg.substr(Length);
379    Arg = Arg.substr(0, Length);
380    assert(OptionsMap.count(Arg) && OptionsMap.find(Arg)->second == PGOpt);
381    return PGOpt;
382  }
383
384  // This must be a grouped option... handle them now.  Grouping options can't
385  // have values.
386  assert(isGrouping(PGOpt) && "Broken getOptionPred!");
387
388  do {
389    // Move current arg name out of Arg into OneArgName.
390    StringRef OneArgName = Arg.substr(0, Length);
391    Arg = Arg.substr(Length);
392
393    // Because ValueRequired is an invalid flag for grouped arguments,
394    // we don't need to pass argc/argv in.
395    assert(PGOpt->getValueExpectedFlag() != cl::ValueRequired &&
396           "Option can not be cl::Grouping AND cl::ValueRequired!");
397    int Dummy = 0;
398    ErrorParsing |= ProvideOption(PGOpt, OneArgName,
399                                  StringRef(), 0, 0, Dummy);
400
401    // Get the next grouping option.
402    PGOpt = getOptionPred(Arg, Length, isGrouping, OptionsMap);
403  } while (PGOpt && Length != Arg.size());
404
405  // Return the last option with Arg cut down to just the last one.
406  return PGOpt;
407}
408
409
410
411static bool RequiresValue(const Option *O) {
412  return O->getNumOccurrencesFlag() == cl::Required ||
413         O->getNumOccurrencesFlag() == cl::OneOrMore;
414}
415
416static bool EatsUnboundedNumberOfValues(const Option *O) {
417  return O->getNumOccurrencesFlag() == cl::ZeroOrMore ||
418         O->getNumOccurrencesFlag() == cl::OneOrMore;
419}
420
421/// ParseCStringVector - Break INPUT up wherever one or more
422/// whitespace characters are found, and store the resulting tokens in
423/// OUTPUT. The tokens stored in OUTPUT are dynamically allocated
424/// using strdup(), so it is the caller's responsibility to free()
425/// them later.
426///
427static void ParseCStringVector(std::vector<char *> &OutputVector,
428                               const char *Input) {
429  // Characters which will be treated as token separators:
430  StringRef Delims = " \v\f\t\r\n";
431
432  StringRef WorkStr(Input);
433  while (!WorkStr.empty()) {
434    // If the first character is a delimiter, strip them off.
435    if (Delims.find(WorkStr[0]) != StringRef::npos) {
436      size_t Pos = WorkStr.find_first_not_of(Delims);
437      if (Pos == StringRef::npos) Pos = WorkStr.size();
438      WorkStr = WorkStr.substr(Pos);
439      continue;
440    }
441
442    // Find position of first delimiter.
443    size_t Pos = WorkStr.find_first_of(Delims);
444    if (Pos == StringRef::npos) Pos = WorkStr.size();
445
446    // Everything from 0 to Pos is the next word to copy.
447    char *NewStr = (char*)malloc(Pos+1);
448    memcpy(NewStr, WorkStr.data(), Pos);
449    NewStr[Pos] = 0;
450    OutputVector.push_back(NewStr);
451
452    WorkStr = WorkStr.substr(Pos);
453  }
454}
455
456/// ParseEnvironmentOptions - An alternative entry point to the
457/// CommandLine library, which allows you to read the program's name
458/// from the caller (as PROGNAME) and its command-line arguments from
459/// an environment variable (whose name is given in ENVVAR).
460///
461void cl::ParseEnvironmentOptions(const char *progName, const char *envVar,
462                                 const char *Overview, bool ReadResponseFiles) {
463  // Check args.
464  assert(progName && "Program name not specified");
465  assert(envVar && "Environment variable name missing");
466
467  // Get the environment variable they want us to parse options out of.
468  const char *envValue = getenv(envVar);
469  if (!envValue)
470    return;
471
472  // Get program's "name", which we wouldn't know without the caller
473  // telling us.
474  std::vector<char*> newArgv;
475  newArgv.push_back(strdup(progName));
476
477  // Parse the value of the environment variable into a "command line"
478  // and hand it off to ParseCommandLineOptions().
479  ParseCStringVector(newArgv, envValue);
480  int newArgc = static_cast<int>(newArgv.size());
481  ParseCommandLineOptions(newArgc, &newArgv[0], Overview, ReadResponseFiles);
482
483  // Free all the strdup()ed strings.
484  for (std::vector<char*>::iterator i = newArgv.begin(), e = newArgv.end();
485       i != e; ++i)
486    free(*i);
487}
488
489
490/// ExpandResponseFiles - Copy the contents of argv into newArgv,
491/// substituting the contents of the response files for the arguments
492/// of type @file.
493static void ExpandResponseFiles(unsigned argc, char** argv,
494                                std::vector<char*>& newArgv) {
495  for (unsigned i = 1; i != argc; ++i) {
496    char *arg = argv[i];
497
498    if (arg[0] == '@') {
499      sys::PathWithStatus respFile(++arg);
500
501      // Check that the response file is not empty (mmap'ing empty
502      // files can be problematic).
503      const sys::FileStatus *FileStat = respFile.getFileStatus();
504      if (FileStat && FileStat->getSize() != 0) {
505
506        // If we could open the file, parse its contents, otherwise
507        // pass the @file option verbatim.
508
509        // TODO: we should also support recursive loading of response files,
510        // since this is how gcc behaves. (From their man page: "The file may
511        // itself contain additional @file options; any such options will be
512        // processed recursively.")
513
514        // Mmap the response file into memory.
515        OwningPtr<MemoryBuffer> respFilePtr;
516        if (!MemoryBuffer::getFile(respFile.c_str(), respFilePtr)) {
517          ParseCStringVector(newArgv, respFilePtr->getBufferStart());
518          continue;
519        }
520      }
521    }
522    newArgv.push_back(strdup(arg));
523  }
524}
525
526void cl::ParseCommandLineOptions(int argc, char **argv,
527                                 const char *Overview, bool ReadResponseFiles) {
528  // Process all registered options.
529  SmallVector<Option*, 4> PositionalOpts;
530  SmallVector<Option*, 4> SinkOpts;
531  StringMap<Option*> Opts;
532  GetOptionInfo(PositionalOpts, SinkOpts, Opts);
533
534  assert((!Opts.empty() || !PositionalOpts.empty()) &&
535         "No options specified!");
536
537  // Expand response files.
538  std::vector<char*> newArgv;
539  if (ReadResponseFiles) {
540    newArgv.push_back(strdup(argv[0]));
541    ExpandResponseFiles(argc, argv, newArgv);
542    argv = &newArgv[0];
543    argc = static_cast<int>(newArgv.size());
544  }
545
546  // Copy the program name into ProgName, making sure not to overflow it.
547  std::string ProgName = sys::path::filename(argv[0]);
548  size_t Len = std::min(ProgName.size(), size_t(79));
549  memcpy(ProgramName, ProgName.data(), Len);
550  ProgramName[Len] = '\0';
551
552  ProgramOverview = Overview;
553  bool ErrorParsing = false;
554
555  // Check out the positional arguments to collect information about them.
556  unsigned NumPositionalRequired = 0;
557
558  // Determine whether or not there are an unlimited number of positionals
559  bool HasUnlimitedPositionals = false;
560
561  Option *ConsumeAfterOpt = 0;
562  if (!PositionalOpts.empty()) {
563    if (PositionalOpts[0]->getNumOccurrencesFlag() == cl::ConsumeAfter) {
564      assert(PositionalOpts.size() > 1 &&
565             "Cannot specify cl::ConsumeAfter without a positional argument!");
566      ConsumeAfterOpt = PositionalOpts[0];
567    }
568
569    // Calculate how many positional values are _required_.
570    bool UnboundedFound = false;
571    for (size_t i = ConsumeAfterOpt != 0, e = PositionalOpts.size();
572         i != e; ++i) {
573      Option *Opt = PositionalOpts[i];
574      if (RequiresValue(Opt))
575        ++NumPositionalRequired;
576      else if (ConsumeAfterOpt) {
577        // ConsumeAfter cannot be combined with "optional" positional options
578        // unless there is only one positional argument...
579        if (PositionalOpts.size() > 2)
580          ErrorParsing |=
581            Opt->error("error - this positional option will never be matched, "
582                       "because it does not Require a value, and a "
583                       "cl::ConsumeAfter option is active!");
584      } else if (UnboundedFound && !Opt->ArgStr[0]) {
585        // This option does not "require" a value...  Make sure this option is
586        // not specified after an option that eats all extra arguments, or this
587        // one will never get any!
588        //
589        ErrorParsing |= Opt->error("error - option can never match, because "
590                                   "another positional argument will match an "
591                                   "unbounded number of values, and this option"
592                                   " does not require a value!");
593      }
594      UnboundedFound |= EatsUnboundedNumberOfValues(Opt);
595    }
596    HasUnlimitedPositionals = UnboundedFound || ConsumeAfterOpt;
597  }
598
599  // PositionalVals - A vector of "positional" arguments we accumulate into
600  // the process at the end.
601  //
602  SmallVector<std::pair<StringRef,unsigned>, 4> PositionalVals;
603
604  // If the program has named positional arguments, and the name has been run
605  // across, keep track of which positional argument was named.  Otherwise put
606  // the positional args into the PositionalVals list...
607  Option *ActivePositionalArg = 0;
608
609  // Loop over all of the arguments... processing them.
610  bool DashDashFound = false;  // Have we read '--'?
611  for (int i = 1; i < argc; ++i) {
612    Option *Handler = 0;
613    Option *NearestHandler = 0;
614    const char *NearestHandlerString = 0;
615    StringRef Value;
616    StringRef ArgName = "";
617
618    // If the option list changed, this means that some command line
619    // option has just been registered or deregistered.  This can occur in
620    // response to things like -load, etc.  If this happens, rescan the options.
621    if (OptionListChanged) {
622      PositionalOpts.clear();
623      SinkOpts.clear();
624      Opts.clear();
625      GetOptionInfo(PositionalOpts, SinkOpts, Opts);
626      OptionListChanged = false;
627    }
628
629    // Check to see if this is a positional argument.  This argument is
630    // considered to be positional if it doesn't start with '-', if it is "-"
631    // itself, or if we have seen "--" already.
632    //
633    if (argv[i][0] != '-' || argv[i][1] == 0 || DashDashFound) {
634      // Positional argument!
635      if (ActivePositionalArg) {
636        ProvidePositionalOption(ActivePositionalArg, argv[i], i);
637        continue;  // We are done!
638      }
639
640      if (!PositionalOpts.empty()) {
641        PositionalVals.push_back(std::make_pair(argv[i],i));
642
643        // All of the positional arguments have been fulfulled, give the rest to
644        // the consume after option... if it's specified...
645        //
646        if (PositionalVals.size() >= NumPositionalRequired &&
647            ConsumeAfterOpt != 0) {
648          for (++i; i < argc; ++i)
649            PositionalVals.push_back(std::make_pair(argv[i],i));
650          break;   // Handle outside of the argument processing loop...
651        }
652
653        // Delay processing positional arguments until the end...
654        continue;
655      }
656    } else if (argv[i][0] == '-' && argv[i][1] == '-' && argv[i][2] == 0 &&
657               !DashDashFound) {
658      DashDashFound = true;  // This is the mythical "--"?
659      continue;              // Don't try to process it as an argument itself.
660    } else if (ActivePositionalArg &&
661               (ActivePositionalArg->getMiscFlags() & PositionalEatsArgs)) {
662      // If there is a positional argument eating options, check to see if this
663      // option is another positional argument.  If so, treat it as an argument,
664      // otherwise feed it to the eating positional.
665      ArgName = argv[i]+1;
666      // Eat leading dashes.
667      while (!ArgName.empty() && ArgName[0] == '-')
668        ArgName = ArgName.substr(1);
669
670      Handler = LookupOption(ArgName, Value, Opts);
671      if (!Handler || Handler->getFormattingFlag() != cl::Positional) {
672        ProvidePositionalOption(ActivePositionalArg, argv[i], i);
673        continue;  // We are done!
674      }
675
676    } else {     // We start with a '-', must be an argument.
677      ArgName = argv[i]+1;
678      // Eat leading dashes.
679      while (!ArgName.empty() && ArgName[0] == '-')
680        ArgName = ArgName.substr(1);
681
682      Handler = LookupOption(ArgName, Value, Opts);
683
684      // Check to see if this "option" is really a prefixed or grouped argument.
685      if (Handler == 0)
686        Handler = HandlePrefixedOrGroupedOption(ArgName, Value,
687                                                ErrorParsing, Opts);
688
689      // Otherwise, look for the closest available option to report to the user
690      // in the upcoming error.
691      if (Handler == 0 && SinkOpts.empty())
692        NearestHandler = LookupNearestOption(ArgName, Opts,
693                                             NearestHandlerString);
694    }
695
696    if (Handler == 0) {
697      if (SinkOpts.empty()) {
698        errs() << ProgramName << ": Unknown command line argument '"
699             << argv[i] << "'.  Try: '" << argv[0] << " -help'\n";
700
701        if (NearestHandler) {
702          // If we know a near match, report it as well.
703          errs() << ProgramName << ": Did you mean '-"
704                 << NearestHandlerString << "'?\n";
705        }
706
707        ErrorParsing = true;
708      } else {
709        for (SmallVectorImpl<Option*>::iterator I = SinkOpts.begin(),
710               E = SinkOpts.end(); I != E ; ++I)
711          (*I)->addOccurrence(i, "", argv[i]);
712      }
713      continue;
714    }
715
716    // If this is a named positional argument, just remember that it is the
717    // active one...
718    if (Handler->getFormattingFlag() == cl::Positional)
719      ActivePositionalArg = Handler;
720    else
721      ErrorParsing |= ProvideOption(Handler, ArgName, Value, argc, argv, i);
722  }
723
724  // Check and handle positional arguments now...
725  if (NumPositionalRequired > PositionalVals.size()) {
726    errs() << ProgramName
727         << ": Not enough positional command line arguments specified!\n"
728         << "Must specify at least " << NumPositionalRequired
729         << " positional arguments: See: " << argv[0] << " -help\n";
730
731    ErrorParsing = true;
732  } else if (!HasUnlimitedPositionals &&
733             PositionalVals.size() > PositionalOpts.size()) {
734    errs() << ProgramName
735         << ": Too many positional arguments specified!\n"
736         << "Can specify at most " << PositionalOpts.size()
737         << " positional arguments: See: " << argv[0] << " -help\n";
738    ErrorParsing = true;
739
740  } else if (ConsumeAfterOpt == 0) {
741    // Positional args have already been handled if ConsumeAfter is specified.
742    unsigned ValNo = 0, NumVals = static_cast<unsigned>(PositionalVals.size());
743    for (size_t i = 0, e = PositionalOpts.size(); i != e; ++i) {
744      if (RequiresValue(PositionalOpts[i])) {
745        ProvidePositionalOption(PositionalOpts[i], PositionalVals[ValNo].first,
746                                PositionalVals[ValNo].second);
747        ValNo++;
748        --NumPositionalRequired;  // We fulfilled our duty...
749      }
750
751      // If we _can_ give this option more arguments, do so now, as long as we
752      // do not give it values that others need.  'Done' controls whether the
753      // option even _WANTS_ any more.
754      //
755      bool Done = PositionalOpts[i]->getNumOccurrencesFlag() == cl::Required;
756      while (NumVals-ValNo > NumPositionalRequired && !Done) {
757        switch (PositionalOpts[i]->getNumOccurrencesFlag()) {
758        case cl::Optional:
759          Done = true;          // Optional arguments want _at most_ one value
760          // FALL THROUGH
761        case cl::ZeroOrMore:    // Zero or more will take all they can get...
762        case cl::OneOrMore:     // One or more will take all they can get...
763          ProvidePositionalOption(PositionalOpts[i],
764                                  PositionalVals[ValNo].first,
765                                  PositionalVals[ValNo].second);
766          ValNo++;
767          break;
768        default:
769          llvm_unreachable("Internal error, unexpected NumOccurrences flag in "
770                 "positional argument processing!");
771        }
772      }
773    }
774  } else {
775    assert(ConsumeAfterOpt && NumPositionalRequired <= PositionalVals.size());
776    unsigned ValNo = 0;
777    for (size_t j = 1, e = PositionalOpts.size(); j != e; ++j)
778      if (RequiresValue(PositionalOpts[j])) {
779        ErrorParsing |= ProvidePositionalOption(PositionalOpts[j],
780                                                PositionalVals[ValNo].first,
781                                                PositionalVals[ValNo].second);
782        ValNo++;
783      }
784
785    // Handle the case where there is just one positional option, and it's
786    // optional.  In this case, we want to give JUST THE FIRST option to the
787    // positional option and keep the rest for the consume after.  The above
788    // loop would have assigned no values to positional options in this case.
789    //
790    if (PositionalOpts.size() == 2 && ValNo == 0 && !PositionalVals.empty()) {
791      ErrorParsing |= ProvidePositionalOption(PositionalOpts[1],
792                                              PositionalVals[ValNo].first,
793                                              PositionalVals[ValNo].second);
794      ValNo++;
795    }
796
797    // Handle over all of the rest of the arguments to the
798    // cl::ConsumeAfter command line option...
799    for (; ValNo != PositionalVals.size(); ++ValNo)
800      ErrorParsing |= ProvidePositionalOption(ConsumeAfterOpt,
801                                              PositionalVals[ValNo].first,
802                                              PositionalVals[ValNo].second);
803  }
804
805  // Loop over args and make sure all required args are specified!
806  for (StringMap<Option*>::iterator I = Opts.begin(),
807         E = Opts.end(); I != E; ++I) {
808    switch (I->second->getNumOccurrencesFlag()) {
809    case Required:
810    case OneOrMore:
811      if (I->second->getNumOccurrences() == 0) {
812        I->second->error("must be specified at least once!");
813        ErrorParsing = true;
814      }
815      // Fall through
816    default:
817      break;
818    }
819  }
820
821  // Now that we know if -debug is specified, we can use it.
822  // Note that if ReadResponseFiles == true, this must be done before the
823  // memory allocated for the expanded command line is free()d below.
824  DEBUG(dbgs() << "Args: ";
825        for (int i = 0; i < argc; ++i)
826          dbgs() << argv[i] << ' ';
827        dbgs() << '\n';
828       );
829
830  // Free all of the memory allocated to the map.  Command line options may only
831  // be processed once!
832  Opts.clear();
833  PositionalOpts.clear();
834  MoreHelp->clear();
835
836  // Free the memory allocated by ExpandResponseFiles.
837  if (ReadResponseFiles) {
838    // Free all the strdup()ed strings.
839    for (std::vector<char*>::iterator i = newArgv.begin(), e = newArgv.end();
840         i != e; ++i)
841      free(*i);
842  }
843
844  // If we had an error processing our arguments, don't let the program execute
845  if (ErrorParsing) exit(1);
846}
847
848//===----------------------------------------------------------------------===//
849// Option Base class implementation
850//
851
852bool Option::error(const Twine &Message, StringRef ArgName) {
853  if (ArgName.data() == 0) ArgName = ArgStr;
854  if (ArgName.empty())
855    errs() << HelpStr;  // Be nice for positional arguments
856  else
857    errs() << ProgramName << ": for the -" << ArgName;
858
859  errs() << " option: " << Message << "\n";
860  return true;
861}
862
863bool Option::addOccurrence(unsigned pos, StringRef ArgName,
864                           StringRef Value, bool MultiArg) {
865  if (!MultiArg)
866    NumOccurrences++;   // Increment the number of times we have been seen
867
868  switch (getNumOccurrencesFlag()) {
869  case Optional:
870    if (NumOccurrences > 1)
871      return error("may only occur zero or one times!", ArgName);
872    break;
873  case Required:
874    if (NumOccurrences > 1)
875      return error("must occur exactly one time!", ArgName);
876    // Fall through
877  case OneOrMore:
878  case ZeroOrMore:
879  case ConsumeAfter: break;
880  default: return error("bad num occurrences flag value!");
881  }
882
883  return handleOccurrence(pos, ArgName, Value);
884}
885
886
887// getValueStr - Get the value description string, using "DefaultMsg" if nothing
888// has been specified yet.
889//
890static const char *getValueStr(const Option &O, const char *DefaultMsg) {
891  if (O.ValueStr[0] == 0) return DefaultMsg;
892  return O.ValueStr;
893}
894
895//===----------------------------------------------------------------------===//
896// cl::alias class implementation
897//
898
899// Return the width of the option tag for printing...
900size_t alias::getOptionWidth() const {
901  return std::strlen(ArgStr)+6;
902}
903
904// Print out the option for the alias.
905void alias::printOptionInfo(size_t GlobalWidth) const {
906  size_t L = std::strlen(ArgStr);
907  errs() << "  -" << ArgStr;
908  errs().indent(GlobalWidth-L-6) << " - " << HelpStr << "\n";
909}
910
911
912
913//===----------------------------------------------------------------------===//
914// Parser Implementation code...
915//
916
917// basic_parser implementation
918//
919
920// Return the width of the option tag for printing...
921size_t basic_parser_impl::getOptionWidth(const Option &O) const {
922  size_t Len = std::strlen(O.ArgStr);
923  if (const char *ValName = getValueName())
924    Len += std::strlen(getValueStr(O, ValName))+3;
925
926  return Len + 6;
927}
928
929// printOptionInfo - Print out information about this option.  The
930// to-be-maintained width is specified.
931//
932void basic_parser_impl::printOptionInfo(const Option &O,
933                                        size_t GlobalWidth) const {
934  outs() << "  -" << O.ArgStr;
935
936  if (const char *ValName = getValueName())
937    outs() << "=<" << getValueStr(O, ValName) << '>';
938
939  outs().indent(GlobalWidth-getOptionWidth(O)) << " - " << O.HelpStr << '\n';
940}
941
942
943
944
945// parser<bool> implementation
946//
947bool parser<bool>::parse(Option &O, StringRef ArgName,
948                         StringRef Arg, bool &Value) {
949  if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" ||
950      Arg == "1") {
951    Value = true;
952    return false;
953  }
954
955  if (Arg == "false" || Arg == "FALSE" || Arg == "False" || Arg == "0") {
956    Value = false;
957    return false;
958  }
959  return O.error("'" + Arg +
960                 "' is invalid value for boolean argument! Try 0 or 1");
961}
962
963// parser<boolOrDefault> implementation
964//
965bool parser<boolOrDefault>::parse(Option &O, StringRef ArgName,
966                                  StringRef Arg, boolOrDefault &Value) {
967  if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" ||
968      Arg == "1") {
969    Value = BOU_TRUE;
970    return false;
971  }
972  if (Arg == "false" || Arg == "FALSE" || Arg == "False" || Arg == "0") {
973    Value = BOU_FALSE;
974    return false;
975  }
976
977  return O.error("'" + Arg +
978                 "' is invalid value for boolean argument! Try 0 or 1");
979}
980
981// parser<int> implementation
982//
983bool parser<int>::parse(Option &O, StringRef ArgName,
984                        StringRef Arg, int &Value) {
985  if (Arg.getAsInteger(0, Value))
986    return O.error("'" + Arg + "' value invalid for integer argument!");
987  return false;
988}
989
990// parser<unsigned> implementation
991//
992bool parser<unsigned>::parse(Option &O, StringRef ArgName,
993                             StringRef Arg, unsigned &Value) {
994
995  if (Arg.getAsInteger(0, Value))
996    return O.error("'" + Arg + "' value invalid for uint argument!");
997  return false;
998}
999
1000// parser<double>/parser<float> implementation
1001//
1002static bool parseDouble(Option &O, StringRef Arg, double &Value) {
1003  SmallString<32> TmpStr(Arg.begin(), Arg.end());
1004  const char *ArgStart = TmpStr.c_str();
1005  char *End;
1006  Value = strtod(ArgStart, &End);
1007  if (*End != 0)
1008    return O.error("'" + Arg + "' value invalid for floating point argument!");
1009  return false;
1010}
1011
1012bool parser<double>::parse(Option &O, StringRef ArgName,
1013                           StringRef Arg, double &Val) {
1014  return parseDouble(O, Arg, Val);
1015}
1016
1017bool parser<float>::parse(Option &O, StringRef ArgName,
1018                          StringRef Arg, float &Val) {
1019  double dVal;
1020  if (parseDouble(O, Arg, dVal))
1021    return true;
1022  Val = (float)dVal;
1023  return false;
1024}
1025
1026
1027
1028// generic_parser_base implementation
1029//
1030
1031// findOption - Return the option number corresponding to the specified
1032// argument string.  If the option is not found, getNumOptions() is returned.
1033//
1034unsigned generic_parser_base::findOption(const char *Name) {
1035  unsigned e = getNumOptions();
1036
1037  for (unsigned i = 0; i != e; ++i) {
1038    if (strcmp(getOption(i), Name) == 0)
1039      return i;
1040  }
1041  return e;
1042}
1043
1044
1045// Return the width of the option tag for printing...
1046size_t generic_parser_base::getOptionWidth(const Option &O) const {
1047  if (O.hasArgStr()) {
1048    size_t Size = std::strlen(O.ArgStr)+6;
1049    for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
1050      Size = std::max(Size, std::strlen(getOption(i))+8);
1051    return Size;
1052  } else {
1053    size_t BaseSize = 0;
1054    for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
1055      BaseSize = std::max(BaseSize, std::strlen(getOption(i))+8);
1056    return BaseSize;
1057  }
1058}
1059
1060// printOptionInfo - Print out information about this option.  The
1061// to-be-maintained width is specified.
1062//
1063void generic_parser_base::printOptionInfo(const Option &O,
1064                                          size_t GlobalWidth) const {
1065  if (O.hasArgStr()) {
1066    size_t L = std::strlen(O.ArgStr);
1067    outs() << "  -" << O.ArgStr;
1068    outs().indent(GlobalWidth-L-6) << " - " << O.HelpStr << '\n';
1069
1070    for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
1071      size_t NumSpaces = GlobalWidth-strlen(getOption(i))-8;
1072      outs() << "    =" << getOption(i);
1073      outs().indent(NumSpaces) << " -   " << getDescription(i) << '\n';
1074    }
1075  } else {
1076    if (O.HelpStr[0])
1077      outs() << "  " << O.HelpStr << '\n';
1078    for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
1079      size_t L = std::strlen(getOption(i));
1080      outs() << "    -" << getOption(i);
1081      outs().indent(GlobalWidth-L-8) << " - " << getDescription(i) << '\n';
1082    }
1083  }
1084}
1085
1086
1087//===----------------------------------------------------------------------===//
1088// -help and -help-hidden option implementation
1089//
1090
1091static int OptNameCompare(const void *LHS, const void *RHS) {
1092  typedef std::pair<const char *, Option*> pair_ty;
1093
1094  return strcmp(((pair_ty*)LHS)->first, ((pair_ty*)RHS)->first);
1095}
1096
1097namespace {
1098
1099class HelpPrinter {
1100  size_t MaxArgLen;
1101  const Option *EmptyArg;
1102  const bool ShowHidden;
1103
1104public:
1105  explicit HelpPrinter(bool showHidden) : ShowHidden(showHidden) {
1106    EmptyArg = 0;
1107  }
1108
1109  void operator=(bool Value) {
1110    if (Value == false) return;
1111
1112    // Get all the options.
1113    SmallVector<Option*, 4> PositionalOpts;
1114    SmallVector<Option*, 4> SinkOpts;
1115    StringMap<Option*> OptMap;
1116    GetOptionInfo(PositionalOpts, SinkOpts, OptMap);
1117
1118    // Copy Options into a vector so we can sort them as we like.
1119    SmallVector<std::pair<const char *, Option*>, 128> Opts;
1120    SmallPtrSet<Option*, 128> OptionSet;  // Duplicate option detection.
1121
1122    for (StringMap<Option*>::iterator I = OptMap.begin(), E = OptMap.end();
1123         I != E; ++I) {
1124      // Ignore really-hidden options.
1125      if (I->second->getOptionHiddenFlag() == ReallyHidden)
1126        continue;
1127
1128      // Unless showhidden is set, ignore hidden flags.
1129      if (I->second->getOptionHiddenFlag() == Hidden && !ShowHidden)
1130        continue;
1131
1132      // If we've already seen this option, don't add it to the list again.
1133      if (!OptionSet.insert(I->second))
1134        continue;
1135
1136      Opts.push_back(std::pair<const char *, Option*>(I->getKey().data(),
1137                                                      I->second));
1138    }
1139
1140    // Sort the options list alphabetically.
1141    qsort(Opts.data(), Opts.size(), sizeof(Opts[0]), OptNameCompare);
1142
1143    if (ProgramOverview)
1144      outs() << "OVERVIEW: " << ProgramOverview << "\n";
1145
1146    outs() << "USAGE: " << ProgramName << " [options]";
1147
1148    // Print out the positional options.
1149    Option *CAOpt = 0;   // The cl::ConsumeAfter option, if it exists...
1150    if (!PositionalOpts.empty() &&
1151        PositionalOpts[0]->getNumOccurrencesFlag() == ConsumeAfter)
1152      CAOpt = PositionalOpts[0];
1153
1154    for (size_t i = CAOpt != 0, e = PositionalOpts.size(); i != e; ++i) {
1155      if (PositionalOpts[i]->ArgStr[0])
1156        outs() << " --" << PositionalOpts[i]->ArgStr;
1157      outs() << " " << PositionalOpts[i]->HelpStr;
1158    }
1159
1160    // Print the consume after option info if it exists...
1161    if (CAOpt) outs() << " " << CAOpt->HelpStr;
1162
1163    outs() << "\n\n";
1164
1165    // Compute the maximum argument length...
1166    MaxArgLen = 0;
1167    for (size_t i = 0, e = Opts.size(); i != e; ++i)
1168      MaxArgLen = std::max(MaxArgLen, Opts[i].second->getOptionWidth());
1169
1170    outs() << "OPTIONS:\n";
1171    for (size_t i = 0, e = Opts.size(); i != e; ++i)
1172      Opts[i].second->printOptionInfo(MaxArgLen);
1173
1174    // Print any extra help the user has declared.
1175    for (std::vector<const char *>::iterator I = MoreHelp->begin(),
1176          E = MoreHelp->end(); I != E; ++I)
1177      outs() << *I;
1178    MoreHelp->clear();
1179
1180    // Halt the program since help information was printed
1181    exit(1);
1182  }
1183};
1184} // End anonymous namespace
1185
1186// Define the two HelpPrinter instances that are used to print out help, or
1187// help-hidden...
1188//
1189static HelpPrinter NormalPrinter(false);
1190static HelpPrinter HiddenPrinter(true);
1191
1192static cl::opt<HelpPrinter, true, parser<bool> >
1193HOp("help", cl::desc("Display available options (-help-hidden for more)"),
1194    cl::location(NormalPrinter), cl::ValueDisallowed);
1195
1196static cl::opt<HelpPrinter, true, parser<bool> >
1197HHOp("help-hidden", cl::desc("Display all available options"),
1198     cl::location(HiddenPrinter), cl::Hidden, cl::ValueDisallowed);
1199
1200static void (*OverrideVersionPrinter)() = 0;
1201
1202static int TargetArraySortFn(const void *LHS, const void *RHS) {
1203  typedef std::pair<const char *, const Target*> pair_ty;
1204  return strcmp(((const pair_ty*)LHS)->first, ((const pair_ty*)RHS)->first);
1205}
1206
1207namespace {
1208class VersionPrinter {
1209public:
1210  void print() {
1211    raw_ostream &OS = outs();
1212    OS << "Low Level Virtual Machine (http://llvm.org/):\n"
1213       << "  " << PACKAGE_NAME << " version " << PACKAGE_VERSION;
1214#ifdef LLVM_VERSION_INFO
1215    OS << LLVM_VERSION_INFO;
1216#endif
1217    OS << "\n  ";
1218#ifndef __OPTIMIZE__
1219    OS << "DEBUG build";
1220#else
1221    OS << "Optimized build";
1222#endif
1223#ifndef NDEBUG
1224    OS << " with assertions";
1225#endif
1226    std::string CPU = sys::getHostCPUName();
1227    if (CPU == "generic") CPU = "(unknown)";
1228    OS << ".\n"
1229#if (ENABLE_TIMESTAMPS == 1)
1230       << "  Built " << __DATE__ << " (" << __TIME__ << ").\n"
1231#endif
1232       << "  Host: " << sys::getHostTriple() << '\n'
1233       << "  Host CPU: " << CPU << '\n'
1234       << '\n'
1235       << "  Registered Targets:\n";
1236
1237    std::vector<std::pair<const char *, const Target*> > Targets;
1238    size_t Width = 0;
1239    for (TargetRegistry::iterator it = TargetRegistry::begin(),
1240           ie = TargetRegistry::end(); it != ie; ++it) {
1241      Targets.push_back(std::make_pair(it->getName(), &*it));
1242      Width = std::max(Width, strlen(Targets.back().first));
1243    }
1244    if (!Targets.empty())
1245      qsort(&Targets[0], Targets.size(), sizeof(Targets[0]),
1246            TargetArraySortFn);
1247
1248    for (unsigned i = 0, e = Targets.size(); i != e; ++i) {
1249      OS << "    " << Targets[i].first;
1250      OS.indent(Width - strlen(Targets[i].first)) << " - "
1251             << Targets[i].second->getShortDescription() << '\n';
1252    }
1253    if (Targets.empty())
1254      OS << "    (none)\n";
1255  }
1256  void operator=(bool OptionWasSpecified) {
1257    if (!OptionWasSpecified) return;
1258
1259    if (OverrideVersionPrinter == 0) {
1260      print();
1261      exit(1);
1262    }
1263    (*OverrideVersionPrinter)();
1264    exit(1);
1265  }
1266};
1267} // End anonymous namespace
1268
1269
1270// Define the --version option that prints out the LLVM version for the tool
1271static VersionPrinter VersionPrinterInstance;
1272
1273static cl::opt<VersionPrinter, true, parser<bool> >
1274VersOp("version", cl::desc("Display the version of this program"),
1275    cl::location(VersionPrinterInstance), cl::ValueDisallowed);
1276
1277// Utility function for printing the help message.
1278void cl::PrintHelpMessage() {
1279  // This looks weird, but it actually prints the help message. The
1280  // NormalPrinter variable is a HelpPrinter and the help gets printed when
1281  // its operator= is invoked. That's because the "normal" usages of the
1282  // help printer is to be assigned true/false depending on whether the
1283  // -help option was given or not. Since we're circumventing that we have
1284  // to make it look like -help was given, so we assign true.
1285  NormalPrinter = true;
1286}
1287
1288/// Utility function for printing version number.
1289void cl::PrintVersionMessage() {
1290  VersionPrinterInstance.print();
1291}
1292
1293void cl::SetVersionPrinter(void (*func)()) {
1294  OverrideVersionPrinter = func;
1295}
1296