1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[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
This commit is contained in:
Joel E. Denny 2020-07-10 07:50:31 -04:00
parent 82eeb7f9a7
commit ec018a8846
2 changed files with 143 additions and 58 deletions

View File

@ -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=4 \
; RUN: | FileCheck %s -match-full-lines -check-prefixes=C0,C1,C2,C3,C4,CS,CM,CE
; 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=5 \
; RUN: | FileCheck %s -match-full-lines -check-prefixes=C0,C1,C2,C3,C4,C5,CM,CE
; 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=6 \
; RUN: | FileCheck %s -match-full-lines \
; RUN: -check-prefixes=C0,C1,C2,C3,C4,C5,C6,CS,CM,CE
; RUN: | FileCheck %s -match-full-lines -check-prefixes=C0,C1,C2,C3,C4,C5,C6,CE
; 7 is the boundary case at which the middle 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=7 \
; RUN: | FileCheck %s -match-full-lines \
; RUN: -check-prefixes=C0,C1,C2,C3,C4,C5,C6,C7,CS,CE
; 8 is the boundary case at which the start ellipsis disappears.
; 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
; 9 is the boundary case at which the end ellipsis disappears.
; 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: | 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

View File

@ -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";
}