llvm.org GIT mirror llvm / ed4e4a5
Re-reland "[Option] Fix PR37006 prefix choice in findNearest" This was first reviewed in https://reviews.llvm.org/D46776 and landed in r332299, but got reverted because it broke the PS4 bots. https://reviews.llvm.org/D50410 fixed this, and then this change was re-reviewed at https://reviews.llvm.org/D50515 and relanded in r341329. It got reverted due to causing MSan issues. However, nobody wrote down the error message and the bot link is dead, so I'm relanding this to capture the MSan error. I'll then either fix it, or copy it somewhere and revert if fixing looks difficult. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@359580 91177308-0d34-0410-b5e6-96231b3b80d8 Nico Weber 3 months ago
3 changed file(s) with 30 addition(s) and 25 deletion(s). Raw diff Collapse all Expand all
250250 unsigned MinimumLength) const {
251251 assert(!Option.empty());
252252
253 // Consider each option as a candidate, finding the closest match.
253 // Consider each [option prefix + option name] pair as a candidate, finding
254 // the closest match.
254255 unsigned BestDistance = UINT_MAX;
255256 for (const Info &CandidateInfo :
256257 ArrayRef(OptionInfos).drop_front(FirstSearchableIndex)) {
257258 StringRef CandidateName = CandidateInfo.Name;
258259
259 // Ignore option candidates with empty names, such as "--", or names
260 // that do not meet the minimum length.
260 // We can eliminate some option prefix/name pairs as candidates right away:
261 // * Ignore option candidates with empty names, such as "--", or names
262 // that do not meet the minimum length.
261263 if (CandidateName.empty() || CandidateName.size() < MinimumLength)
262264 continue;
263265
264 // If FlagsToInclude were specified, ignore options that don't include
265 // those flags.
266 // * If FlagsToInclude were specified, ignore options that don't include
267 // those flags.
266268 if (FlagsToInclude && !(CandidateInfo.Flags & FlagsToInclude))
267269 continue;
268 // Ignore options that contain the FlagsToExclude.
270 // * Ignore options that contain the FlagsToExclude.
269271 if (CandidateInfo.Flags & FlagsToExclude)
270272 continue;
271273
272 // Ignore positional argument option candidates (which do not
273 // have prefixes).
274 // * Ignore positional argument option candidates (which do not
275 // have prefixes).
274276 if (!CandidateInfo.Prefixes)
275277 continue;
276 // Find the most appropriate prefix. For example, if a user asks for
277 // "--helm", suggest "--help" over "-help".
278 StringRef Prefix = CandidateInfo.Prefixes[0];
279 for (int P = 1; CandidateInfo.Prefixes[P]; P++) {
280 if (Option.startswith(CandidateInfo.Prefixes[P]))
281 Prefix = CandidateInfo.Prefixes[P];
282 }
283
284 // Check if the candidate ends with a character commonly used when
278
279 // Now check if the candidate ends with a character commonly used when
285280 // delimiting an option from its value, such as '=' or ':'. If it does,
286281 // attempt to split the given option based on that delimiter.
287282 std::string Delimiter = "";
295290 else
296291 std::tie(LHS, RHS) = Option.split(Last);
297292
298 std::string NormalizedName =
299 (LHS.drop_front(Prefix.size()) + Delimiter).str();
300 unsigned Distance =
301 CandidateName.edit_distance(NormalizedName, /*AllowReplacements=*/true,
302 /*MaxEditDistance=*/BestDistance);
303 if (Distance < BestDistance) {
304 BestDistance = Distance;
305 NearestString = (Prefix + CandidateName + RHS).str();
293 // Consider each possible prefix for each candidate to find the most
294 // appropriate one. For example, if a user asks for "--helm", suggest
295 // "--help" over "-help".
296 for (int P = 0; const char *const CandidatePrefix = CandidateInfo.Prefixes[P]; P++) {
297 std::string NormalizedName = (LHS + Delimiter).str();
298 StringRef Candidate = (CandidatePrefix + CandidateName).str();
299 unsigned Distance =
300 Candidate.edit_distance(NormalizedName, /*AllowReplacements=*/true,
301 /*MaxEditDistance=*/BestDistance);
302 if (Distance < BestDistance) {
303 BestDistance = Distance;
304 NearestString = (Candidate + RHS).str();
305 }
306306 }
307307 }
308308 return BestDistance;
285285 EXPECT_EQ(Nearest, "-blorp");
286286 EXPECT_EQ(1U, T.findNearest("--blorm", Nearest));
287287 EXPECT_EQ(Nearest, "--blorp");
288 EXPECT_EQ(1U, T.findNearest("-blarg", Nearest));
289 EXPECT_EQ(Nearest, "-blarn");
290 EXPECT_EQ(1U, T.findNearest("--blarm", Nearest));
291 EXPECT_EQ(Nearest, "--blarn");
288292 EXPECT_EQ(1U, T.findNearest("-fjormp", Nearest));
289293 EXPECT_EQ(Nearest, "--fjormp");
290294
2929 def SlurpJoined : Option<["-"], "slurpjoined", KIND_REMAINING_ARGS_JOINED>;
3030
3131 def Blorp : Flag<["-", "--"], "blorp">, HelpText<"The blorp option">, Flags<[OptFlag1]>;
32 def Blarn : Flag<["--", "-"], "blarn">, HelpText<"The blarn option">, Flags<[OptFlag1]>;
3233 def Cramb : Joined<["/"], "cramb:">, HelpText<"The cramb option">, MetaVarName<"CRAMB">, Flags<[OptFlag1]>;
3334 def Doopf1 : Flag<["-"], "doopf1">, HelpText<"The doopf1 option">, Flags<[OptFlag1]>;
3435 def Doopf2 : Flag<["-"], "doopf2">, HelpText<"The doopf2 option">, Flags<[OptFlag2]>;