; Throughout this file, where %{pre}=FOO, FileCheck prefixes are as follows to
; indicate the level of FileCheck verbosity under test:
; - FOO    = quiet, -v, or -vv
; - FOO-V  = -v or -vv (-vv implies -v)
; - FOO-VV = -vv
; - FOO-Q  = quiet only
; - FOO-VQ = -v only
;
; Most cases use just FOO, FOO-V, and FOO-VV in a unified block of directives
; that checks an input dump where some annotations are omitted at lower
; verbosity levels.
;
; For a few cases, multiple annotations persist but *change* across verbosity
; levels, usually due to modified annotation labels.  Seeing multiple versions
; of the same annotation in the same block of directives can be confusing.  To
; improve readability, it is usually best to split these into separate blocks.
; For example, use FOO-Q to check only the version without -v or -vv.

; DEFINE: %{pre} =
; DEFINE: %{opts} =
;
; DEFINE: %{run-fc} = \
; DEFINE:   %ProtectFileCheckOutput \
; DEFINE:   FileCheck -dump-input=always -input-file=%t.in %t.chk \
; DEFINE:       -dump-input-label-width=15 %{opts}
;
; DEFINE: %{check-fc} = \
; DEFINE:   FileCheck -strict-whitespace -match-full-lines %s \
; DEFINE:       -allow-unused-prefixes \
; DEFINE:       -implicit-check-not='remark:' -implicit-check-not='error:'
;
; For each case, it is usually best to run these in order of decreasing
; verbosity to maximize the information for debugging when the case is broken.
;
; DEFINE: %{run-vv} = %{run-fc} -vv 2>&1 | \
; DEFINE:     %{check-fc} -check-prefixes=%{pre},%{pre}-V,%{pre}-VV
; DEFINE: %{run-v} = %{run-fc} -v 2>&1 | \
; DEFINE:     %{check-fc} -check-prefixes=%{pre},%{pre}-V,%{pre}-VQ
; DEFINE: %{run} = %{run-fc} 2>&1 | \
; DEFINE:     %{check-fc} -check-prefixes=%{pre},%{pre}-Q

;--------------------------------------------------
; Label column width
;
; Check that the label column width is sane when we do not force a minimum.  The
; rest of the test file is easier to maintain if we otherwise always force it
; because that avoids the possibility of it fluctuating across different
; verbosity levels.
;--------------------------------------------------

; Check with both the annotation label and the line number fairly short.
;
; RUN: echo 'hello world' > %t.in
; RUN: echo 'CHECK: hello world' > %t.chk
;
; REDEFINE: %{opts} = -dump-input-label-width=0
; REDEFINE: %{pre} = WIDTH-SHORT
; RUN: %{run-v}
;
;      WIDTH-SHORT:<<<<<<
; WIDTH-SHORT-NEXT:         1: hello world 
; WIDTH-SHORT-NEXT:check:1     ^~~~~~~~~~~
; WIDTH-SHORT-NEXT:>>>>>>
;  WIDTH-SHORT-NOT:{{.}}

; Check that lengthening the annotation label widens the column.
;
; RUN: echo 'hello world' > %t.in
; RUN: echo 'hello world' >> %t.in
; RUN: echo 'CHECK-COUNT-2: hello world' > %t.chk
;
; REDEFINE: %{opts} = -dump-input-label-width=0
; REDEFINE: %{pre} = WIDTH-ANNOT
; RUN: %{run-v}
;
;      WIDTH-ANNOT:<<<<<<
; WIDTH-ANNOT-NEXT:           1: hello world 
; WIDTH-ANNOT-NEXT:count:1'0     ^~~~~~~~~~~
; WIDTH-ANNOT-NEXT:           2: hello world 
; WIDTH-ANNOT-NEXT:count:1'1     ^~~~~~~~~~~
; WIDTH-ANNOT-NEXT:>>>>>>
;  WIDTH-ANNOT-NOT:{{.}}

; Check that a longer line number (6 characters) than annotation label (5
; characters) widens the column.
;
; RUN: %python -c 'print("x\n" * 10**5, end="")' > %t.in
; RUN: echo 'the end' >> %t.in
; RUN: echo 'CHECK-DAG: the end' > %t.chk
;
; REDEFINE: %{opts} = -dump-input-label-width=0 -dump-input-filter=annotation \
; REDEFINE:           -dump-input-context=3
; REDEFINE: %{pre} = WIDTH-LINENO
; RUN: %{run-v}
;
;      WIDTH-LINENO:<<<<<<
; WIDTH-LINENO-NEXT:        .
; WIDTH-LINENO-NEXT:        .
; WIDTH-LINENO-NEXT:        .
; WIDTH-LINENO-NEXT:    99998: x 
; WIDTH-LINENO-NEXT:    99999: x 
; WIDTH-LINENO-NEXT:   100000: x 
; WIDTH-LINENO-NEXT:   100001: the end 
; WIDTH-LINENO-NEXT:dag:1      ^~~~~~~
; WIDTH-LINENO-NEXT:>>>>>>
;  WIDTH-LINENO-NOT:{{.}}

; REDEFINE: %{opts} =

;--------------------------------------------------
; CHECK (also: multi-line search range, fuzzy match)
;--------------------------------------------------

; Good match and no match.

; RUN: echo 'hello'   > %t.in
; RUN: echo 'again'   >> %t.in
; RUN: echo 'whirled' >> %t.in

; RUN: echo 'CHECK: hello' > %t.chk
; RUN: echo 'CHECK: world' >> %t.chk

; REDEFINE: %{pre} = CHK
; RUN: not %{run-vv}
; RUN: not %{run-v}
; RUN: not %{run}

; Verbose diagnostics are suppressed but not errors.
; CHK:{{.*}}error:{{.*}}
; CHK:{{.*}}possible intended match here{{.*}}

;        CHK:<<<<<<
;   CHK-NEXT:              1: hello 
; CHK-V-NEXT:check:1          ^~~~~
;   CHK-NEXT:check:2'0            {   search range start (exclusive)
;   CHK-NEXT:check:2'1                error: no match found in search range
;   CHK-NEXT:              2: again 
;   CHK-NEXT:              3: whirled 
;   CHK-NEXT:check:2'2        ?         possible intended match
;   CHK-NEXT:check:2'3                } search range end (exclusive)
;   CHK-NEXT:>>>>>>
;    CHK-NOT:{{.}}

;--------------------------------------------------
; CHECK-COUNT-<num>
;--------------------------------------------------

; Good match and no match.

; RUN: echo 'pete'   > %t.in
; RUN: echo 'repete' >> %t.in
; RUN: echo 'repeat' >> %t.in

; RUN: echo 'CHECK-COUNT-3: pete' > %t.chk

; REDEFINE: %{pre} = CNT
; RUN: not %{run-vv}
; RUN: not %{run-v}
; RUN: not %{run}

; Verbose diagnostics are suppressed but not errors.
; CNT:{{.*}}error:{{.*}}

;      CNT-V:<<<<<<
; CNT-V-NEXT:              1: pete 
; CNT-V-NEXT:count:1'0        ^~~~
; CNT-V-NEXT:              2: repete 
; CNT-V-NEXT:count:1'1          ^~~~
; CNT-V-NEXT:count:1'2             {   search range start (exclusive)
; CNT-V-NEXT:count:1'3                 error: no match found in search range
; CNT-V-NEXT:              3: repeat 
; CNT-V-NEXT:count:1'4        ?        possible intended match
; CNT-V-NEXT:count:1'5               } search range end (exclusive)
; CNT-V-NEXT:>>>>>>
;  CNT-V-NOT:{{.}}

;      CNT-Q:<<<<<<
; CNT-Q-NEXT:              1: pete 
; CNT-Q-NEXT:              2: repete 
; CNT-Q-NEXT:count:1'0             {   search range start (exclusive)
; CNT-Q-NEXT:count:1'1                 error: no match found in search range
; CNT-Q-NEXT:              3: repeat 
; CNT-Q-NEXT:count:1'2        ?        possible intended match
; CNT-Q-NEXT:count:1'3               } search range end (exclusive)
; CNT-Q-NEXT:>>>>>>
;  CNT-Q-NOT:{{.}}

;--------------------------------------------------
; CHECK-NEXT (also: EOF search-range, single-char search range, wrong-line match)
;--------------------------------------------------

; Good match and no match.

; RUN: echo 'hello' > %t.in
; RUN: echo 'again' >> %t.in

; RUN: echo 'CHECK: hello' > %t.chk
; RUN: echo 'CHECK-NEXT: again' >> %t.chk
; RUN: echo 'CHECK-NEXT: world' >> %t.chk

; REDEFINE: %{pre} = NXT
; RUN: not %{run-vv}
; RUN: not %{run-v}
; RUN: not %{run}

; Verbose diagnostics are suppressed but not errors.
; NXT:{{.*}}error:{{.*}}

;        NXT:<<<<<<
;   NXT-NEXT:              1: hello 
; NXT-V-NEXT:check:1          ^~~~~
;   NXT-NEXT:              2: again 
; NXT-V-NEXT:next:2           ^~~~~
;   NXT-NEXT:next:3'0             { } search range (exclusive bounds)
;   NXT-NEXT:next:3'1                 error: no match found in search range
;   NXT-NEXT:>>>>>>
;    NXT-NOT:{{.}}

; Wrong-line match.

; RUN: echo 'yonder' >> %t.in
; RUN: echo 'world' >> %t.in

; REDEFINE: %{pre} = NXT2
; RUN: not %{run-vv}
; RUN: not %{run-v}
; RUN: not %{run}

; Verbose diagnostics are suppressed but not errors.
; NXT2:{{.*}}error:{{.*}}

;        NXT2:<<<<<<
;   NXT2-NEXT:              1: hello 
; NXT2-V-NEXT:check:1          ^~~~~
;   NXT2-NEXT:              2: again 
; NXT2-V-NEXT:next:2           ^~~~~
;   NXT2-NEXT:next:3'0             {   search range start (exclusive)
;   NXT2-NEXT:              3: yonder 
;   NXT2-NEXT:              4: world 
;   NXT2-NEXT:next:3'1         !~~~~   error: match on wrong line
;   NXT2-NEXT:next:3'2               } search range end (exclusive)
;   NXT2-NEXT:>>>>>>
;    NXT2-NOT:{{.}}

;--------------------------------------------------
; CHECK-SAME (also: multiple annotations per line, wrong-line match)
;--------------------------------------------------

; Good match and no match.

; RUN: echo 'hello world!' > %t.in

; RUN: echo 'CHECK: hello' > %t.chk
; RUN: echo 'CHECK-SAME: world' >> %t.chk
; RUN: echo 'CHECK-SAME: again' >> %t.chk

; REDEFINE: %{pre} = SAM
; RUN: not %{run-vv}
; RUN: not %{run-v}
; RUN: not %{run}

; Verbose diagnostics are suppressed but not errors.
; SAM:{{.*}}error:{{.*}}

;        SAM:<<<<<<
;   SAM-NEXT:              1: hello world! 
; SAM-V-NEXT:check:1          ^~~~~
; SAM-V-NEXT:same:2                 ^~~~~
;   SAM-NEXT:same:3'0                   {  } search range (exclusive bounds)
;   SAM-NEXT:same:3'1                        error: no match found in search range
;   SAM-NEXT:>>>>>>
;    SAM-NOT:{{.}}

; Wrong-line match.

; RUN: echo 'again' >> %t.in

; REDEFINE: %{pre} = SAM2
; RUN: not %{run-vv}
; RUN: not %{run-v}
; RUN: not %{run}

; Verbose diagnostics are suppressed but not errors.
; SAM2:{{.*}}error:{{.*}}

;        SAM2:<<<<<<
;   SAM2-NEXT:              1: hello world! 
; SAM2-V-NEXT:check:1          ^~~~~
; SAM2-V-NEXT:same:2                 ^~~~~
;   SAM2-NEXT:same:3'0                   {    search range start (exclusive)
;   SAM2-NEXT:              2: again 
;   SAM2-NEXT:same:3'1         !~~~~   error: match on wrong line
;   SAM2-NEXT:same:3'2               } search range end (exclusive)
;   SAM2-NEXT:>>>>>>
;    SAM2-NOT:{{.}}

;--------------------------------------------------
; CHECK-EMPTY (also: search range ends at label, empty match range, wrong-line
; match)
;--------------------------------------------------

; Good match and no match.
;
; CHECK-EMPTY always seems to match an empty line at EOF (illegally when it's
; not the next line) unless either (1) the last line is non-empty and has no
; newline or (2) there's a CHECK-LABEL to end the search range before EOF.  We
; choose scenario 2 to check the case of no match.

; RUN: echo 'hello' > %t.in
; RUN: echo '' >> %t.in
; RUN: echo 'world' >> %t.in
; RUN: echo 'label' >> %t.in

; RUN: echo 'CHECK: hello' > %t.chk
; RUN: echo 'CHECK-EMPTY:' >> %t.chk
; RUN: echo 'CHECK-EMPTY:' >> %t.chk
; RUN: echo 'CHECK-LABEL: label' >> %t.chk

; REDEFINE: %{pre} = EMP
; RUN: not %{run-vv}
; RUN: not %{run-v}
; RUN: not %{run}

; Verbose diagnostics are suppressed but not errors.
; EMP:{{.*}}error:{{.*}}

;        EMP:<<<<<<
;   EMP-NEXT:              1: hello 
; EMP-V-NEXT:check:1          ^~~~~
;   EMP-NEXT:              2:  
; EMP-V-NEXT:empty:2          ^
;   EMP-NEXT:empty:3'0       {   search range start (exclusive)
;   EMP-NEXT:empty:3'1           error: no match found in search range
;   EMP-NEXT:              3: world 
;   EMP-NEXT:              4: label 
; EMP-V-NEXT:label:4          ^~~~~
;   EMP-NEXT:empty:3'2             }  search range end (exclusive)
;   EMP-NEXT:>>>>>>
;    EMP-NOT:{{.}}

; Wrong-line match.

; RUN: echo 'hello' > %t.in
; RUN: echo 'world' >> %t.in

; RUN: echo 'CHECK: hello' > %t.chk
; RUN: echo 'CHECK-EMPTY:' >> %t.chk

; REDEFINE: %{pre} = EMP2
; RUN: not %{run-vv}
; RUN: not %{run-v}
; RUN: not %{run}

; Verbose diagnostics are suppressed but not errors.
; EMP2:{{.*}}error:{{.*}}

; TODO: The search range of CHECK-EMPTY logically ends at the last character of
; the file, as show below.  However, it can actually match the empty string
; immediately after its search range, as shown below.  That is, -dump-input
; seems to be doing the right thing: it makes no sense to show the search range
; including a non-existent character.  If it's worth the effort to change
; anything here, then CHECK-EMPTY should probably report any match past the end
; of the file as a failure to match at all.  That would also include cases that
; are currently successful matches, but that's a strange enough case that it
; probably wouldn't be backward-incompatible for real test suites.

;        EMP2:<<<<<<
;   EMP2-NEXT:              1: hello 
; EMP2-V-NEXT:check:1          ^~~~~
;   EMP2-NEXT:empty:2'0            {   search range start (exclusive)
;   EMP2-NEXT:              2: world 
;   EMP2-NEXT:empty:2'2              } search range end (exclusive)
;   EMP2-NEXT:              3: 
;   EMP2-NEXT:empty:2'1        ! error: match on wrong line
;   EMP2-NEXT:>>>>>>
;    EMP2-NOT:{{.}}

;--------------------------------------------------
; CHECK-NOT (also: EOF pattern, and multiline range that ends before EOL)
;--------------------------------------------------

; No match (success) and unexpected match (error).

; RUN: echo 'hello' > %t.in
; RUN: echo 'world' >> %t.in
; RUN: echo 'again' >> %t.in

; RUN: echo 'CHECK-NOT: goodbye' > %t.chk
; RUN: echo 'CHECK-NOT: world' >> %t.chk

; REDEFINE: %{pre} = NOT
; RUN: not %{run-vv}
; RUN: not %{run-v}
; RUN: not %{run}

; Verbose diagnostics are suppressed but not errors.
; NOT:{{.*}}error:{{.*}}

;         NOT:<<<<<<
;    NOT-NEXT:              1: hello 
; NOT-VV-NEXT:not:1'0         {        search range start (exclusive)
;    NOT-NEXT:not:2'0         {        search range start (exclusive)
;    NOT-NEXT:              2: world 
;    NOT-NEXT:not:2'1          !~~~~   error: no match expected
;    NOT-NEXT:              3: again 
; NOT-VV-NEXT:not:1'1                } search range end (exclusive)
;    NOT-NEXT:not:2'2                } search range end (exclusive)
; NOT-VV-NEXT:              4: 
; NOT-VV-NEXT:eof:2            ^
;    NOT-NEXT:>>>>>>
;     NOT-NOT:{{.}}

; Again, but with a CHECK instead of EOF as search range end.

; RUN: echo 'CHECK: ain' >> %t.chk

; REDEFINE: %{pre} = NOT2
; RUN: not %{run-vv}
; RUN: not %{run-v}
; RUN: not %{run}

; Verbose diagnostics are suppressed but not errors.
; NOT2:{{.*}}error:{{.*}}

;         NOT2:<<<<<<
;    NOT2-NEXT:              1: hello 
; NOT2-VV-NEXT:not:1'0         {        search range start (exclusive)
;    NOT2-NEXT:not:2'0         {        search range start (exclusive)
;    NOT2-NEXT:              2: world 
;    NOT2-NEXT:not:2'1          !~~~~   error: no match expected
;    NOT2-NEXT:              3: again 
;  NOT2-V-NEXT:check:3            ^~~
; NOT2-VV-NEXT:not:1'1            }     search range end (exclusive)
;    NOT2-NEXT:not:2'2            }     search range end (exclusive)
;    NOT2-NEXT:>>>>>>
;     NOT2-NOT:{{.}}

;--------------------------------------------------
; CHECK-DAG (also: matches in different order than directives, discarded match)
;--------------------------------------------------

; Good match, discarded match plus good match, and no match.

; RUN: echo 'abc' > %t.in
; RUN: echo 'def' >> %t.in
; RUN: echo 'abc' >> %t.in

; RUN: echo 'CHECK-DAG: def' > %t.chk
; RUN: echo 'CHECK-DAG: abc' >> %t.chk
; RUN: echo 'CHECK-DAG: abc' >> %t.chk
; RUN: echo 'CHECK-DAG: def' >> %t.chk

; REDEFINE: %{pre} = DAG
; RUN: not %{run-vv}
; RUN: not %{run-v}
; RUN: not %{run}

; Verbose diagnostics are suppressed but not errors.
; DAG:{{.*}}error:{{.*}}

;      DAG-VV:<<<<<<
; DAG-VV-NEXT:              1: abc 
; DAG-VV-NEXT:dag:2            ^~~
; DAG-VV-NEXT:dag:3'0          !~~   discard: overlaps earlier match
; DAG-VV-NEXT:              2: def 
; DAG-VV-NEXT:dag:1            ^~~
; DAG-VV-NEXT:dag:4'0          !~~   discard: overlaps earlier match
; DAG-VV-NEXT:dag:4'1            {   search range start (exclusive)
; DAG-VV-NEXT:dag:4'2                error: no match found in search range
; DAG-VV-NEXT:              3: abc 
; DAG-VV-NEXT:dag:3'1          ^~~
; DAG-VV-NEXT:dag:4'3              } search range end (exclusive)
; DAG-VV-NEXT:>>>>>>
;  DAG-VV-NOT:{{.}}

;      DAG-VQ:<<<<<<
; DAG-VQ-NEXT:              1: abc 
; DAG-VQ-NEXT:dag:2            ^~~
; DAG-VQ-NEXT:              2: def 
; DAG-VQ-NEXT:dag:1            ^~~
; DAG-VQ-NEXT:dag:4'0            {   search range start (exclusive)
; DAG-VQ-NEXT:dag:4'1                error: no match found in search range
; DAG-VQ-NEXT:              3: abc 
; DAG-VQ-NEXT:dag:3            ^~~
; DAG-VQ-NEXT:dag:4'2              } search range end (exclusive)
; DAG-VQ-NEXT:>>>>>>
;  DAG-VQ-NOT:{{.}}

;      DAG-Q:<<<<<<
; DAG-Q-NEXT:              1: abc 
; DAG-Q-NEXT:              2: def 
; DAG-Q-NEXT:dag:4'0            {   search range start (exclusive)
; DAG-Q-NEXT:dag:4'1                error: no match found in search range
; DAG-Q-NEXT:              3: abc 
; DAG-Q-NEXT:dag:4'2              } search range end (exclusive)
; DAG-Q-NEXT:>>>>>>
;  DAG-Q-NOT:{{.}}

; Check sorting of annotations when the order of diagnostics across an input
; line is different than the order of the associated directives in the check
; file.  Try cases when diagnostics' input ranges overlap but are not
; identical to check how that affects sorting.

; RUN: echo 'abc def abc def' > %t.in

; RUN: echo 'CHECK-DAG: def' > %t.chk
; RUN: echo 'CHECK-DAG: bc' >> %t.chk
; RUN: echo 'CHECK-DAG: abc' >> %t.chk
; RUN: echo 'CHECK-DAG: de' >> %t.chk
; RUN: echo 'CHECK-DAG: def' >> %t.chk

; REDEFINE: %{pre} = DAG1L
; RUN: not %{run-vv}
; RUN: not %{run-v}
; RUN: not %{run}

; Verbose diagnostics are suppressed but not errors.
; DAG1L:{{.*}}error:{{.*}}

;      DAG1L-VV:<<<<<<
; DAG1L-VV-NEXT:              1: abc def abc def 
; DAG1L-VV-NEXT:dag:1                ^~~
; DAG1L-VV-NEXT:dag:2             ^~
; DAG1L-VV-NEXT:dag:3'0          !~~               discard: overlaps earlier match
; DAG1L-VV-NEXT:dag:3'1                  ^~~
; DAG1L-VV-NEXT:dag:4'0              !~            discard: overlaps earlier match
; DAG1L-VV-NEXT:dag:4'1                      ^~
; DAG1L-VV-NEXT:dag:5'0              !~~           discard: overlaps earlier match
; DAG1L-VV-NEXT:dag:5'1                      !~~   discard: overlaps earlier match
; DAG1L-VV-NEXT:dag:5'2                       {  } search range (exclusive bounds)
; DAG1L-VV-NEXT:dag:5'3                            error: no match found in search range
; DAG1L-VV-NEXT:>>>>>>
;  DAG1L-VV-NOT:{{.}}

;      DAG1L-VQ:<<<<<<
; DAG1L-VQ-NEXT:              1: abc def abc def 
; DAG1L-VQ-NEXT:dag:1                ^~~
; DAG1L-VQ-NEXT:dag:2             ^~
; DAG1L-VQ-NEXT:dag:3                    ^~~
; DAG1L-VQ-NEXT:dag:4                        ^~
; DAG1L-VQ-NEXT:dag:5'0                       {  } search range (exclusive bounds)
; DAG1L-VQ-NEXT:dag:5'1                            error: no match found in search range
; DAG1L-VQ-NEXT:>>>>>>
;  DAG1L-VQ-NOT:{{.}}

;      DAG1L-Q:<<<<<<
; DAG1L-Q-NEXT:              1: abc def abc def 
; DAG1L-Q-NEXT:dag:5'0                       {  } search range (exclusive bounds)
; DAG1L-Q-NEXT:dag:5'1                            error: no match found in search range
; DAG1L-Q-NEXT:>>>>>>
;  DAG1L-Q-NOT:{{.}}

;--------------------------------------------------
; CHECK-LABEL
;
; Each CHECK-LABEL is processed twice: once before other patterns in the
; preceding section, and once afterward.
;
; As expected, the search range for a negative pattern preceding a CHECK-LABEL
; ends at the start of the CHECK-LABEL match.  not:7 and not:11 below
; demonstrate this behavior.
;
; The search range for a positive pattern preceding a CHECK-LABEL ends at the
; end of the CHECK-LABEL match.  check:3 and check:5 below demonstrate this
; behavior.  As in the case of check:5, an effect of this behavior is that the
; second CHECK-LABEL match might fail even though the first succeeded.
;
; FIXME: It seems like the search range for such a positive pattern should be
; the same as in the case of a negative pattern.  Note that -dump-input is
; correct here.  It's the matching behavior that's strange.
;--------------------------------------------------

; RUN: echo 'text'   >  %t.in
; RUN: echo 'labelA' >> %t.in
; RUN: echo 'textA'  >> %t.in
; RUN: echo 'labelB' >> %t.in
; RUN: echo 'textB'  >> %t.in
; RUN: echo 'labelC' >> %t.in
; RUN: echo 'textC'  >> %t.in
; RUN: echo 'labelD' >> %t.in
; RUN: echo 'textD'  >> %t.in
; RUN: echo 'labelE' >> %t.in
; RUN: echo 'textE'  >> %t.in
; RUN: echo 'labelF' >> %t.in

; RUN: echo 'CHECK: text'         >  %t.chk
; RUN: echo 'CHECK-LABEL: labelA' >> %t.chk
; RUN: echo 'CHECK: foobar'       >> %t.chk
; RUN: echo 'CHECK-LABEL: labelB' >> %t.chk
; RUN: echo 'CHECK: labelC'       >> %t.chk
; RUN: echo 'CHECK-LABEL: labelC' >> %t.chk
; RUN: echo 'CHECK-NOT: foobar'   >> %t.chk
; RUN: echo 'CHECK-LABEL: labelD' >> %t.chk
; RUN: echo 'CHECK-NOT: textD'    >> %t.chk
; RUN: echo 'CHECK-LABEL: labelE' >> %t.chk
; RUN: echo 'CHECK-NOT: labelF'   >> %t.chk
; RUN: echo 'CHECK-LABEL: labelF' >> %t.chk

; REDEFINE: %{pre} = LAB
; RUN: not %{run-vv}
; RUN: not %{run-v}
; RUN: not %{run}

; Verbose diagnostics are suppressed but not errors.
; LAB:{{.*}}.chk:3:8: error: CHECK: expected string not found in input
; LAB:{{.*}}.chk:6:14: error: CHECK-LABEL: expected string not found in input
; LAB:{{.*}}.chk:9:12: error: CHECK-NOT: excluded string found in input

;       LAB-V:<<<<<<
;  LAB-V-NEXT:              1: text 
;  LAB-V-NEXT:check:1          ^~~~
;  LAB-V-NEXT:              2: labelA 
;  LAB-V-NEXT:label:2'0        ^~~~~~
;  LAB-V-NEXT:label:2'1        ^~~~~~
;  LAB-V-NEXT:check:3'0             {   search range start (exclusive)
;  LAB-V-NEXT:check:3'1                 error: no match found in search range
;  LAB-V-NEXT:              3: textA 
;  LAB-V-NEXT:              4: labelB 
;  LAB-V-NEXT:label:4          ^~~~~~
;  LAB-V-NEXT:check:3'2              }  search range end (exclusive)
;  LAB-V-NEXT:              5: textB 
;  LAB-V-NEXT:              6: labelC 
;  LAB-V-NEXT:label:6'0        ^~~~~~
;  LAB-V-NEXT:check:5          ^~~~~~
;  LAB-V-NEXT:label:6'1             {}  search range (exclusive bounds)
;  LAB-V-NEXT:label:6'2                 error: no match found in search range
; LAB-VV-NEXT:not:7'0               {   search range start (exclusive)
;  LAB-V-NEXT:              7: textC 
; LAB-VV-NEXT:not:7'1                } search range end (exclusive)
;  LAB-V-NEXT:              8: labelD 
;  LAB-V-NEXT:label:8'0        ^~~~~~
;  LAB-V-NEXT:label:8'1        ^~~~~~
;  LAB-V-NEXT:not:9'0               {   search range start (exclusive)
;  LAB-V-NEXT:              9: textD 
;  LAB-V-NEXT:not:9'1          !~~~~   error: no match expected
;  LAB-V-NEXT:not:9'2                } search range end (exclusive)
;  LAB-V-NEXT:             10: labelE 
;  LAB-V-NEXT:label:10'0       ^~~~~~
;  LAB-V-NEXT:label:10'1       ^~~~~~
; LAB-VV-NEXT:not:11'0              {   search range start (exclusive)
;  LAB-V-NEXT:             11: textE 
; LAB-VV-NEXT:not:11'1               } search range end (exclusive)
;  LAB-V-NEXT:             12: labelF 
;  LAB-V-NEXT:label:12'0       ^~~~~~
;  LAB-V-NEXT:label:12'1       ^~~~~~
;  LAB-V-NEXT:>>>>>>
;   LAB-V-NOT:{{.}}

;      LAB-Q:<<<<<<
; LAB-Q-NEXT:              1: text 
; LAB-Q-NEXT:              2: labelA 
; LAB-Q-NEXT:check:3'0             {   search range start (exclusive)
; LAB-Q-NEXT:check:3'1                 error: no match found in search range
; LAB-Q-NEXT:              3: textA 
; LAB-Q-NEXT:              4: labelB 
; LAB-Q-NEXT:check:3'2              }  search range end (exclusive)
; LAB-Q-NEXT:              5: textB 
; LAB-Q-NEXT:              6: labelC 
; LAB-Q-NEXT:label:6'0             {}  search range (exclusive bounds)
; LAB-Q-NEXT:label:6'1                 error: no match found in search range
; LAB-Q-NEXT:              7: textC 
; LAB-Q-NEXT:              8: labelD 
; LAB-Q-NEXT:not:9'0               {   search range start (exclusive)
; LAB-Q-NEXT:              9: textD 
; LAB-Q-NEXT:not:9'1          !~~~~   error: no match expected
; LAB-Q-NEXT:not:9'2                } search range end (exclusive)
; LAB-Q-NEXT:             10: labelE 
; LAB-Q-NEXT:             11: textE 
; LAB-Q-NEXT:             12: labelF 
; LAB-Q-NEXT:>>>>>>
;  LAB-Q-NOT:{{.}}

;--------------------------------------------------
; --implicit-check-not
;
; The first two --implicit-check-not patterns have no match (success).  The
; third has an unexpected match (error).  To check per-input-line annotation
; sorting, all of those plus the CHECK directives have annotations on the same
; input line.
;--------------------------------------------------

; RUN: echo 'hello world again!' > %t.in

; RUN: echo 'CHECK: hel' > %t.chk
; RUN: echo 'CHECK: wor' >> %t.chk
; RUN: echo 'CHECK: !' >> %t.chk

; REDEFINE: %{pre} = IMPNOT
; REDEFINE: %{opts} =  \
; REDEFINE:     --implicit-check-not='goodbye' \
; REDEFINE:     --implicit-check-not='world' \
; REDEFINE:     --implicit-check-not='again'
; RUN: not %{run-vv}
; RUN: not %{run-v}
; RUN: not %{run}
; REDEFINE: %{opts} =

; Verbose diagnostics are suppressed but not errors.
; IMPNOT:{{.*}}command line:1:22: error: IMPLICIT-CHECK-NOT: excluded string found in input

;      IMPNOT-VV:<<<<<<
; IMPNOT-VV-NEXT:              1: hello world again! 
; IMPNOT-VV-NEXT:check:1          ^~~
; IMPNOT-VV-NEXT:not:imp1'0      {}                    search range (exclusive bounds)
; IMPNOT-VV-NEXT:not:imp2'0      {}                    search range (exclusive bounds)
; IMPNOT-VV-NEXT:not:imp3'0      {}                    search range (exclusive bounds)
; IMPNOT-VV-NEXT:check:2                ^~~
; IMPNOT-VV-NEXT:not:imp1'1         {   }              search range (exclusive bounds)
; IMPNOT-VV-NEXT:not:imp2'1         {   }              search range (exclusive bounds)
; IMPNOT-VV-NEXT:not:imp3'1         {   }              search range (exclusive bounds)
; IMPNOT-VV-NEXT:check:3                           ^
; IMPNOT-VV-NEXT:not:imp1'2               {        }   search range (exclusive bounds)
; IMPNOT-VV-NEXT:not:imp2'2               {        }   search range (exclusive bounds)
; IMPNOT-VV-NEXT:not:imp3'2               {        }   search range (exclusive bounds)
; IMPNOT-VV-NEXT:not:imp3'3                   !~~~~    error: no match expected
; IMPNOT-VV-NEXT:>>>>>>
;  IMPNOT-VV-NOT:{{.}}

;      IMPNOT-VQ:<<<<<<
; IMPNOT-VQ-NEXT:              1: hello world again! 
; IMPNOT-VQ-NEXT:check:1          ^~~
; IMPNOT-VQ-NEXT:check:2                ^~~
; IMPNOT-VQ-NEXT:check:3                           ^
; IMPNOT-VQ-NEXT:not:imp3'0               {        }   search range (exclusive bounds)
; IMPNOT-VQ-NEXT:not:imp3'1                   !~~~~    error: no match expected
; IMPNOT-VQ-NEXT:>>>>>>
;  IMPNOT-VQ-NOT:{{.}}

;      IMPNOT-Q:<<<<<<
; IMPNOT-Q-NEXT:              1: hello world again! 
; IMPNOT-Q-NEXT:not:imp3'0               {        }   search range (exclusive bounds)
; IMPNOT-Q-NEXT:not:imp3'1                   !~~~~    error: no match expected
; IMPNOT-Q-NEXT:>>>>>>
;  IMPNOT-Q-NOT:{{.}}

;--------------------------------------------------
; Substitutions: successful and failed positive directives.
;--------------------------------------------------

; RUN: echo 'def-match1 def-match2'  >  %t.in
; RUN: echo 'def-match1 def-nomatch' >> %t.in

; RUN: echo 'CHECK: [[DEF_MATCH1]] [[DEF_MATCH2]]'            >  %t.chk
; RUN: echo 'CHECK: [[DEF_MATCH1]] [[UNDEF]] [[DEF_NOMATCH]]' >> %t.chk

; REDEFINE: %{pre} = SUBST-POS
; REDEFINE: %{opts} =  \
; REDEFINE:     -DDEF_MATCH1=def-match1 -DDEF_MATCH2=def-match2 \
; REDEFINE:     -DDEF_NOMATCH=foobar
; RUN: not %{run-vv}
; RUN: not %{run-v}
; RUN: not %{run}
; REDEFINE: %{opts} =

; Verbose diagnostics are suppressed but not errors.
; SUBST-POS:{{.*}}error:{{.*}}
; SUBST-POS:{{.*}}possible intended match here{{.*}}

;        SUBST-POS:<<<<<<
;   SUBST-POS-NEXT:              1: def-match1 def-match2 
; SUBST-POS-V-NEXT:check:1'0        ^~~~~~~~~~~~~~~~~~~~~
; SUBST-POS-V-NEXT:check:1'1                                with "DEF_MATCH1" equal to "def-match1"
; SUBST-POS-V-NEXT:check:1'2                                with "DEF_MATCH2" equal to "def-match2"
;   SUBST-POS-NEXT:check:2'0                            {   search range start (exclusive)
;   SUBST-POS-NEXT:check:2'1                                error: match failed for invalid pattern
;   SUBST-POS-NEXT:check:2'2                                undefined variable: UNDEF
;   SUBST-POS-NEXT:check:2'3                                with "DEF_MATCH1" equal to "def-match1"
;   SUBST-POS-NEXT:check:2'4                                with "DEF_NOMATCH" equal to "foobar"
;   SUBST-POS-NEXT:              2: def-match1 def-nomatch 
;   SUBST-POS-NEXT:check:2'5                 ?               possible intended match
;   SUBST-POS-NEXT:check:2'6                               } search range end (exclusive)
;   SUBST-POS-NEXT:>>>>>>

;--------------------------------------------------
; Substitutions: successful and failed negative directives.
;--------------------------------------------------

; RUN: echo 'def-match1 def-nomatch' >  %t.in
; RUN: echo 'def-match1 def-match2'  >> %t.in
; RUN: echo 'END'                    >> %t.in

; RUN: echo 'CHECK-NOT: [[DEF_MATCH1]] [[UNDEF]] [[DEF_NOMATCH]]' >  %t.chk
; RUN: echo 'CHECK-NOT: [[DEF_MATCH1]] [[DEF_MATCH2]]'            >> %t.chk
; RUN: echo 'CHECK: END'                                          >> %t.chk

; REDEFINE: %{pre} = SUBST-NEG
; REDEFINE: %{opts} =  \
; REDEFINE:     -DDEF_MATCH1=def-match1 -DDEF_MATCH2=def-match2 \
; REDEFINE:     -DDEF_NOMATCH=foobar
; RUN: not %{run-vv}
; RUN: not %{run-v}
; RUN: not %{run}
; REDEFINE: %{opts} =

; Verbose diagnostics are suppressed but not errors.
; SUBST-NEG-COUNT-2:{{.*}}error:{{.*}}

;        SUBST-NEG:<<<<<<
;   SUBST-NEG-NEXT:              1: def-match1 def-nomatch 
;   SUBST-NEG-NEXT:not:1'0         {                         search range start (exclusive)
;   SUBST-NEG-NEXT:not:1'1                                   error: match failed for invalid pattern
;   SUBST-NEG-NEXT:not:1'2                                   undefined variable: UNDEF
;   SUBST-NEG-NEXT:not:1'3                                   with "DEF_MATCH1" equal to "def-match1"
;   SUBST-NEG-NEXT:not:1'4                                   with "DEF_NOMATCH" equal to "foobar"
;   SUBST-NEG-NEXT:not:2'0         {                         search range start (exclusive)
;   SUBST-NEG-NEXT:              2: def-match1 def-match2 
;   SUBST-NEG-NEXT:not:1'5                                } search range end (exclusive)
;   SUBST-NEG-NEXT:not:2'1          !~~~~~~~~~~~~~~~~~~~~   error: no match expected
;   SUBST-NEG-NEXT:not:2'2                                  with "DEF_MATCH1" equal to "def-match1"
;   SUBST-NEG-NEXT:not:2'3                                  with "DEF_MATCH2" equal to "def-match2"
;   SUBST-NEG-NEXT:not:2'4                                } search range end (exclusive)
;   SUBST-NEG-NEXT:              3: END 
; SUBST-NEG-V-NEXT:check:3          ^~~
;   SUBST-NEG-NEXT:>>>>>>

;--------------------------------------------------
; Captured variables
;--------------------------------------------------

; RUN: echo 'strvar: foo'           >  %t.in
; RUN: echo 'numvar no expr: 51'    >> %t.in
; RUN: echo 'numvar expr: -49'      >> %t.in
; RUN: echo 'many: foo 100 8 bar'   >> %t.in
; RUN: echo 'var in neg match: foo' >> %t.in
; RUN: echo 'END'                   >> %t.in

; RUN: echo 'CHECK: strvar: [[STRVAR:[a-z]+]]'                         >  %t.chk
; RUN: echo 'CHECK: numvar no expr: [[#NUMVAR_NO_EXPR:]]'              >> %t.chk
; RUN: echo 'CHECK: numvar expr: [[#%d,NUMVAR_EXPR:2-NUMVAR_NO_EXPR]]' >> %t.chk

; Capture many variables of different kinds in a different order than their
; names sort alphabetically to ensure they're sorted in capture order.
; RUN: echo 'CHECK: many: [[VAR1:foo]] [[#%d,VAR3:]] [[#VAR2:]] [[VAR4:bar]]' \
; RUN:      >> %t.chk

; RUN: echo 'CHECK-NOT: var in neg match: [[VAR:foo]]' >> %t.chk
; RUN: echo 'CHECK: END'                               >> %t.chk

; REDEFINE: %{pre} = CAPTURE-NEG
; RUN: not %{run-vv}
; RUN: not %{run-v}
; RUN: not %{run}

; Verbose diagnostics are suppressed but not errors.
; CAPTURE-NEG:{{.*}}error:{{.*}}

;        CAPTURE-NEG:<<<<<<
;   CAPTURE-NEG-NEXT:              1: strvar: foo 
; CAPTURE-NEG-V-NEXT:check:1'0        ^~~~~~~~~~~
  CAPTURE-NEG-V-NEXT:check:1'1                ^~~   captured var "STRVAR"
;   CAPTURE-NEG-NEXT:              2: numvar no expr: 51 
; CAPTURE-NEG-V-NEXT:check:2'0        ^~~~~~~~~~~~~~~~~~
; CAPTURE-NEG-V-NEXT:check:2'1                        ^~   captured var "NUMVAR_NO_EXPR"
;   CAPTURE-NEG-NEXT:              3: numvar expr: -49 
; CAPTURE-NEG-V-NEXT:check:3'0        ^~~~~~~~~~~~~~~~
; CAPTURE-NEG-V-NEXT:check:3'1                           with "%d,NUMVAR_EXPR:2-NUMVAR_NO_EXPR" equal to "-49"
; CAPTURE-NEG-V-NEXT:check:3'2                     ^~~   captured var "NUMVAR_EXPR"
;   CAPTURE-NEG-NEXT:              4: many: foo 100 8 bar 
; CAPTURE-NEG-V-NEXT:check:4'0        ^~~~~~~~~~~~~~~~~~~
; CAPTURE-NEG-V-NEXT:check:4'1              ^~~             captured var "VAR1"
; CAPTURE-NEG-V-NEXT:check:4'2                  ^~~         captured var "VAR3"
; CAPTURE-NEG-V-NEXT:check:4'3                      ^       captured var "VAR2"
; CAPTURE-NEG-V-NEXT:check:4'4                        ^~~   captured var "VAR4"
;   CAPTURE-NEG-NEXT:not:5'0                            {   search range start (exclusive)
;   CAPTURE-NEG-NEXT:              5: var in neg match: foo 
;   CAPTURE-NEG-NEXT:not:5'1          !~~~~~~~~~~~~~~~~~~~~   error: no match expected
;   CAPTURE-NEG-NEXT:not:5'2                            !~~   captured var "VAR"
;   CAPTURE-NEG-NEXT:not:5'3                                } search range end (exclusive)
;   CAPTURE-NEG-NEXT:              6: END 
; CAPTURE-NEG-V-NEXT:check:6          ^~~
;   CAPTURE-NEG-NEXT:>>>>>>

;--------------------------------------------------
; CHECK-NEXT, CHECK-SAME, CHECK-DAG note fixups.
;
; When CHECK-NEXT or CHECK-SAME fails for the wrong line, or when a CHECK-DAG
; match is discarded, the associated diagnostic type must be converted from
; successful to failed or discarded.  However, any note annotation must be
; traversed to find that diagnostic.  We check this behavior here only for
; substitutions, but it's the same mechanism for all note annotations.
;--------------------------------------------------

;- - - - - - - - - - - - - - - - - - - - - - - - -
; CHECK-NEXT.
;- - - - - - - - - - - - - - - - - - - - - - - - -

; RUN: echo 'pre var' > %t.in

; RUN: echo 'CHECK: pre'          >  %t.chk
; RUN: echo 'CHECK-NEXT: [[VAR]]' >> %t.chk

; REDEFINE: %{pre} = SUBST_NEXT
; REDEFINE: %{opts} = -DVAR=var
; RUN: not %{run-vv}
; RUN: not %{run-v}
; RUN: not %{run}
; REDEFINE: %{opts} =

; Verbose diagnostics are suppressed but not errors.
; SUBST_NEXT:{{.*}}error:{{.*}}

;        SUBST_NEXT:<<<<<<
;   SUBST_NEXT-NEXT:              1: pre var 
; SUBST_NEXT-V-NEXT:check:1          ^~~
;   SUBST_NEXT-NEXT:next:2'0           {     } search range (exclusive bounds)
;   SUBST_NEXT-NEXT:next:2'1             !~~   error: match on wrong line
; SUBST_NEXT-V-NEXT:next:2'2                   with "VAR" equal to "var"
;   SUBST_NEXT-NEXT:>>>>>>

;- - - - - - - - - - - - - - - - - - - - - - - - -
; CHECK-SAME.
;- - - - - - - - - - - - - - - - - - - - - - - - -

; RUN: echo 'pre' >  %t.in
; RUN: echo 'var' >> %t.in

; RUN: echo 'CHECK: pre'          >  %t.chk
; RUN: echo 'CHECK-SAME: [[VAR]]' >> %t.chk

; REDEFINE: %{pre} = SUBST_SAME
; REDEFINE: %{opts} = -DVAR=var
; RUN: not %{run-vv}
; RUN: not %{run-v}
; RUN: not %{run}
; REDEFINE: %{opts} =

; Verbose diagnostics are suppressed but not errors.
; SUBST_SAME:{{.*}}error:{{.*}}

;      SUBST_SAME-V:<<<<<<
; SUBST_SAME-V-NEXT:              1: pre 
; SUBST_SAME-V-NEXT:check:1          ^~~
; SUBST_SAME-V-NEXT:same:2'0           {   search range start (exclusive)
; SUBST_SAME-V-NEXT:              2: var 
; SUBST_SAME-V-NEXT:same:2'1         !~~   error: match on wrong line
; SUBST_SAME-V-NEXT:same:2'2               with "VAR" equal to "var"
; SUBST_SAME-V-NEXT:same:2'3             } search range end (exclusive)
; SUBST_SAME-V-NEXT:>>>>>>

;      SUBST_SAME-Q:<<<<<<
; SUBST_SAME-Q-NEXT:              1: pre 
; SUBST_SAME-Q-NEXT:same:2'0           {   search range start (exclusive)
; SUBST_SAME-Q-NEXT:              2: var 
; SUBST_SAME-Q-NEXT:same:2'1         !~~   error: match on wrong line
; SUBST_SAME-Q-NEXT:same:2'2             } search range end (exclusive)
; SUBST_SAME-Q-NEXT:>>>>>>

;- - - - - - - - - - - - - - - - - - - - - - - - -
; CHECK-DAG.
;- - - - - - - - - - - - - - - - - - - - - - - - -

; RUN: echo 'var' >  %t.in
; RUN: echo 'var' >> %t.in
; RUN: echo 'END' >> %t.in

; RUN: echo 'CHECK-DAG: var'      >  %t.chk
; RUN: echo 'CHECK-DAG: [[VAR]]'  >> %t.chk
; RUN: echo 'CHECK: END'          >> %t.chk

; REDEFINE: %{pre} = SUBST_DAG
; REDEFINE: %{opts} = -DVAR=var
; RUN: %{run-vv}
; RUN: %{run-v}
; RUN: %{run}
; REDEFINE: %{opts} =

;      SUBST_DAG-VV:<<<<<<
; SUBST_DAG-VV-NEXT:              1: var 
; SUBST_DAG-VV-NEXT:dag:1            ^~~
; SUBST_DAG-VV-NEXT:dag:2'0          !~~   discard: overlaps earlier match
; SUBST_DAG-VV-NEXT:dag:2'1                with "VAR" equal to "var"
; SUBST_DAG-VV-NEXT:              2: var 
; SUBST_DAG-VV-NEXT:dag:2'2          ^~~
; SUBST_DAG-VV-NEXT:dag:2'3                with "VAR" equal to "var"
; SUBST_DAG-VV-NEXT:              3: END 
; SUBST_DAG-VV-NEXT:check:3          ^~~
; SUBST_DAG-VV-NEXT:>>>>>>

;      SUBST_DAG-VQ:<<<<<<
; SUBST_DAG-VQ-NEXT:              1: var 
; SUBST_DAG-VQ-NEXT:dag:1            ^~~
; SUBST_DAG-VQ-NEXT:              2: var 
; SUBST_DAG-VQ-NEXT:dag:2'0          ^~~
; SUBST_DAG-VQ-NEXT:dag:2'1                with "VAR" equal to "var"
; SUBST_DAG-VQ-NEXT:              3: END 
; SUBST_DAG-VQ-NEXT:check:3          ^~~
; SUBST_DAG-VQ-NEXT:>>>>>>

;      SUBST_DAG-Q:<<<<<<
; SUBST_DAG-Q-NEXT:              1: var 
; SUBST_DAG-Q-NEXT:              2: var 
; SUBST_DAG-Q-NEXT:              3: END 
; SUBST_DAG-Q-NEXT:>>>>>>

;--------------------------------------------------
; Check multiline marker where start/end columns vary across lines.
;--------------------------------------------------

; RUN: echo '<start' >  %t.in
; RUN: echo ''       >> %t.in
; RUN: echo '1'      >> %t.in
; RUN: echo '12'     >> %t.in
; RUN: echo 'end>'   >> %t.in

; RUN: echo 'CHECK: start{{(.|[[:space:]])*}}end' >  %t.chk

; REDEFINE: %{pre} = MULTILINE-MARKER
; RUN: %{run-vv}
; RUN: %{run-v}
; RUN: %{run}

;        MULTILINE-MARKER:<<<<<<
;   MULTILINE-MARKER-NEXT:              1: <start 
; MULTILINE-MARKER-V-NEXT:check:1           ^~~~~~
;   MULTILINE-MARKER-NEXT:              2:  
; MULTILINE-MARKER-V-NEXT:check:1          ~
;   MULTILINE-MARKER-NEXT:              3: 1 
; MULTILINE-MARKER-V-NEXT:check:1          ~~
;   MULTILINE-MARKER-NEXT:              4: 12 
; MULTILINE-MARKER-V-NEXT:check:1          ~~~
;   MULTILINE-MARKER-NEXT:              5: end> 
; MULTILINE-MARKER-V-NEXT:check:1          ~~~
;   MULTILINE-MARKER-NEXT:>>>>>>

;--------------------------------------------------
; Check empty and single-character match ranges.
;--------------------------------------------------

; RUN: echo '11' >  %t.in

; RUN: echo 'empty  at    bof: CHECK: {{0?}}'           >  %t.chk
; RUN: echo 'single at    bof: CHECK: {{1?}}'           >> %t.chk
; RUN: echo 'empty  in middle: CHECK: {{0?}}'           >> %t.chk
; RUN: echo 'single in middle: CHECK: {{1?}}'           >> %t.chk
; RUN: echo 'single at    eof: CHECK: {{[[:space:]]?}}' >> %t.chk
; RUN: echo 'empty  at    eof: CHECK: {{0?}}'           >> %t.chk

; REDEFINE: %{pre} = EMPTY-SINGLE-MATCH
; RUN: %{run-vv}
; RUN: %{run-v}
; RUN: %{run}

;        EMPTY-SINGLE-MATCH:<<<<<<
;   EMPTY-SINGLE-MATCH-NEXT:              1: 11 
; EMPTY-SINGLE-MATCH-V-NEXT:check:1          ^
; EMPTY-SINGLE-MATCH-V-NEXT:check:2          ^
; EMPTY-SINGLE-MATCH-V-NEXT:check:3           ^
; EMPTY-SINGLE-MATCH-V-NEXT:check:4           ^
; EMPTY-SINGLE-MATCH-V-NEXT:check:5            ^
; EMPTY-SINGLE-MATCH-V-NEXT:              2: 
; EMPTY-SINGLE-MATCH-V-NEXT:check:6          ^
;   EMPTY-SINGLE-MATCH-NEXT:>>>>>>

;--------------------------------------------------
; Check search range for empty file and thus empty search range at start/end of
; file.
;--------------------------------------------------

; RUN: echo 'CHECK-NOT: foo' > %t.chk
; REDEFINE: %{opts} = -input-file=/dev/null -allow-empty

; REDEFINE: %{pre} = NEG-SEARCH-EMPTY-FILE
; RUN: %{run-vv}
; RUN: %{run-v}
; RUN: %{run}

;         NEG-SEARCH-EMPTY-FILE:<<<<<<
; NEG-SEARCH-EMPTY-FILE-VV-NEXT:              1: 
; NEG-SEARCH-EMPTY-FILE-VV-NEXT:eof:1            ^
; NEG-SEARCH-EMPTY-FILE-VV-NEXT:not:1           {} search range (exclusive bounds)
;    NEG-SEARCH-EMPTY-FILE-NEXT:>>>>>>

; RUN: echo 'CHECK: foo' > %t.chk

; REDEFINE: %{pre} = POS-SEARCH-EMPTY-FILE
; RUN: not %{run-vv}
; RUN: not %{run-v}
; RUN: not %{run}

; Verbose diagnostics are suppressed but not errors.
; POS-SEARCH-EMPTY-FILE:{{.*}}error:{{.*}}

;      POS-SEARCH-EMPTY-FILE:<<<<<<
; POS-SEARCH-EMPTY-FILE-NEXT:              1: 
; POS-SEARCH-EMPTY-FILE-NEXT:check:1'0       {} search range (exclusive bounds)
; POS-SEARCH-EMPTY-FILE-NEXT:check:1'1          error: no match found in search range
; POS-SEARCH-EMPTY-FILE-NEXT:>>>>>>

; REDEFINE: %{opts} =

;--------------------------------------------------
; Check non-empty search range at start/end of file.
;--------------------------------------------------

; RUN: echo 'one line' > %t.in

; RUN: echo 'CHECK-NOT: foo' > %t.chk

; REDEFINE: %{pre} = SEARCH-BOF-EOF-ONE-LINE
; RUN: %{run-vv}
; RUN: %{run-v}
; RUN: %{run}

;         SEARCH-BOF-EOF-ONE-LINE:<<<<<<
;    SEARCH-BOF-EOF-ONE-LINE-NEXT:              1: one line 
; SEARCH-BOF-EOF-ONE-LINE-VV-NEXT:not:1           {         } search range (exclusive bounds)
; SEARCH-BOF-EOF-ONE-LINE-VV-NEXT:              2: 
; SEARCH-BOF-EOF-ONE-LINE-VV-NEXT:eof:1            ^
;    SEARCH-BOF-EOF-ONE-LINE-NEXT:>>>>>>

; RUN: echo 'line 1' >  %t.in
; RUN: echo 'line 2' >> %t.in

; RUN: echo 'CHECK: foo' > %t.chk

; REDEFINE: %{pre} = SEARCH-BOF-EOF-MULTI-LINE
; RUN: not %{run-vv}
; RUN: not %{run-v}
; RUN: not %{run}

; Verbose diagnostics are suppressed but not errors.
; SEARCH-BOF-EOF-MULTI-LINE:{{.*}}error:{{.*}}

;      SEARCH-BOF-EOF-MULTI-LINE:<<<<<<
; SEARCH-BOF-EOF-MULTI-LINE-NEXT:              1: line 1 
; SEARCH-BOF-EOF-MULTI-LINE-NEXT:check:1'0       {         search range start (exclusive)
; SEARCH-BOF-EOF-MULTI-LINE-NEXT:check:1'1                 error: no match found in search range
; SEARCH-BOF-EOF-MULTI-LINE-NEXT:              2: line 2 
; SEARCH-BOF-EOF-MULTI-LINE-NEXT:check:1'2               } search range end (exclusive)
; SEARCH-BOF-EOF-MULTI-LINE-NEXT:>>>>>>

;--------------------------------------------------
; Check search ranges at line boundaries but not file boundaries.  Also check
; empty search ranges (for non-empty file) and one-character search ranges.
;--------------------------------------------------

; RUN: echo 'start'      >  %t.in
; RUN: echo 'empty'      >> %t.in
; RUN: echo 'next'       >> %t.in
; RUN: echo 'one char'   >> %t.in
; RUN: echo 'next'       >> %t.in
; RUN: echo 'one line'   >> %t.in
; RUN: echo 'next'       >> %t.in
; RUN: echo 'multi'      >> %t.in
; RUN: echo 'line'       >> %t.in
; RUN: echo 'next'       >> %t.in
; RUN: echo 'off by one' >> %t.in
; RUN: echo ' end'       >> %t.in

; RUN: echo ' 1: CHECK: start{{[[:space:]]}}'               >  %t.chk
; RUN: echo ' 2: CHECK-NOT: foo'                            >> %t.chk
; RUN: echo ' 3: CHECK: empty'                              >> %t.chk
; RUN: echo ' 4: CHECK-NOT: foo'                            >> %t.chk
; RUN: echo ' 5: CHECK: {{[[:space:]]}}next{{[[:space:]]}}' >> %t.chk
; RUN: echo ' 6: CHECK-NOT: foo'                            >> %t.chk
; RUN: echo ' 7: CHECK: ne char'                            >> %t.chk
; RUN: echo ' 8: CHECK-NOT: foo'                            >> %t.chk
; RUN: echo ' 9: CHECK: next{{[[:space:]]}}'                >> %t.chk
; RUN: echo '10: CHECK-NOT: foo'                            >> %t.chk
; RUN: echo '11: CHECK: next{{[[:space:]]}}'                >> %t.chk
; RUN: echo '12: CHECK-NOT: foo'                            >> %t.chk
; RUN: echo '13: CHECK: next'                               >> %t.chk
; RUN: echo '14: CHECK-NOT: foo'                            >> %t.chk
; RUN: echo '15: CHECK: end'                                >> %t.chk

; REDEFINE: %{pre} = SEARCH-LINE-BOUNDS
; RUN: %{run-vv}
; RUN: %{run-v}
; RUN: %{run}

;         SEARCH-LINE-BOUNDS:<<<<<<
;    SEARCH-LINE-BOUNDS-NEXT:              1: start 
;  SEARCH-LINE-BOUNDS-V-NEXT:check:1          ^~~~~~
;    SEARCH-LINE-BOUNDS-NEXT:              2: empty 
;  SEARCH-LINE-BOUNDS-V-NEXT:check:3          ^~~~~
; SEARCH-LINE-BOUNDS-VV-NEXT:not:2           {}       search range (exclusive bounds)
;  SEARCH-LINE-BOUNDS-V-NEXT:check:5               ^
; SEARCH-LINE-BOUNDS-VV-NEXT:not:4                {}  search range (exclusive bounds)
;    SEARCH-LINE-BOUNDS-NEXT:              3: next 
;  SEARCH-LINE-BOUNDS-V-NEXT:check:5          ~~~~~
;    SEARCH-LINE-BOUNDS-NEXT:              4: one char 
;  SEARCH-LINE-BOUNDS-V-NEXT:check:7           ^~~~~~~
; SEARCH-LINE-BOUNDS-VV-NEXT:not:6           { }         search range (exclusive bounds)
; SEARCH-LINE-BOUNDS-VV-NEXT:not:8                   { } search range (exclusive bounds)
;    SEARCH-LINE-BOUNDS-NEXT:              5: next 
;  SEARCH-LINE-BOUNDS-V-NEXT:check:9          ^~~~~
;    SEARCH-LINE-BOUNDS-NEXT:              6: one line 
; SEARCH-LINE-BOUNDS-VV-NEXT:not:10          {         } search range (exclusive bounds)
;    SEARCH-LINE-BOUNDS-NEXT:              7: next 
;  SEARCH-LINE-BOUNDS-V-NEXT:check:11         ^~~~~
;    SEARCH-LINE-BOUNDS-NEXT:              8: multi 
; SEARCH-LINE-BOUNDS-VV-NEXT:not:12'0        {        search range start (exclusive)
;    SEARCH-LINE-BOUNDS-NEXT:              9: line 
; SEARCH-LINE-BOUNDS-VV-NEXT:not:12'1              } search range end (exclusive)
;    SEARCH-LINE-BOUNDS-NEXT:             10: next 
;  SEARCH-LINE-BOUNDS-V-NEXT:check:13         ^~~~
; SEARCH-LINE-BOUNDS-VV-NEXT:not:14'0            {   search range start (exclusive)
;    SEARCH-LINE-BOUNDS-NEXT:             11: off by one 
;    SEARCH-LINE-BOUNDS-NEXT:             12:  end 
;  SEARCH-LINE-BOUNDS-V-NEXT:check:15          ^~~
; SEARCH-LINE-BOUNDS-VV-NEXT:not:14'1          }     search range end (exclusive)
;    SEARCH-LINE-BOUNDS-NEXT:>>>>>>
