1 //===- FileCheck.cpp - Check that File's Contents match what is expected --===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // FileCheck does a line-by line check of a file that validates whether it
11 // contains the expected content. This is useful for regression tests etc.
13 // This program exits with an exit status of 2 on error, exit status of 0 if
14 // the file matched the expected contents, and exit status of 1 if it did not
15 // contain the expected contents.
17 //===----------------------------------------------------------------------===//
19 #include "llvm/Support/CommandLine.h"
20 #include "llvm/Support/InitLLVM.h"
21 #include "llvm/Support/Process.h"
22 #include "llvm/Support/raw_ostream.h"
23 #include "llvm/Support/FileCheck.h"
26 static cl::opt
<std::string
>
27 CheckFilename(cl::Positional
, cl::desc("<check-file>"), cl::Required
);
29 static cl::opt
<std::string
>
30 InputFilename("input-file", cl::desc("File to check (defaults to stdin)"),
31 cl::init("-"), cl::value_desc("filename"));
33 static cl::list
<std::string
> CheckPrefixes(
35 cl::desc("Prefix to use from check file (defaults to 'CHECK')"));
36 static cl::alias
CheckPrefixesAlias(
37 "check-prefixes", cl::aliasopt(CheckPrefixes
), cl::CommaSeparated
,
40 "Alias for -check-prefix permitting multiple comma separated values"));
42 static cl::opt
<bool> NoCanonicalizeWhiteSpace(
44 cl::desc("Do not treat all horizontal whitespace as equivalent"));
46 static cl::list
<std::string
> ImplicitCheckNot(
48 cl::desc("Add an implicit negative check with this pattern to every\n"
49 "positive check. This can be used to ensure that no instances of\n"
50 "this pattern occur which are not matched by a positive pattern"),
51 cl::value_desc("pattern"));
53 static cl::list
<std::string
> GlobalDefines("D", cl::Prefix
,
54 cl::desc("Define a variable to be used in capture patterns."),
55 cl::value_desc("VAR=VALUE"));
57 static cl::opt
<bool> AllowEmptyInput(
58 "allow-empty", cl::init(false),
59 cl::desc("Allow the input file to be empty. This is useful when making\n"
60 "checks that some error message does not occur, for example."));
62 static cl::opt
<bool> MatchFullLines(
63 "match-full-lines", cl::init(false),
64 cl::desc("Require all positive matches to cover an entire input line.\n"
65 "Allows leading and trailing whitespace if --strict-whitespace\n"
66 "is not also passed."));
68 static cl::opt
<bool> EnableVarScope(
69 "enable-var-scope", cl::init(false),
70 cl::desc("Enables scope for regex variables. Variables with names that\n"
71 "do not start with '$' will be reset at the beginning of\n"
72 "each CHECK-LABEL block."));
74 static cl::opt
<bool> AllowDeprecatedDagOverlap(
75 "allow-deprecated-dag-overlap", cl::init(false),
76 cl::desc("Enable overlapping among matches in a group of consecutive\n"
77 "CHECK-DAG directives. This option is deprecated and is only\n"
78 "provided for convenience as old tests are migrated to the new\n"
79 "non-overlapping CHECK-DAG implementation.\n"));
81 static cl::opt
<bool> Verbose("v", cl::init(false),
82 cl::desc("Print directive pattern matches.\n"));
84 static cl::opt
<bool> VerboseVerbose(
85 "vv", cl::init(false),
86 cl::desc("Print information helpful in diagnosing internal FileCheck\n"
87 "issues. Implies -v.\n"));
88 static const char * DumpInputEnv
= "FILECHECK_DUMP_INPUT_ON_FAILURE";
90 static cl::opt
<bool> DumpInputOnFailure(
91 "dump-input-on-failure", cl::init(std::getenv(DumpInputEnv
)),
92 cl::desc("Dump original input to stderr before failing.\n"
93 "The value can be also controlled using\n"
94 "FILECHECK_DUMP_INPUT_ON_FAILURE environment variable.\n"));
96 typedef cl::list
<std::string
>::const_iterator prefix_iterator
;
104 static void DumpCommandLine(int argc
, char **argv
) {
105 errs() << "FileCheck command line: ";
106 for (int I
= 0; I
< argc
; I
++)
107 errs() << " " << argv
[I
];
111 int main(int argc
, char **argv
) {
112 // Enable use of ANSI color codes because FileCheck is using them to
114 llvm::sys::Process::UseANSIEscapeCodes(true);
116 InitLLVM
X(argc
, argv
);
117 cl::ParseCommandLineOptions(argc
, argv
, /*Overview*/ "", /*Errs*/ nullptr,
120 FileCheckRequest Req
;
121 for (auto Prefix
: CheckPrefixes
)
122 Req
.CheckPrefixes
.push_back(Prefix
);
124 for (auto CheckNot
: ImplicitCheckNot
)
125 Req
.ImplicitCheckNot
.push_back(CheckNot
);
127 for (auto G
: GlobalDefines
)
128 Req
.GlobalDefines
.push_back(G
);
130 Req
.AllowEmptyInput
= AllowEmptyInput
;
131 Req
.EnableVarScope
= EnableVarScope
;
132 Req
.AllowDeprecatedDagOverlap
= AllowDeprecatedDagOverlap
;
133 Req
.Verbose
= Verbose
;
134 Req
.VerboseVerbose
= VerboseVerbose
;
135 Req
.NoCanonicalizeWhiteSpace
= NoCanonicalizeWhiteSpace
;
136 Req
.MatchFullLines
= MatchFullLines
;
142 if (!FC
.ValidateCheckPrefixes()) {
143 errs() << "Supplied check-prefix is invalid! Prefixes must be unique and "
144 "start with a letter and contain only alphanumeric characters, "
145 "hyphens and underscores\n";
149 Regex PrefixRE
= FC
.buildCheckPrefixRegex();
151 if (!PrefixRE
.isValid(REError
)) {
152 errs() << "Unable to combine check-prefix strings into a prefix regular "
153 "expression! This is likely a bug in FileCheck's verification of "
154 "the check-prefix strings. Regular expression parsing failed "
155 "with the following error: "
163 // Read the expected strings from the check file.
164 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> CheckFileOrErr
=
165 MemoryBuffer::getFileOrSTDIN(CheckFilename
);
166 if (std::error_code EC
= CheckFileOrErr
.getError()) {
167 errs() << "Could not open check file '" << CheckFilename
168 << "': " << EC
.message() << '\n';
171 MemoryBuffer
&CheckFile
= *CheckFileOrErr
.get();
173 SmallString
<4096> CheckFileBuffer
;
174 StringRef CheckFileText
= FC
.CanonicalizeFile(CheckFile
, CheckFileBuffer
);
176 SM
.AddNewSourceBuffer(MemoryBuffer::getMemBuffer(
177 CheckFileText
, CheckFile
.getBufferIdentifier()),
180 std::vector
<FileCheckString
> CheckStrings
;
181 if (FC
.ReadCheckFile(SM
, CheckFileText
, PrefixRE
, CheckStrings
))
184 // Open the file to check and add it to SourceMgr.
185 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> InputFileOrErr
=
186 MemoryBuffer::getFileOrSTDIN(InputFilename
);
187 if (std::error_code EC
= InputFileOrErr
.getError()) {
188 errs() << "Could not open input file '" << InputFilename
189 << "': " << EC
.message() << '\n';
192 MemoryBuffer
&InputFile
= *InputFileOrErr
.get();
194 if (InputFile
.getBufferSize() == 0 && !AllowEmptyInput
) {
195 errs() << "FileCheck error: '" << InputFilename
<< "' is empty.\n";
196 DumpCommandLine(argc
, argv
);
200 SmallString
<4096> InputFileBuffer
;
201 StringRef InputFileText
= FC
.CanonicalizeFile(InputFile
, InputFileBuffer
);
203 SM
.AddNewSourceBuffer(MemoryBuffer::getMemBuffer(
204 InputFileText
, InputFile
.getBufferIdentifier()),
208 FC
.CheckInput(SM
, InputFileText
, CheckStrings
) ? EXIT_SUCCESS
: 1;
209 if (ExitCode
== 1 && DumpInputOnFailure
)
210 errs() << "Full input was:\n<<<<<<\n" << InputFileText
<< "\n>>>>>>\n";