From d481df53104d0da83924075b9a0f15024d6232ef Mon Sep 17 00:00:00 2001 From: Brian Gesiak Date: Tue, 9 Jan 2018 19:38:04 +0000 Subject: [PATCH] [Option] For typo '-foo', suggest '--foo' Summary: https://reviews.llvm.org/rL321877 introduced the `OptTable::findNearest` method, to find the closest edit distance option for a given string. However, the implementation contained a bug: for a typo `-foo` with an edit distance of 1 away from a valid option `--foo`, `findNearest` would suggest a nearby option of `foo`. That is, the result would not include the `--` prefix, and so was not a valid option. Fix the bug by ensuring that the prefix string is initialized to one of the valid prefixes for the option. Test Plan: `check-llvm-unit` Reviewers: v.g.vassilev, teemperor, ruiu, jroelofs, yamaguchi Reviewed By: jroelofs Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D41873 llvm-svn: 322109 --- llvm/lib/Option/OptTable.cpp | 4 ++-- llvm/unittests/Option/OptionParsingTest.cpp | 2 ++ llvm/unittests/Option/Opts.td | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Option/OptTable.cpp b/llvm/lib/Option/OptTable.cpp index f85b90430917..dcd1cc46d964 100644 --- a/llvm/lib/Option/OptTable.cpp +++ b/llvm/lib/Option/OptTable.cpp @@ -277,8 +277,8 @@ unsigned OptTable::findNearest(StringRef Option, std::string &NearestString, continue; // Find the most appropriate prefix. For example, if a user asks for // "--helm", suggest "--help" over "-help". - StringRef Prefix; - for (int P = 0; CandidateInfo.Prefixes[P]; P++) { + StringRef Prefix = CandidateInfo.Prefixes[0]; + for (int P = 1; CandidateInfo.Prefixes[P]; P++) { if (Option.startswith(CandidateInfo.Prefixes[P])) Prefix = CandidateInfo.Prefixes[P]; } diff --git a/llvm/unittests/Option/OptionParsingTest.cpp b/llvm/unittests/Option/OptionParsingTest.cpp index 26bbb37602fb..eef21ab51209 100644 --- a/llvm/unittests/Option/OptionParsingTest.cpp +++ b/llvm/unittests/Option/OptionParsingTest.cpp @@ -283,6 +283,8 @@ TEST(Option, FindNearest) { EXPECT_EQ(Nearest, "-blorp"); EXPECT_EQ(1U, T.findNearest("--blorm", Nearest)); EXPECT_EQ(Nearest, "--blorp"); + EXPECT_EQ(1U, T.findNearest("-fjormp", Nearest)); + EXPECT_EQ(Nearest, "--fjormp"); // The nearest candidate respects the prefix and value delimiter // of the original string. diff --git a/llvm/unittests/Option/Opts.td b/llvm/unittests/Option/Opts.td index 539850df1343..c4544b5b3f9b 100644 --- a/llvm/unittests/Option/Opts.td +++ b/llvm/unittests/Option/Opts.td @@ -34,4 +34,5 @@ def Cramb : Joined<["/"], "cramb:">, HelpText<"The cramb option">, MetaVarName<" def Doopf1 : Flag<["-"], "doopf1">, HelpText<"The doopf1 option">, Flags<[OptFlag1]>; def Doopf2 : Flag<["-"], "doopf2">, HelpText<"The doopf2 option">, Flags<[OptFlag2]>; def Ermgh : Joined<["--"], "ermgh">, HelpText<"The ermgh option">, MetaVarName<"ERMGH">, Flags<[OptFlag1]>; +def Fjormp : Flag<["--"], "fjormp">, HelpText<"The fjormp option">, Flags<[OptFlag1]>; def DashDash : Option<["--"], "", KIND_REMAINING_ARGS>;