lldb-test: Improve newline handling
authorPavel Labath <pavel@labath.sk>
Sat, 15 Dec 2018 13:49:25 +0000 (13:49 +0000)
committerPavel Labath <pavel@labath.sk>
Sat, 15 Dec 2018 13:49:25 +0000 (13:49 +0000)
Summary:
Previously lldb-test's LinePrinter would output the indentation spaces
even on completely empty lines. This is not nice, as trailing spaces get
flagged as errors in some tools/editors, and it prevents FileCheck's
CHECK-EMPTY from working.

Equally annoying was the fact that the LinePrinter did not terminate
it's output with a newline (instead it would leave the unterminated hanging
indent from the last NewLine() command), which meant that the shell prompt
following the lldb-test command came out wrong.

This fixes both issues by changing how newlines are handled. NewLine(),
which was ending the previous line ('\n') *and* begging the next line by
printing the indent, is now "demoted" to just printing literal "\n".
Instead, lines are now delimited via a helper Line object, which makes
sure the line is indented and terminated in an RAII fashion. The typical
usage would be:
Printer.line() << "This text will be indented and terminated";
If one needs to do more work than it will fit into a single statement,
one can also assign the result of the line() function to a local
variable. The line will then be terminated when that object goes out of
scope.

Reviewers: zturner

Subscribers: lldb-commits

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

llvm-svn: 349269

lldb/lit/Modules/MachO/subsections.yaml
lldb/tools/lldb-test/FormatUtil.cpp
lldb/tools/lldb-test/FormatUtil.h

index b6455b0..7509b78 100644 (file)
@@ -11,8 +11,8 @@
 #CHECK-NEXT:  VM size: 4294967296
 #CHECK-NEXT:  File size: 0
 #CHECK-NEXT:  There are no subsections
 #CHECK-NEXT:  VM size: 4294967296
 #CHECK-NEXT:  File size: 0
 #CHECK-NEXT:  There are no subsections
-#
-#CHECK:       Index: 1
+#CHECK-EMPTY:
+#CHECK-NEXT:  Index: 1
 #CHECK-NEXT:  Name: __TEXT
 #CHECK-NEXT:  Type: container
 #CHECK-NEXT:  Permissions: r-x
 #CHECK-NEXT:  Name: __TEXT
 #CHECK-NEXT:  Type: container
 #CHECK-NEXT:  Permissions: r-x
@@ -29,8 +29,8 @@
 #CHECK-NEXT:    VM address: 0x100000f30
 #CHECK-NEXT:    VM size: 22
 #CHECK-NEXT:    File size: 22
 #CHECK-NEXT:    VM address: 0x100000f30
 #CHECK-NEXT:    VM size: 22
 #CHECK-NEXT:    File size: 22
-#
-#CHECK:         Index: 1
+#CHECK-EMPTY:
+#CHECK-NEXT:    Index: 1
 #CHECK-NEXT:    Name: __unwind_info
 #CHECK-NEXT:    Type: compact-unwind
 #CHECK-NEXT:    Permissions: r-x
 #CHECK-NEXT:    Name: __unwind_info
 #CHECK-NEXT:    Type: compact-unwind
 #CHECK-NEXT:    Permissions: r-x
@@ -38,8 +38,8 @@
 #CHECK-NEXT:    VM address: 0x100000f48
 #CHECK-NEXT:    VM size: 76
 #CHECK-NEXT:    File size: 76
 #CHECK-NEXT:    VM address: 0x100000f48
 #CHECK-NEXT:    VM size: 76
 #CHECK-NEXT:    File size: 76
-#
-#CHECK:         Index: 2
+#CHECK-EMPTY:
+#CHECK-NEXT:    Index: 2
 #CHECK-NEXT:    Name: __eh_frame
 #CHECK-NEXT:    Type: eh-frame
 #CHECK-NEXT:    Permissions: r-x
 #CHECK-NEXT:    Name: __eh_frame
 #CHECK-NEXT:    Type: eh-frame
 #CHECK-NEXT:    Permissions: r-x
index 381cbd6..970f25a 100644 (file)
 using namespace lldb_private;
 using namespace llvm;
 
 using namespace lldb_private;
 using namespace llvm;
 
+LinePrinter::Line::~Line() {
+  if (P)
+    P->NewLine();
+}
+
 LinePrinter::LinePrinter(int Indent, llvm::raw_ostream &Stream)
     : OS(Stream), IndentSpaces(Indent), CurrentIndent(0) {}
 
 LinePrinter::LinePrinter(int Indent, llvm::raw_ostream &Stream)
     : OS(Stream), IndentSpaces(Indent), CurrentIndent(0) {}
 
@@ -31,39 +36,31 @@ void LinePrinter::Unindent(uint32_t Amount) {
 
 void LinePrinter::NewLine() {
   OS << "\n";
 
 void LinePrinter::NewLine() {
   OS << "\n";
-  OS.indent(CurrentIndent);
-}
-
-void LinePrinter::print(const Twine &T) { OS << T; }
-
-void LinePrinter::printLine(const Twine &T) {
-  NewLine();
-  OS << T;
 }
 
 void LinePrinter::formatBinary(StringRef Label, ArrayRef<uint8_t> Data,
                                uint32_t StartOffset) {
 }
 
 void LinePrinter::formatBinary(StringRef Label, ArrayRef<uint8_t> Data,
                                uint32_t StartOffset) {
-  NewLine();
-  OS << Label << " (";
-  if (!Data.empty()) {
-    OS << "\n";
-    OS << format_bytes_with_ascii(Data, StartOffset, 32, 4,
-                                  CurrentIndent + IndentSpaces, true);
-    NewLine();
+  if (Data.empty()) {
+    line() << Label << " ()";
+    return;
   }
   }
-  OS << ")";
+  line() << Label << " (";
+  OS << format_bytes_with_ascii(Data, StartOffset, 32, 4,
+                                CurrentIndent + IndentSpaces, true);
+  NewLine();
+  line() << ")";
 }
 
 void LinePrinter::formatBinary(StringRef Label, ArrayRef<uint8_t> Data,
                                uint64_t Base, uint32_t StartOffset) {
 }
 
 void LinePrinter::formatBinary(StringRef Label, ArrayRef<uint8_t> Data,
                                uint64_t Base, uint32_t StartOffset) {
-  NewLine();
-  OS << Label << " (";
-  if (!Data.empty()) {
-    OS << "\n";
-    Base += StartOffset;
-    OS << format_bytes_with_ascii(Data, Base, 32, 4,
-                                  CurrentIndent + IndentSpaces, true);
-    NewLine();
+  if (Data.empty()) {
+    line() << Label << " ()";
+    return;
   }
   }
-  OS << ")";
+  line() << Label << " (";
+  Base += StartOffset;
+  OS << format_bytes_with_ascii(Data, Base, 32, 4, CurrentIndent + IndentSpaces,
+                                true);
+  NewLine();
+  line() << ")";
 }
 }
index f22ee41..598d4c5 100644 (file)
@@ -26,27 +26,36 @@ class LinePrinter {
   int CurrentIndent;
 
 public:
   int CurrentIndent;
 
 public:
+  class Line {
+    LinePrinter *P;
+
+  public:
+    Line(LinePrinter &P) : P(&P) { P.OS.indent(P.CurrentIndent); }
+    ~Line();
+
+    Line(Line &&RHS) : P(RHS.P) { RHS.P = nullptr; }
+    void operator=(Line &&) = delete;
+
+    operator llvm::raw_ostream &() { return P->OS; }
+  };
+
   LinePrinter(int Indent, llvm::raw_ostream &Stream);
 
   void Indent(uint32_t Amount = 0);
   void Unindent(uint32_t Amount = 0);
   void NewLine();
 
   LinePrinter(int Indent, llvm::raw_ostream &Stream);
 
   void Indent(uint32_t Amount = 0);
   void Unindent(uint32_t Amount = 0);
   void NewLine();
 
-  void printLine(const llvm::Twine &T);
-  void print(const llvm::Twine &T);
+  void printLine(const llvm::Twine &T) { line() << T; }
   template <typename... Ts> void formatLine(const char *Fmt, Ts &&... Items) {
     printLine(llvm::formatv(Fmt, std::forward<Ts>(Items)...));
   }
   template <typename... Ts> void formatLine(const char *Fmt, Ts &&... Items) {
     printLine(llvm::formatv(Fmt, std::forward<Ts>(Items)...));
   }
-  template <typename... Ts> void format(const char *Fmt, Ts &&... Items) {
-    print(llvm::formatv(Fmt, std::forward<Ts>(Items)...));
-  }
 
   void formatBinary(llvm::StringRef Label, llvm::ArrayRef<uint8_t> Data,
                     uint32_t StartOffset);
   void formatBinary(llvm::StringRef Label, llvm::ArrayRef<uint8_t> Data,
                     uint64_t BaseAddr, uint32_t StartOffset);
 
 
   void formatBinary(llvm::StringRef Label, llvm::ArrayRef<uint8_t> Data,
                     uint32_t StartOffset);
   void formatBinary(llvm::StringRef Label, llvm::ArrayRef<uint8_t> Data,
                     uint64_t BaseAddr, uint32_t StartOffset);
 
-  llvm::raw_ostream &getStream() { return OS; }
+  Line line() { return Line(*this); }
   int getIndentLevel() const { return CurrentIndent; }
 };
 
   int getIndentLevel() const { return CurrentIndent; }
 };
 
@@ -64,12 +73,6 @@ struct AutoIndent {
   uint32_t Amount = 0;
 };
 
   uint32_t Amount = 0;
 };
 
-template <class T>
-inline llvm::raw_ostream &operator<<(LinePrinter &Printer, const T &Item) {
-  Printer.getStream() << Item;
-  return Printer.getStream();
-}
-
 } // namespace lldb_private
 
 #endif
 } // namespace lldb_private
 
 #endif