[llvm] 405e836 - [CommandLine] Add inline ArgName printing

Don Hinton via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 6 08:17:59 PST 2019


Author: Don Hinton
Date: 2019-11-06T08:17:33-08:00
New Revision: 405e83689fb42f8ae673d9a26bd21366c4a055be

URL: https://github.com/llvm/llvm-project/commit/405e83689fb42f8ae673d9a26bd21366c4a055be
DIFF: https://github.com/llvm/llvm-project/commit/405e83689fb42f8ae673d9a26bd21366c4a055be.diff

LOG: [CommandLine] Add inline ArgName printing

Summary:
This patch adds PrintArgInline (after PrintArg) that strips the
leading spaces from an argument before printing them, for usage
inline.

Related bug: PR42943 <https://bugs.llvm.org/show_bug.cgi?id=42943>

Patch by Daan Sprenkels!

Reviewers: jhenderson, chandlerc, hintonda

Reviewed By: jhenderson

Subscribers: hiraditya, kristina, llvm-commits, dsprenkels

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D69501

Added: 
    

Modified: 
    llvm/lib/Support/CommandLine.cpp
    llvm/unittests/Support/CommandLineTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp
index 620f7ffd4c9f..92e0f5b22104 100644
--- a/llvm/lib/Support/CommandLine.cpp
+++ b/llvm/lib/Support/CommandLine.cpp
@@ -88,21 +88,26 @@ void parser<char>::anchor() {}
 
 //===----------------------------------------------------------------------===//
 
-static StringRef ArgPrefix = "  -";
-static StringRef ArgPrefixLong = "  --";
+const static size_t DefaultPad = 2;
+
+static StringRef ArgPrefix = "-";
+static StringRef ArgPrefixLong = "--";
 static StringRef ArgHelpPrefix = " - ";
 
-static size_t argPlusPrefixesSize(StringRef ArgName) {
+static size_t argPlusPrefixesSize(StringRef ArgName, size_t Pad = DefaultPad) {
   size_t Len = ArgName.size();
   if (Len == 1)
-    return Len + ArgPrefix.size() + ArgHelpPrefix.size();
-  return Len + ArgPrefixLong.size() + ArgHelpPrefix.size();
+    return Len + Pad + ArgPrefix.size() + ArgHelpPrefix.size();
+  return Len + Pad + ArgPrefixLong.size() + ArgHelpPrefix.size();
 }
 
-static StringRef argPrefix(StringRef ArgName) {
-  if (ArgName.size() == 1)
-    return ArgPrefix;
-  return ArgPrefixLong;
+static SmallString<8> argPrefix(StringRef ArgName, size_t Pad = DefaultPad) {
+  SmallString<8> Prefix;
+  for (size_t I = 0; I < Pad; ++I) {
+    Prefix.push_back(' ');
+  }
+  Prefix.append(ArgName.size() > 1 ? ArgPrefixLong : ArgPrefix);
+  return Prefix;
 }
 
 // Option predicates...
@@ -119,13 +124,14 @@ namespace {
 
 class PrintArg {
   StringRef ArgName;
+  size_t Pad;
 public:
-  PrintArg(StringRef ArgName) : ArgName(ArgName) {}
-  friend raw_ostream &operator<<(raw_ostream &OS, const PrintArg&);
+  PrintArg(StringRef ArgName, size_t Pad = DefaultPad) : ArgName(ArgName), Pad(Pad) {}
+  friend raw_ostream &operator<<(raw_ostream &OS, const PrintArg &);
 };
 
 raw_ostream &operator<<(raw_ostream &OS, const PrintArg& Arg) {
-  OS << argPrefix(Arg.ArgName) << Arg.ArgName;
+  OS << argPrefix(Arg.ArgName, Arg.Pad) << Arg.ArgName;
   return OS;
 }
 
@@ -1447,7 +1453,7 @@ bool CommandLineParser::ParseCommandLineOptions(int argc,
         if (NearestHandler) {
           // If we know a near match, report it as well.
           *Errs << ProgramName << ": Did you mean '"
-                << PrintArg(NearestHandlerString) << "'?\n";
+                << PrintArg(NearestHandlerString, 0) << "'?\n";
         }
 
         ErrorParsing = true;
@@ -1601,7 +1607,7 @@ bool Option::error(const Twine &Message, StringRef ArgName, raw_ostream &Errs) {
   if (ArgName.empty())
     Errs << HelpStr; // Be nice for positional arguments
   else
-    Errs << GlobalParser->ProgramName << ": for the " << PrintArg(ArgName);
+    Errs << GlobalParser->ProgramName << ": for the " << PrintArg(ArgName, 0);
 
   Errs << " option: " << Message << "\n";
   return true;

diff  --git a/llvm/unittests/Support/CommandLineTest.cpp b/llvm/unittests/Support/CommandLineTest.cpp
index 1a1c8a4404e3..1948413070ae 100644
--- a/llvm/unittests/Support/CommandLineTest.cpp
+++ b/llvm/unittests/Support/CommandLineTest.cpp
@@ -1653,4 +1653,54 @@ TEST(CommandLineTest, LongOptions) {
   EXPECT_TRUE(Errs.empty()); Errs.clear();
   cl::ResetAllOptionOccurrences();
 }
+
+TEST(CommandLineTest, OptionErrorMessage) {
+  // When there is an error, we expect some error message like:
+  //   prog: for the -a option: [...]
+  //
+  // Test whether the "for the -a option"-part is correctly formatted.
+  cl::ResetCommandLineParser();
+
+  StackOption<bool> OptA("a", cl::desc("Some option"));
+  StackOption<bool> OptLong("long", cl::desc("Some long option"));
+
+  std::string Errs;
+  raw_string_ostream OS(Errs);
+
+  OptA.error("custom error", OS);
+  OS.flush();
+  EXPECT_FALSE(Errs.find("for the -a option:") == std::string::npos);
+  Errs.clear();
+
+  OptLong.error("custom error", OS);
+  OS.flush();
+  EXPECT_FALSE(Errs.find("for the --long option:") == std::string::npos);
+  Errs.clear();
+
+  cl::ResetAllOptionOccurrences();
+}
+
+TEST(CommandLineTest, OptionErrorMessageSuggest) {
+  // When there is an error, and the edit-distance is not very large,
+  // we expect some error message like:
+  //   prog: did you mean '--option'?
+  //
+  // Test whether this message is well-formatted.
+  cl::ResetCommandLineParser();
+
+  StackOption<bool> OptLong("aluminium", cl::desc("Some long option"));
+
+  const char *args[] = {"prog", "--aluminum"};
+
+  std::string Errs;
+  raw_string_ostream OS(Errs);
+
+  EXPECT_FALSE(cl::ParseCommandLineOptions(2, args, StringRef(), &OS));
+  OS.flush();
+  EXPECT_FALSE(Errs.find("prog: Did you mean '--aluminium'?\n") ==
+               std::string::npos);
+  Errs.clear();
+
+  cl::ResetAllOptionOccurrences();
+}
 }  // anonymous namespace


        


More information about the llvm-commits mailing list