Skip to content

Commit

Permalink
Add support for --dump-input flag (fixes #19) (#36)
Browse files Browse the repository at this point in the history
This adds support for the `--dump-input` flag, but currently only
supports two out of the four values implemented upstream:

- 🟢 `never`: Don't print anything
- 🟢 `fail`: Print diagnostics on failure
- 🔴 `always`: Always print something
- 🔴 `help`: Print help text fur `--dump-input`
  • Loading branch information
AntonLydike committed Sep 7, 2024
1 parent 55c6af1 commit e3c2ef6
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 21 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Here's an overview of all FileCheck features and their implementation status.
- [X] `--strict-whitespace` (Bug: [#6](https://github.com/AntonLydike/filecheck/issues/6))
- [ ] `--ignore-case`
- [ ] `--implicit-check-not` (Tracked: [#20](https://github.com/AntonLydike/filecheck/issues/20))
- [ ] `--dump-input` (Tracked: [#19](https://github.com/AntonLydike/filecheck/issues/19))
- [X] `--dump-input` (only `fail` and `never` supported)
- [ ] `--dump-input-context`
- [ ] `--dump-input-filter`
- [X] `--enable-var-scope`
Expand Down
5 changes: 5 additions & 0 deletions filecheck/help.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
match.
--match-full-lines : Expect every check line to match the whole line.
--reject-empty-vars : Raise an error when a value captures an empty string.
--dump-input : Dump the input to stderr annotated with helpful
information depending on the context. Allowed values
are help, always, never, fail. Default is fail.
Only fail and never is currently supported in this
version of filecheck.
ARGUMENTS:
check-file : The file from which the check lines are to be read
Expand Down
48 changes: 30 additions & 18 deletions filecheck/matcher.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import re
import os
import sys
from collections.abc import Sequence
from dataclasses import dataclass, field
from typing import Callable
from typing import Callable, TextIO

from filecheck.compiler import compile_uops
from filecheck.error import CheckError, ParseError, ErrorOnMatch
from filecheck.finput import FInput, InputRange
from filecheck.logging import warn
from filecheck.colors import ERR, FMT
from filecheck.ops import CheckOp, CountOp, Literal, Subst, UOp, RE, Capture
from filecheck.options import Options
from filecheck.options import Options, DumpInputKind
from filecheck.parser import Parser
from filecheck.preprocess import Preprocessor

Expand Down Expand Up @@ -45,6 +46,8 @@ class Matcher:

ctx: Context = field(default_factory=Context)

stderr: TextIO = field(init=False)

@classmethod
def from_opts(cls, opts: Options):
"""
Expand All @@ -56,6 +59,15 @@ def from_opts(cls, opts: Options):

def __post_init__(self):
self.ctx.live_variables.update(self.opts.variables)
if self.opts.dump_input == DumpInputKind.NEVER:
self.stderr = open(os.devnull, "w")
else:
self.stderr = sys.stderr
if self.opts.dump_input in (DumpInputKind.ALWAYS, DumpInputKind.HELP):
warn(
f"Unsupported dump-input flag: {self.opts.dump_input.name.lower()}",
opts=self.opts,
)

def run(self) -> int:
"""
Expand All @@ -67,7 +79,7 @@ def run(self) -> int:
if self.file.content in ("", "\n"):
print(
f"{ERR}filecheck error:{FMT.RESET} '{self.opts.readable_input_file()}' is empty.",
file=sys.stderr,
file=self.stderr,
)
return 1

Expand All @@ -81,16 +93,16 @@ def run(self) -> int:
pref = f"prefixes {', '.join(self.opts.check_prefixes)}"
print(
f"{ERR}filecheck error:{FMT.RESET} No check strings found with {pref}:",
file=sys.stderr,
file=self.stderr,
)
return 2
except ParseError as ex:
print(
f"{self.opts.match_filename}:{ex.line_no}:{ex.offset} {ex.message}",
file=sys.stderr,
file=self.stderr,
)
print(ex.offending_line.rstrip("\n"), file=sys.stderr)
print(" " * (ex.offset - 1) + "^", file=sys.stderr)
print(ex.offending_line.rstrip("\n"), file=self.stderr)
print(" " * (ex.offset - 1) + "^", file=self.stderr)
return 1

function_table: dict[str, Callable[[CheckOp], None]] = {
Expand Down Expand Up @@ -122,40 +134,40 @@ def run(self) -> int:
except CheckError as ex:
print(
f"{self.opts.match_filename}:{ex.op.source_line}: {ERR}error:{FMT.RESET} {ex.message}",
file=sys.stderr,
file=self.stderr,
)
print("Current position at " + self.file.print_line(), file=sys.stderr)
print("Current position at " + self.file.print_line(), file=self.stderr)

if self.file.is_discontigous():
print(
"\nCurrently matching in range (grey is already matched):",
file=sys.stderr,
file=self.stderr,
)
print("".join(self.file.print_current_range()), file=sys.stderr)
print("".join(self.file.print_current_range()), file=self.stderr)

# try to look for a shorter match, and print that if possible
prefix_match = self.find_prefix_match_for(ex.op)
if prefix_match is not None:
print("Possible intended match at:", file=sys.stderr)
print(self.file.print_line(prefix_match.start(0)), file=sys.stderr)
print("Possible intended match at:", file=self.stderr)
print(self.file.print_line(prefix_match.start(0)), file=self.stderr)

return 1
except ErrorOnMatch as ex:
print(
f"{self.opts.match_filename}:{ex.op.source_line}: {ERR}error:{FMT.RESET} {ex.message}",
file=sys.stderr,
file=self.stderr,
)
print("Matching at: ", end="", file=sys.stderr)
print("Matching at: ", end="", file=self.stderr)
print(
self.file.print_line(ex.match.start(0), ex.match.end(0)),
file=sys.stderr,
file=self.stderr,
)
if self.file.is_discontigous():
print(
"\nCurrently matching in range (grey is already matched):",
file=sys.stderr,
file=self.stderr,
)
print("".join(self.file.print_current_range()), file=sys.stderr)
print("".join(self.file.print_current_range()), file=self.stderr)
return 1

return 0
Expand Down
20 changes: 18 additions & 2 deletions filecheck/options.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from dataclasses import dataclass, field
from enum import Enum
from enum import Enum, auto
from typing import Iterable
import os

Expand All @@ -8,6 +8,13 @@ class Extension(Enum):
MLIR_REGEX_CLS = "MLIR_REGEX_CLS"


class DumpInputKind(Enum):
HELP = auto()
ALWAYS = auto()
NEVER = auto()
FAIL = auto()


@dataclass
class Options:
match_filename: str
Expand All @@ -19,6 +26,7 @@ class Options:
match_full_lines: bool = False
allow_empty: bool = False
reject_empty_vars: bool = False
dump_input: DumpInputKind = DumpInputKind.FAIL
variables: dict[str, str | int] = field(default_factory=dict)

extensions: set[Extension] = field(default_factory=set)
Expand All @@ -32,7 +40,7 @@ def __post_init__(self):
extensions: set[Extension] = set()
for ext in self.extensions:
if isinstance(ext, str):
if ext in set(e.name for e in Extension):
if ext in set(e.value for e in Extension):
extensions.add(
Extension[ext] # pyright: ignore[reportArgumentType]
)
Expand All @@ -43,6 +51,14 @@ def __post_init__(self):
else:
extensions.add(ext)
self.extensions = extensions
if isinstance(self.dump_input, str):
name: str = self.dump_input.upper()
if name in set(d.name for d in DumpInputKind):
self.dump_input = DumpInputKind[name]
else:
raise RuntimeError(
f'Unknown value supplied for dump-input flag: "{name}"'
)

def readable_input_file(self):
if self.input_file == "-":
Expand Down
12 changes: 12 additions & 0 deletions tests/filecheck/flags/dump-input.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// RUN: strip-comments.sh %s | filecheck %s --dump-input never --check-prefix RIGHT | filecheck %s --allow-empty --check-prefix EMPTY
// RUN: strip-comments.sh %s | exfail filecheck %s --dump-input never --check-prefix WRONG | filecheck %s --allow-empty --check-prefix EMPTY
// RUN: strip-comments.sh %s | filecheck %s --dump-input fail --check-prefix RIGHT | filecheck %s --allow-empty --check-prefix EMPTY
// RUN: strip-comments.sh %s | exfail filecheck %s --dump-input fail --check-prefix WRONG | filecheck %s --allow-empty --check-prefix HAS-OUTPUT
// RUN: strip-comments.sh %s | filecheck %s --dump-input help --check-prefix RIGHT 2>&1 | filecheck %s --allow-empty --check-prefix UNKNOWN-FLAG -DFLAG=help
// RUN: strip-comments.sh %s | filecheck %s --dump-input always --check-prefix RIGHT 2>&1 | filecheck %s --allow-empty --check-prefix UNKNOWN-FLAG -DFLAG=always
test
// RIGHT: test
// WRONG: wrong
// EMPTY-NOT: {{.+}}
// HAS-OUTPUT: error: Couldn't match "wrong".
// UNKNOWN-FLAG: Warning: Unsupported dump-input flag: [[FLAG]]

0 comments on commit e3c2ef6

Please sign in to comment.