diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2011-05-02 19:34:44 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2011-05-02 19:34:44 +0000 | 
| commit | 6b943ff3a3f8617113ecbf611cf0f8957e4e19d2 (patch) | |
| tree | fc5f365fb9035b2d0c622bbf06c9bbe8627d7279 /lib/Support/CommandLine.cpp | |
| parent | d0e4e96dc17a6c1c6de3340842c80f0e187ba349 (diff) | |
Notes
Diffstat (limited to 'lib/Support/CommandLine.cpp')
| -rw-r--r-- | lib/Support/CommandLine.cpp | 193 | 
1 files changed, 162 insertions, 31 deletions
diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp index 7e744993a7cb0..7f1c0d320b11f 100644 --- a/lib/Support/CommandLine.cpp +++ b/lib/Support/CommandLine.cpp @@ -186,12 +186,14 @@ static Option *LookupOption(StringRef &Arg, StringRef &Value,  /// have already been stripped.  static Option *LookupNearestOption(StringRef Arg,                                     const StringMap<Option*> &OptionsMap, -                                   const char *&NearestString) { +                                   std::string &NearestString) {    // Reject all dashes.    if (Arg.empty()) return 0;    // Split on any equal sign. -  StringRef LHS = Arg.split('=').first; +  std::pair<StringRef, StringRef> SplitArg = Arg.split('='); +  StringRef &LHS = SplitArg.first;  // LHS == Arg when no '=' is present. +  StringRef &RHS = SplitArg.second;    // Find the closest match.    Option *Best = 0; @@ -204,14 +206,19 @@ static Option *LookupNearestOption(StringRef Arg,      if (O->ArgStr[0])        OptionNames.push_back(O->ArgStr); +    bool PermitValue = O->getValueExpectedFlag() != cl::ValueDisallowed; +    StringRef Flag = PermitValue ? LHS : Arg;      for (size_t i = 0, e = OptionNames.size(); i != e; ++i) {        StringRef Name = OptionNames[i];        unsigned Distance = StringRef(Name).edit_distance( -        Arg, /*AllowReplacements=*/true, /*MaxEditDistance=*/BestDistance); +        Flag, /*AllowReplacements=*/true, /*MaxEditDistance=*/BestDistance);        if (!Best || Distance < BestDistance) {          Best = O; -        NearestString = OptionNames[i];          BestDistance = Distance; +	if (RHS.empty() || !PermitValue) +	  NearestString = OptionNames[i]; +	else +	  NearestString = std::string(OptionNames[i]) + "=" + RHS.str();        }      }    } @@ -611,7 +618,7 @@ void cl::ParseCommandLineOptions(int argc, char **argv,    for (int i = 1; i < argc; ++i) {      Option *Handler = 0;      Option *NearestHandler = 0; -    const char *NearestHandlerString = 0; +    std::string NearestHandlerString;      StringRef Value;      StringRef ArgName = ""; @@ -908,8 +915,6 @@ void alias::printOptionInfo(size_t GlobalWidth) const {    errs().indent(GlobalWidth-L-6) << " - " << HelpStr << "\n";  } - -  //===----------------------------------------------------------------------===//  // Parser Implementation code...  // @@ -939,7 +944,11 @@ void basic_parser_impl::printOptionInfo(const Option &O,    outs().indent(GlobalWidth-getOptionWidth(O)) << " - " << O.HelpStr << '\n';  } - +void basic_parser_impl::printOptionName(const Option &O, +                                        size_t GlobalWidth) const { +  outs() << "  -" << O.ArgStr; +  outs().indent(GlobalWidth-std::strlen(O.ArgStr)); +}  // parser<bool> implementation @@ -1083,6 +1092,89 @@ void generic_parser_base::printOptionInfo(const Option &O,    }  } +static const size_t MaxOptWidth = 8; // arbitrary spacing for printOptionDiff + +// printGenericOptionDiff - Print the value of this option and it's default. +// +// "Generic" options have each value mapped to a name. +void generic_parser_base:: +printGenericOptionDiff(const Option &O, const GenericOptionValue &Value, +                       const GenericOptionValue &Default, +                       size_t GlobalWidth) const { +  outs() << "  -" << O.ArgStr; +  outs().indent(GlobalWidth-std::strlen(O.ArgStr)); + +  unsigned NumOpts = getNumOptions(); +  for (unsigned i = 0; i != NumOpts; ++i) { +    if (Value.compare(getOptionValue(i))) +      continue; + +    outs() << "= " << getOption(i); +    size_t L = std::strlen(getOption(i)); +    size_t NumSpaces = MaxOptWidth > L ? MaxOptWidth - L : 0; +    outs().indent(NumSpaces) << " (default: "; +    for (unsigned j = 0; j != NumOpts; ++j) { +      if (Default.compare(getOptionValue(j))) +        continue; +      outs() << getOption(j); +      break; +    } +    outs() << ")\n"; +    return; +  } +  outs() << "= *unknown option value*\n"; +} + +// printOptionDiff - Specializations for printing basic value types. +// +#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";                                                    \ +  }                                                                     \ + +PRINT_OPT_DIFF(bool) +PRINT_OPT_DIFF(boolOrDefault) +PRINT_OPT_DIFF(int) +PRINT_OPT_DIFF(unsigned) +PRINT_OPT_DIFF(double) +PRINT_OPT_DIFF(float) +PRINT_OPT_DIFF(char) + +void parser<std::string>:: +printOptionDiff(const Option &O, StringRef V, OptionValue<std::string> D, +                size_t GlobalWidth) const { +  printOptionName(O, GlobalWidth); +  outs() << "= " << V; +  size_t NumSpaces = MaxOptWidth > V.size() ? MaxOptWidth - V.size() : 0; +  outs().indent(NumSpaces) << " (default: "; +  if (D.hasValue()) +    outs() << D.getValue(); +  else +    outs() << "*no default*"; +  outs() << ")\n"; +} + +// Print a placeholder for options that don't yet support printOptionDiff(). +void basic_parser_impl:: +printOptionNoValue(const Option &O, size_t GlobalWidth) const { +  printOptionName(O, GlobalWidth); +  outs() << "= *cannot print option value*\n"; +}  //===----------------------------------------------------------------------===//  // -help and -help-hidden option implementation @@ -1094,6 +1186,35 @@ static int OptNameCompare(const void *LHS, const void *RHS) {    return strcmp(((pair_ty*)LHS)->first, ((pair_ty*)RHS)->first);  } +// Copy Options into a vector so we can sort them as we like. +static void +sortOpts(StringMap<Option*> &OptMap, +         SmallVectorImpl< std::pair<const char *, Option*> > &Opts, +         bool ShowHidden) { +  SmallPtrSet<Option*, 128> OptionSet;  // Duplicate option detection. + +  for (StringMap<Option*>::iterator I = OptMap.begin(), E = OptMap.end(); +       I != E; ++I) { +    // Ignore really-hidden options. +    if (I->second->getOptionHiddenFlag() == ReallyHidden) +      continue; + +    // Unless showhidden is set, ignore hidden flags. +    if (I->second->getOptionHiddenFlag() == Hidden && !ShowHidden) +      continue; + +    // If we've already seen this option, don't add it to the list again. +    if (!OptionSet.insert(I->second)) +      continue; + +    Opts.push_back(std::pair<const char *, Option*>(I->getKey().data(), +                                                    I->second)); +  } + +  // Sort the options list alphabetically. +  qsort(Opts.data(), Opts.size(), sizeof(Opts[0]), OptNameCompare); +} +  namespace {  class HelpPrinter { @@ -1115,30 +1236,8 @@ public:      StringMap<Option*> OptMap;      GetOptionInfo(PositionalOpts, SinkOpts, OptMap); -    // Copy Options into a vector so we can sort them as we like.      SmallVector<std::pair<const char *, Option*>, 128> Opts; -    SmallPtrSet<Option*, 128> OptionSet;  // Duplicate option detection. - -    for (StringMap<Option*>::iterator I = OptMap.begin(), E = OptMap.end(); -         I != E; ++I) { -      // Ignore really-hidden options. -      if (I->second->getOptionHiddenFlag() == ReallyHidden) -        continue; - -      // Unless showhidden is set, ignore hidden flags. -      if (I->second->getOptionHiddenFlag() == Hidden && !ShowHidden) -        continue; - -      // If we've already seen this option, don't add it to the list again. -      if (!OptionSet.insert(I->second)) -        continue; - -      Opts.push_back(std::pair<const char *, Option*>(I->getKey().data(), -                                                      I->second)); -    } - -    // Sort the options list alphabetically. -    qsort(Opts.data(), Opts.size(), sizeof(Opts[0]), OptNameCompare); +    sortOpts(OptMap, Opts, ShowHidden);      if (ProgramOverview)        outs() << "OVERVIEW: " << ProgramOverview << "\n"; @@ -1197,6 +1296,38 @@ static cl::opt<HelpPrinter, true, parser<bool> >  HHOp("help-hidden", cl::desc("Display all available options"),       cl::location(HiddenPrinter), cl::Hidden, cl::ValueDisallowed); +static cl::opt<bool> +PrintOptions("print-options", +             cl::desc("Print non-default options after command line parsing"), +             cl::Hidden, cl::init(false)); + +static cl::opt<bool> +PrintAllOptions("print-all-options", +                cl::desc("Print all option values after command line parsing"), +                cl::Hidden, cl::init(false)); + +// Print the value of each option. +void cl::PrintOptionValues() { +  if (!PrintOptions && !PrintAllOptions) return; + +  // Get all the options. +  SmallVector<Option*, 4> PositionalOpts; +  SmallVector<Option*, 4> SinkOpts; +  StringMap<Option*> OptMap; +  GetOptionInfo(PositionalOpts, SinkOpts, OptMap); + +  SmallVector<std::pair<const char *, Option*>, 128> Opts; +  sortOpts(OptMap, Opts, /*ShowHidden*/true); + +  // Compute the maximum argument length... +  size_t MaxArgLen = 0; +  for (size_t i = 0, e = Opts.size(); i != e; ++i) +    MaxArgLen = std::max(MaxArgLen, Opts[i].second->getOptionWidth()); + +  for (size_t i = 0, e = Opts.size(); i != e; ++i) +    Opts[i].second->printOptionValue(MaxArgLen, PrintAllOptions); +} +  static void (*OverrideVersionPrinter)() = 0;  static int TargetArraySortFn(const void *LHS, const void *RHS) {  | 
