[PATCH] Better output for long help strings for command-line options.

Alexander Kornienko alexfh at google.com
Fri May 10 08:03:14 PDT 2013


Hi atrick,

This patch allows using \n inside long help strings for command-line
options, so that all lines are equally indented. This is not a perfect solution,
as we don't (and probably don't want to) know about terminal width, but it
allows to format long help strings somehow readable without manually padding
them with spaces. A motivating example is -help output from clang-format (source
code in tools/clang-format/ClangFormat.cpp, see cl options offset, length,
style, and dump-config).

http://llvm-reviews.chandlerc.com/D779

Files:
  docs/CommandLine.rst
  lib/Support/CommandLine.cpp

Index: docs/CommandLine.rst
===================================================================
--- docs/CommandLine.rst
+++ docs/CommandLine.rst
@@ -930,7 +930,8 @@
 .. _cl::desc(...):
 
 * The **cl::desc** attribute specifies a description for the option to be
-  shown in the ``-help`` output for the program.
+  shown in the ``-help`` output for the program. This attribute supports
+  multi-line descriptions with lines separated by '\n'.
 
 .. _cl::value_desc:
 
Index: lib/Support/CommandLine.cpp
===================================================================
--- lib/Support/CommandLine.cpp
+++ lib/Support/CommandLine.cpp
@@ -913,11 +913,20 @@
   return std::strlen(ArgStr)+6;
 }
 
+void printHelpStr(StringRef HelpStr, size_t Indent,
+                  size_t FirstLineIndentedBy) {
+  std::pair<StringRef, StringRef> Split = HelpStr.split('\n');
+  outs().indent(Indent - FirstLineIndentedBy) << " - " << Split.first << "\n";
+  while (!Split.second.empty()) {
+    Split = Split.second.split('\n');
+    outs().indent(Indent) << Split.first << "\n";
+  }
+}
+
 // Print out the option for the alias.
 void alias::printOptionInfo(size_t GlobalWidth) const {
-  size_t L = std::strlen(ArgStr);
   outs() << "  -" << ArgStr;
-  outs().indent(GlobalWidth-L-6) << " - " << HelpStr << "\n";
+  printHelpStr(HelpStr, GlobalWidth, std::strlen(ArgStr) + 6);
 }
 
 //===----------------------------------------------------------------------===//
@@ -946,7 +955,7 @@
   if (const char *ValName = getValueName())
     outs() << "=<" << getValueStr(O, ValName) << '>';
 
-  outs().indent(GlobalWidth-getOptionWidth(O)) << " - " << O.HelpStr << '\n';
+  printHelpStr(O.HelpStr, GlobalWidth, getOptionWidth(O));
 }
 
 void basic_parser_impl::printOptionName(const Option &O,
@@ -1087,9 +1096,8 @@
 void generic_parser_base::printOptionInfo(const Option &O,
                                           size_t GlobalWidth) const {
   if (O.hasArgStr()) {
-    size_t L = std::strlen(O.ArgStr);
     outs() << "  -" << O.ArgStr;
-    outs().indent(GlobalWidth-L-6) << " - " << O.HelpStr << '\n';
+    printHelpStr(O.HelpStr, GlobalWidth, std::strlen(O.ArgStr) + 6);
 
     for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
       size_t NumSpaces = GlobalWidth-strlen(getOption(i))-8;
@@ -1100,9 +1108,9 @@
     if (O.HelpStr[0])
       outs() << "  " << O.HelpStr << '\n';
     for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
-      size_t L = std::strlen(getOption(i));
-      outs() << "    -" << getOption(i);
-      outs().indent(GlobalWidth-L-8) << " - " << getDescription(i) << '\n';
+      const char *Option = getOption(i);
+      outs() << "    -" << Option;
+      printHelpStr(getDescription(i), GlobalWidth, std::strlen(Option) + 8);
     }
   }
 }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D779.1.patch
Type: text/x-patch
Size: 2776 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130510/bf63ab50/attachment.bin>


More information about the llvm-commits mailing list