[llvm] 77b6ddf - [FileCheck] In input dump, elide only if ellipsis is shorter
Joel E. Denny via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 10 08:04:29 PDT 2020
Author: Joel E. Denny
Date: 2020-07-10T11:02:11-04:00
New Revision: 77b6ddf1bd77da90407316345156415dc646e744
URL: https://github.com/llvm/llvm-project/commit/77b6ddf1bd77da90407316345156415dc646e744
DIFF: https://github.com/llvm/llvm-project/commit/77b6ddf1bd77da90407316345156415dc646e744.diff
LOG: [FileCheck] In input dump, elide only if ellipsis is shorter
For example, given `-dump-input-context=3 -vv`, the following now
shows more leading context for the error than requested because a
leading ellipsis would occupy the same number of lines as it would
elide:
```
<<<<<<
1: foo6
2: foo5
3: foo4
4: foo3
5: foo2
6: foo1
7: hello world
check:1 ^~~~~
check:2 X~~~~ error: no match found
8: foo1
check:2 ~~~~
9: foo2
check:2 ~~~~
10: foo3
check:2 ~~~~
.
.
.
>>>>>>
```
Reviewed By: mehdi_amini
Differential Revision: https://reviews.llvm.org/D83526
Added:
Modified:
llvm/test/FileCheck/dump-input-context.txt
llvm/utils/FileCheck/FileCheck.cpp
Removed:
################################################################################
diff --git a/llvm/test/FileCheck/dump-input-context.txt b/llvm/test/FileCheck/dump-input-context.txt
index 6badaf88778d..2e4382ec12ed 100644
--- a/llvm/test/FileCheck/dump-input-context.txt
+++ b/llvm/test/FileCheck/dump-input-context.txt
@@ -9,9 +9,9 @@
; - M: Between two input lines included by the filter.
; - E: At the end of the input.
;
-; They are all present at -dump-input-context=6. One disappears each time
-; -dump-input-context is incremented beyond that because there are no lines
-; left to elide.
+; They are all present at -dump-input-context=4. One becomes useless each time
+; -dump-input-context is incremented beyond that because then that ellipsis
+; becomes equal to or larger than the input lines it elides.
;--------------------------------------------------
; RUN: echo foo8 > %t.in
@@ -47,6 +47,7 @@
; RUN: echo foo7 >> %t.in
; RUN: echo foo8 >> %t.in
; RUN: echo foo9 >> %t.in
+; RUN: echo foo0 >> %t.in
; RUN: echo 'CHECK-LABEL: lab1' > %t.chk
; RUN: echo ' CHECK-NEXT: hello' >> %t.chk
@@ -57,9 +58,9 @@
; CS-NEXT: .
; CS-NEXT: .
; CS-NEXT: .
-; C8-NEXT: 1: foo8
-; C7-NEXT: 2: foo7
-; C6-NEXT: 3: foo6
+; C5-NEXT: 1: foo8
+; C5-NEXT: 2: foo7
+; C5-NEXT: 3: foo6
; C5-NEXT: 4: foo5
; C4-NEXT: 5: foo4
; C3-NEXT: 6: foo3
@@ -75,11 +76,11 @@
; C4-NEXT: 13: foo4
; C5-NEXT: 14: foo5
; C6-NEXT: 15: foo6
-; C7-NEXT: 16: foo7
+; C6-NEXT: 16: foo7
; CM-NEXT: .
; CM-NEXT: .
; CM-NEXT: .
-; C7-NEXT: 17: foo7
+; C6-NEXT: 17: foo7
; C6-NEXT: 18: foo6
; C5-NEXT: 19: foo5
; C4-NEXT: 20: foo4
@@ -96,13 +97,65 @@
; C5-NEXT: 29: foo5
; C6-NEXT: 30: foo6
; C7-NEXT: 31: foo7
-; C8-NEXT: 32: foo8
-; C9-NEXT: 33: foo9
+; C7-NEXT: 32: foo8
+; C7-NEXT: 33: foo9
+; C7-NEXT: 34: foo0
; CE-NEXT: .
; CE-NEXT: .
; CE-NEXT: .
; C0-NEXT: >>>>>>
+; Now build an alternate set of checks where input lines that might be elided by
+; ellipses have annotations.
+
+; RUN: cp %t.in %t.wide.in
+; RUN: echo 'CHECK-LABEL: lab1' > %t.wide.chk
+; RUN: echo ' CHECK: hello' >> %t.wide.chk
+; RUN: echo ' CHECK: goodbye' >> %t.wide.chk
+; RUN: echo 'CHECK-LABEL: lab2' >> %t.wide.chk
+; RUN: echo ' CHECK-NEXT: world' >> %t.wide.chk
+
+; W5: <<<<<<
+; W5: 9: lab1 hello
+; W5-NEXT: label:1'0 ^~~~
+; W5-NEXT: label:1'1 ^~~~
+; W5-NEXT: check:2 ^~~~~
+; W5-NEXT: 10: foo1
+; W5-NEXT: check:3 X~~~ error: no match found
+; W5-NEXT: 11: foo2
+; W5-NEXT: check:3 ~~~~
+; W5-NEXT: 12: foo3
+; W5-NEXT: check:3 ~~~~
+; W5-NEXT: 13: foo4
+; W5-NEXT: check:3 ~~~~
+; W5-NEXT: 14: foo5
+; W5-NEXT: check:3 ~~~~
+; W5-NEXT: 15: foo6
+; W5-NEXT: check:3 ~~~~
+; W6-NEXT: 16: foo7
+; W6-NEXT: check:3 ~~~~
+; WM-NEXT: .
+; WM-NEXT: .
+; WM-NEXT: .
+; W6-NEXT: 17: foo7
+; W6-NEXT: check:3 ~~~~
+; W6-NEXT: 18: foo6
+; W6-NEXT: check:3 ~~~~
+; W5-NEXT: 19: foo5
+; W5-NEXT: check:3 ~~~~
+; W5-NEXT: 20: foo4
+; W5-NEXT: check:3 ~~~~
+; W5-NEXT: 21: foo3
+; W5-NEXT: check:3 ~~~~
+; W5-NEXT: 22: foo2
+; W5-NEXT: check:3 ~~~~
+; W5-NEXT: 23: foo1
+; W5-NEXT: check:3 ~~~~
+; W5-NEXT: 24: lab2 world
+; W5-NEXT: label:4 ^~~~
+; W5-NEXT: check:3 ~~~~
+; W5-NEXT: next:5 !~~~~ error: match on wrong line
+
;--------------------------------------------------
; Check -dump-input-context=<bad value>.
;--------------------------------------------------
@@ -135,40 +188,35 @@ BADVAL: {{F|f}}ile{{C|c}}heck{{.*}}: for the --dump-input-context option: '[[VAL
; RUN: -dump-input-context=1 \
; RUN: | FileCheck %s -match-full-lines -check-prefixes=C0,C1,CS,CM,CE
-; 6 is the boundary case at which all ellipses are present in our test.
+; 4 is the boundary case at which all ellipses are present in our test.
; RUN: %ProtectFileCheckOutput \
; RUN: not FileCheck -dump-input=fail -vv %t.chk < %t.in 2>&1 \
-; RUN: -dump-input-context=6 \
-; RUN: | FileCheck %s -match-full-lines \
-; RUN: -check-prefixes=C0,C1,C2,C3,C4,C5,C6,CS,CM,CE
+; RUN: -dump-input-context=4 \
+; RUN: | FileCheck %s -match-full-lines -check-prefixes=C0,C1,C2,C3,C4,CS,CM,CE
-; 7 is the boundary case at which the middle ellipsis disappears.
+; 5 is the boundary case at which the start ellipsis is useless.
; RUN: %ProtectFileCheckOutput \
; RUN: not FileCheck -dump-input=fail -vv %t.chk < %t.in 2>&1 \
-; RUN: -dump-input-context=7 \
-; RUN: | FileCheck %s -match-full-lines \
-; RUN: -check-prefixes=C0,C1,C2,C3,C4,C5,C6,C7,CS,CE
+; RUN: -dump-input-context=5 \
+; RUN: | FileCheck %s -match-full-lines -check-prefixes=C0,C1,C2,C3,C4,C5,CM,CE
-; 8 is the boundary case at which the start ellipsis disappears.
+; 6 is the boundary case at which the middle ellipsis is useless.
; RUN: %ProtectFileCheckOutput \
; RUN: not FileCheck -dump-input=fail -vv %t.chk < %t.in 2>&1 \
-; RUN: -dump-input-context=8 \
-; RUN: | FileCheck %s -match-full-lines \
-; RUN: -check-prefixes=C0,C1,C2,C3,C4,C5,C6,C7,C8,CE
+; RUN: -dump-input-context=6 \
+; RUN: | FileCheck %s -match-full-lines -check-prefixes=C0,C1,C2,C3,C4,C5,C6,CE
-; 9 is the boundary case at which the end ellipsis disappears.
+; 7 is the boundary case at which the end ellipsis is useless.
; RUN: %ProtectFileCheckOutput \
; RUN: not FileCheck -dump-input=fail -vv %t.chk < %t.in 2>&1 \
-; RUN: -dump-input-context=9 \
-; RUN: | FileCheck %s -match-full-lines \
-; RUN: -check-prefixes=C0,C1,C2,C3,C4,C5,C6,C7,C8,C9
+; RUN: -dump-input-context=7 \
+; RUN: | FileCheck %s -match-full-lines -check-prefixes=C0,C1,C2,C3,C4,C5,C6,C7
; Make sure all is fine when -dump-input-context is far larger than the input.
; RUN: %ProtectFileCheckOutput \
; RUN: not FileCheck -dump-input=fail -vv %t.chk < %t.in 2>&1 \
; RUN: -dump-input-context=200 \
-; RUN: | FileCheck %s -match-full-lines \
-; RUN: -check-prefixes=C0,C1,C2,C3,C4,C5,C6,C7,C8,C9
+; RUN: | FileCheck %s -match-full-lines -check-prefixes=C0,C1,C2,C3,C4,C5,C6,C7
;--------------------------------------------------
; Check that -dump-input-context default is 5.
@@ -176,8 +224,7 @@ BADVAL: {{F|f}}ile{{C|c}}heck{{.*}}: for the --dump-input-context option: '[[VAL
; RUN: %ProtectFileCheckOutput \
; RUN: not FileCheck -dump-input=fail -vv %t.chk < %t.in 2>&1 \
-; RUN: | FileCheck %s -match-full-lines \
-; RUN: -check-prefixes=C0,C1,C2,C3,C4,C5,CS,CM,CE
+; RUN: | FileCheck %s -match-full-lines -check-prefixes=C0,C1,C2,C3,C4,C5,CM,CE
;--------------------------------------------------
; Check multiple -dump-input-context options.
@@ -225,3 +272,22 @@ BADVAL: {{F|f}}ile{{C|c}}heck{{.*}}: for the --dump-input-context option: '[[VAL
; RUN: not FileCheck -dump-input=fail -vv %t.chk < %t.in 2>&1 \
; RUN: -dump-input-context=0 \
; RUN: | FileCheck %s -match-full-lines -check-prefixes=C0,C1,CS,CM,CE
+
+;--------------------------------------------------
+; Check how annotations on input lines that might be elided by ellipses affect
+; whether they are actually elided.
+;--------------------------------------------------
+
+; At -dump-input-context=5, the ellipsis is useful but only when annotations on
+; elided input lines are considered.
+; RUN: %ProtectFileCheckOutput \
+; RUN: not FileCheck -dump-input=fail -vv %t.wide.chk < %t.wide.in 2>&1 \
+; RUN: -dump-input-context=5 \
+; RUN: | FileCheck %s -match-full-lines -check-prefixes=W5,WM
+
+; At -dump-input-context=6, the ellipsis is not useful even when annotations on
+; elided input lines are considered.
+; RUN: %ProtectFileCheckOutput \
+; RUN: not FileCheck -dump-input=fail -vv %t.wide.chk < %t.wide.in 2>&1 \
+; RUN: -dump-input-context=6 \
+; RUN: | FileCheck %s -match-full-lines -check-prefixes=W5,W6
diff --git a/llvm/utils/FileCheck/FileCheck.cpp b/llvm/utils/FileCheck/FileCheck.cpp
index 0952d4bd24d0..ec2556074aee 100644
--- a/llvm/utils/FileCheck/FileCheck.cpp
+++ b/llvm/utils/FileCheck/FileCheck.cpp
@@ -429,6 +429,25 @@ static unsigned FindInputLineInFilter(
return UINT_MAX;
}
+/// To OS, print a vertical ellipsis (right-justified at LabelWidth) if it would
+/// occupy less lines than ElidedLines, but print ElidedLines otherwise. Either
+/// way, clear ElidedLines. Thus, if ElidedLines is empty, do nothing.
+static void DumpEllipsisOrElidedLines(raw_ostream &OS, std::string &ElidedLines,
+ unsigned LabelWidth) {
+ if (ElidedLines.empty())
+ return;
+ unsigned EllipsisLines = 3;
+ if (EllipsisLines < StringRef(ElidedLines).count('\n')) {
+ for (unsigned i = 0; i < EllipsisLines; ++i) {
+ WithColor(OS, raw_ostream::BLACK, /*Bold=*/true)
+ << right_justify(".", LabelWidth);
+ OS << '\n';
+ }
+ } else
+ OS << ElidedLines;
+ ElidedLines.clear();
+}
+
static void DumpAnnotatedInput(raw_ostream &OS, const FileCheckRequest &Req,
bool DumpInputFilterOnError,
unsigned DumpInputContext,
@@ -507,7 +526,12 @@ static void DumpAnnotatedInput(raw_ostream &OS, const FileCheckRequest &Req,
// Print annotated input lines.
unsigned PrevLineInFilter = 0; // 0 means none so far
unsigned NextLineInFilter = 0; // 0 means uncomputed, UINT_MAX means none
- bool PrevLineElided = false;
+ std::string ElidedLines;
+ raw_string_ostream ElidedLinesOS(ElidedLines);
+ ColorMode TheColorMode =
+ WithColor(OS).colorsEnabled() ? ColorMode::Enable : ColorMode::Disable;
+ if (TheColorMode == ColorMode::Enable)
+ ElidedLinesOS.enable_colors(true);
auto AnnotationItr = Annotations.begin(), AnnotationEnd = Annotations.end();
for (unsigned Line = 1;
InputFilePtr != InputFileEnd || AnnotationItr != AnnotationEnd;
@@ -524,37 +548,29 @@ static void DumpAnnotatedInput(raw_ostream &OS, const FileCheckRequest &Req,
// Elide this input line and its annotations if it's not within the
// context specified by -dump-input-context of an input line included by
- // the dump filter.
+ // the dump filter. However, in case the resulting ellipsis would occupy
+ // more lines than the input lines and annotations it elides, buffer the
+ // elided lines and annotations so we can print them instead.
+ raw_ostream *LineOS = &OS;
if ((!PrevLineInFilter || PrevLineInFilter + DumpInputContext < Line) &&
(NextLineInFilter == UINT_MAX ||
- Line + DumpInputContext < NextLineInFilter)) {
- while (InputFilePtr != InputFileEnd && *InputFilePtr != '\n')
- ++InputFilePtr;
- if (InputFilePtr != InputFileEnd)
- ++InputFilePtr;
- while (AnnotationItr != AnnotationEnd && AnnotationItr->InputLine == Line)
- ++AnnotationItr;
- if (!PrevLineElided) {
- for (unsigned i = 0; i < 3; ++i) {
- WithColor(OS, raw_ostream::BLACK, /*Bold=*/true)
- << right_justify(".", LabelWidth);
- OS << '\n';
- }
- PrevLineElided = true;
- }
- continue;
+ Line + DumpInputContext < NextLineInFilter))
+ LineOS = &ElidedLinesOS;
+ else {
+ LineOS = &OS;
+ DumpEllipsisOrElidedLines(OS, ElidedLinesOS.str(), LabelWidth);
}
- PrevLineElided = false;
// Print right-aligned line number.
- WithColor(OS, raw_ostream::BLACK, true)
+ WithColor(*LineOS, raw_ostream::BLACK, /*Bold=*/true, /*BF=*/false,
+ TheColorMode)
<< format_decimal(Line, LabelWidth) << ": ";
// For the case where -v and colors are enabled, find the annotations for
// good matches for expected patterns in order to highlight everything
// else in the line. There are no such annotations if -v is disabled.
std::vector<InputAnnotation> FoundAndExpectedMatches;
- if (Req.Verbose && WithColor(OS).colorsEnabled()) {
+ if (Req.Verbose && TheColorMode == ColorMode::Enable) {
for (auto I = AnnotationItr; I != AnnotationEnd && I->InputLine == Line;
++I) {
if (I->FoundAndExpectedMatch)
@@ -566,7 +582,8 @@ static void DumpAnnotatedInput(raw_ostream &OS, const FileCheckRequest &Req,
// expected patterns.
bool Newline = false;
{
- WithColor COS(OS);
+ WithColor COS(*LineOS, raw_ostream::SAVEDCOLOR, /*Bold=*/false,
+ /*BG=*/false, TheColorMode);
bool InMatch = false;
if (Req.Verbose)
COS.changeColor(raw_ostream::CYAN, true, true);
@@ -590,13 +607,14 @@ static void DumpAnnotatedInput(raw_ostream &OS, const FileCheckRequest &Req,
++InputFilePtr;
}
}
- OS << '\n';
+ *LineOS << '\n';
unsigned InputLineWidth = InputFilePtr - InputFileLine - Newline;
// Print any annotations.
while (AnnotationItr != AnnotationEnd &&
AnnotationItr->InputLine == Line) {
- WithColor COS(OS, AnnotationItr->Marker.Color, true);
+ WithColor COS(*LineOS, AnnotationItr->Marker.Color, /*Bold=*/true,
+ /*BG=*/false, TheColorMode);
// The two spaces below are where the ": " appears on input lines.
COS << left_justify(AnnotationItr->Label, LabelWidth) << " ";
unsigned Col;
@@ -621,6 +639,7 @@ static void DumpAnnotatedInput(raw_ostream &OS, const FileCheckRequest &Req,
++AnnotationItr;
}
}
+ DumpEllipsisOrElidedLines(OS, ElidedLinesOS.str(), LabelWidth);
OS << ">>>>>>\n";
}
More information about the llvm-commits
mailing list