diff options
author | Daniel Dunbar <daniel@zuster.org> | 2011-01-18 01:59:24 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2011-01-18 01:59:24 +0000 |
commit | f4fb66acae1ae9a296c091a7a857c1d01953b444 (patch) | |
tree | 495af180146dd140aa7e3cf739cf77c7633915b1 /lib/Support/CommandLine.cpp | |
parent | cdfe3c359b1c6003aca559d7a3d3b15168c419d4 (diff) |
Support/CommandLine: Add "Did you mean" print for mismatched operands.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123717 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support/CommandLine.cpp')
-rw-r--r-- | lib/Support/CommandLine.cpp | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp index 6f5d9dd428..2b4fba8062 100644 --- a/lib/Support/CommandLine.cpp +++ b/lib/Support/CommandLine.cpp @@ -180,6 +180,34 @@ static Option *LookupOption(StringRef &Arg, StringRef &Value, return I->second; } +/// LookupNearestOption - Lookup the closest match to the option specified by +/// the specified option on the command line. If there is a value specified +/// (after an equal sign) return that as well. This assumes that leading dashes +/// have already been stripped. +static Option *LookupNearestOption(StringRef Arg, + const StringMap<Option*> &OptionsMap) { + // Reject all dashes. + if (Arg.empty()) return 0; + + // Split on any equal sign. + StringRef LHS = Arg.split('=').first; + + // Find the closest match. + Option *Best = 0; + unsigned BestDistance = 0; + for (StringMap<Option*>::const_iterator it = OptionsMap.begin(), + ie = OptionsMap.end(); it != ie; ++it) { + unsigned Distance = StringRef(it->second->ArgStr).edit_distance( + Arg, /*AllowReplacements=*/true, /*MaxEditDistance=*/BestDistance); + if (!Best || Distance < BestDistance) { + Best = it->second; + BestDistance = Distance; + } + } + + return Best; +} + /// CommaSeparateAndAddOccurence - A wrapper around Handler->addOccurence() that /// does special handling of cl::CommaSeparated options. static bool CommaSeparateAndAddOccurence(Option *Handler, unsigned pos, @@ -571,6 +599,7 @@ void cl::ParseCommandLineOptions(int argc, char **argv, bool DashDashFound = false; // Have we read '--'? for (int i = 1; i < argc; ++i) { Option *Handler = 0; + Option *NearestHandler = 0; StringRef Value; StringRef ArgName = ""; @@ -644,12 +673,22 @@ void cl::ParseCommandLineOptions(int argc, char **argv, if (Handler == 0) Handler = HandlePrefixedOrGroupedOption(ArgName, Value, ErrorParsing, Opts); + + // Otherwise, look for the closest available option to report to the user + // in the upcoming error. + if (Handler == 0 && SinkOpts.empty()) + NearestHandler = LookupNearestOption(ArgName, Opts); } if (Handler == 0) { if (SinkOpts.empty()) { errs() << ProgramName << ": Unknown command line argument '" << argv[i] << "'. Try: '" << argv[0] << " -help'\n"; + + // If we know a near match, report it as well. + errs() << ProgramName << ": Did you mean '-" + << NearestHandler->ArgStr << "'?\n"; + ErrorParsing = true; } else { for (SmallVectorImpl<Option*>::iterator I = SinkOpts.begin(), |