In option typo correction, consider -foo=VALUE flags as two distinct parts. The
authorNick Lewycky <nicholas@mxc.ca>
Mon, 2 May 2011 05:24:47 +0000 (05:24 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Mon, 2 May 2011 05:24:47 +0000 (05:24 +0000)
comments claimed it did this, but the LHS value was actually an unused variable.

The new system considers only the '-foo' part when comparing it for typos
against flags that have values, but still look at the whole string for flags
that don't. That way, we'll still correct '-inst=combine' to '-instcombine'.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@130685 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Support/CommandLine.cpp

index a1f2fce8bf1348c9dccca9aaa20f1177eda069c9..7f1c0d320b11f7a27867b83806bdd4c784826372 100644 (file)
@@ -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 = "";