LinuxCommandLibrary

filecheck

Analyze file types and their structure

TLDR

Match input_file content with pattern file check_file

$ FileCheck --input-file=[path/to/input_file] [path/to/check_file]
copy

Match input from the stdin with pattern file check_file
$ echo "[some_text]" | FileCheck [path/to/check_file]
copy

Match with the specified custom check prefix (Note: The default prefix is CHECK)
$ echo "[some_text]" | FileCheck --check-prefix=[prefix] [path/to/check_file]
copy

Print good directive pattern matches
$ echo "[some_text]" | FileCheck -v [path/to/check_file]
copy

Input llvm_code.ll into llvm-as, then pipe the output into FileCheck to match
$ llvm-as [path/to/llvm_code.ll] | FileCheck [path/to/check_file]
copy

SYNOPSIS

filecheck [options] check-file [input-file]
filecheck [options] --input-file=input-file check-file

PARAMETERS

--help
    Display available options and usage information.

--version
    Display the version of the program.

--check-prefix=
    Specifies a prefix to use for CHECK: directives. Can be specified multiple times to define multiple prefix sets (e.g., CHECK, FOO).

--input-file=
    Specifies the input file to check. If not specified, filecheck reads from standard input.

--allow-empty
    Do not fail if the check-file contains no CHECK: directives.

--strict-whitespace
    Require exact whitespace match for CHECK: patterns. By default, multiple spaces or tabs in a pattern can match any sequence of whitespace.

--implicit-check-not=
    Add an implicit CHECK-NOT: for the given pattern. This pattern will be checked between every successful CHECK match.

--enable-var-parsing
    Enable parsing of [[VAR]] and {{EXPR}} syntax for capturing parts of matches into variables and performing simple expressions.

--enable-eval-parsing
    Enable parsing of {{EXPR}} syntax for expressions. This is often implied by --enable-var-parsing.

--match-full-lines
    Require CHECK patterns to match entire input lines, not just substrings.

--dump-input
    Dump the input file to standard error before checking begins, useful for debugging.

--dump-check-lines
    Dump the parsed CHECK lines to standard error before checking, useful for debugging.

--verbose
    Print verbose output, including matched lines and successful checks.

--color
    Use colored output for matches and failures, if the terminal supports it.

--fix-misexpectations
    Update the check-file in place with suggested CHECK: patterns based on the current input. Use with caution as it modifies files.

--ignore-case
    Perform case-insensitive matching for all patterns.

DESCRIPTION

filecheck is a powerful command-line utility, primarily used in automated testing, especially within the LLVM project. It verifies if an input file (e.g., compiler output, disassembled code) matches specific patterns defined in a "check file" (often the test source itself). The tool reads the check file line by line, looking for CHECK: directives. These directives specify patterns that must be found in the input file, in a specific order or context.

filecheck supports various directives like CHECK-NEXT: for sequential matches, CHECK-NOT: for absence of patterns, CHECK-SAME: for continuation on the same line, CHECK-DAG: for unordered matches within a block, and CHECK-LABEL: for matching and anchoring in functions or labels. Its robust pattern matching capabilities, including basic regular expressions and variable substitution, make it indispensable for verifying complex compiler optimizations, code generation, and language feature implementations in large test suites.

CAVEATS

filecheck is very particular about whitespace; by default, it compresses sequences of whitespace. Use --strict-whitespace for exact matches.

Debugging failing filecheck tests can be challenging due to its sequential matching and the nature of CHECK-NOT: failures, which often occur unexpectedly.

It is primarily designed for automated test verification in compiler and toolchain development, not as a general-purpose text processing utility like grep or sed. Its regular expression support is basic, and complex regex might require pre-processing the input.

CHECK DIRECTIVES EXPLAINED

The core functionality of filecheck revolves around its directives, placed in the check-file:

  • CHECK: pattern
    Matches the pattern anywhere in the input stream, advancing the internal cursor past the matched line.
  • CHECK-NEXT: pattern
    Matches the pattern on the line immediately following the last successful CHECK match.
  • CHECK-SAME: pattern
    Matches the pattern on the same line as the last successful CHECK match. Useful for multiple checks on a single line.
  • CHECK-NOT: pattern
    Ensures that the pattern does NOT appear on any line between the current input cursor position and the next successful CHECK (or the end of the input).
  • CHECK-DAG: pattern
    Matches pattern anywhere in the input stream, but does not advance the cursor. Multiple CHECK-DAG patterns can match in any order within a block, useful for non-deterministic output order.
  • CHECK-LABEL: pattern
    Matches pattern and anchors the search context to the line it matches. This is typically used to define logical blocks (e.g., function definitions) within which subsequent checks operate.
  • CHECK-EMPTY:
    Matches an empty line.
  • [[VAR]] and {{EXPR}}
    When --enable-var-parsing is active, [[VAR:regex]] captures a regular expression match into a variable VAR, and {{EXPR}} allows using arithmetic or string expressions with these variables in subsequent patterns.

TYPICAL USAGE

filecheck is most commonly used in conjunction with test runners like LLVM's lit (LLVM Integrated Tester). A typical test file might contain source code, compiler flags, and the CHECK: directives embedded as comments. The test runner compiles or processes the source code, redirects its output to filecheck, and then filecheck verifies the output against the embedded directives. This approach allows for self-contained, easily verifiable tests where the expected output patterns are part of the test source itself, simplifying maintenance and understanding.

HISTORY

filecheck was developed as an integral part of the LLVM project's testing infrastructure. Its creation was driven by the need for a robust and flexible way to verify complex compiler outputs, where traditional diffing or simple grep commands were insufficient due to variations in whitespace, register allocation, or instruction ordering. It became the de-facto standard for validating code generation and optimization passes within LLVM test suites, allowing developers to write self-contained tests where the expected output patterns are embedded directly within the source code of the test itself.

SEE ALSO

grep(1), awk(1), sed(1), diff(1)

Copied to clipboard