Add %{field} escape to -printf / -printfln / -fprintf / -fprintfln - #234
Merged
Conversation
-printf's format is a % directive language and treats a bare `{...}` literally
(printf formats legitimately contain braces, e.g. JSON), so the rich brace field
vocabulary was unreachable from these per-branch actions (unlike the whole-run
--format global). Bridge it with an xff `%{NAME}` / `%{NAME:qualifier}` escape,
rendered by the same fields::Template engine as --format: %{relpath}, %{core},
%{suffix}, %{target}, %{def.NAME}, %{env.NAME}, %{size:h}, time qualifiers, the
s/// rewrite, etc.
Rules: %% stays a literal percent; a bare `{...}` stays literal (find-compat, no
breakage); an unterminated `%{` is emitted literally, matching the field template's
own lenient handling. The escape is an xff extension in otherwise find-native
actions, so EnforceStyle rejects a %{...} format under --config=find (plain %
formats stay fine); -printfln / -fprintfln are xff already. The symlink read that
backs %{target} is skipped unless the format actually uses %{.
FormatPrintf now takes the EvalContext (for captures/defines/env/target), like
RenderExecArgv. Self-doc: -printf summary notes the escape; --help / --man /
--markdown regenerate from the registry. Tests: run_test pins the escape rules
(expand, %%, bare-literal, unterminated); parser_test pins the strict-find
rejection; an xff_golden case pins the find(reject)-vs-xff(expand) divergence.
helly25
enabled auto-merge (squash)
July 3, 2026 23:42
helly25
added a commit
that referenced
this pull request
Jul 5, 2026
Re-pins the mbo git_override to the main commit merging helly25/mbo#234 (which added the empty-time_format git-style header and ignore_missing_final_newline), and wires the two xff-side bits: - -diff now sets time_format="" so the unified/context header omits the per-file mtime (`--- a/one.txt`), making the output reproducible. The diff golden tests drop the mtime-strip sed (normalize) and the fixture drops its `touch` - the git-style header is verbatim, so the committed goldens match directly. - --diff-ignore gains an `eofnl` token (-> mbo ignore_missing_final_newline): a file with and one without a final newline compare equal. No `lead`/`eol` token - leading whitespace is subsumed by `change`/`ws`, and CRLF-vs-LF by `trail` (a `\r` is trailing whitespace). Tests: run_test + diff_test.sh gain eofnl cases (equal with the token, differ without); the diff goldens pass with no normalization. `bazel test //xff/...` green (66 tests).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
-printf's format is a%-directive language and treats a bare{...}literally (printf formats legitimately contain braces, e.g. JSON), so the rich brace field vocabulary was unreachable from these per-branch actions - unlike the whole-run--formatglobal. This bridges the gap with an xff%{NAME}/%{NAME:qualifier}escape.%{...}renders through the samefields::Templateengine as--formatbraces, so the full vocabulary comes along:%{relpath},%{core},%{suffix},%{target},%{def.NAME},%{env.NAME},%{capture.N}, time qualifiers, thes/PAT/REPL/rewrite, path-component qualifiers - all work.Rules
%%stays a literal percent; a bare{...}stays literal (find-compat, no breakage); an unterminated%{is emitted literally, matching the field template's own lenient handling.EnforceStylerejects a%{...}format under--config=find(a plain%pformat stays fine).-printfln/-fprintflnare xff already.%{target}is skipped unless the format actually uses%{.FormatPrintfnow takes theEvalContext(for captures/defines/env/target), likeRenderExecArgv.Self-doc + tests:
-printfsummary notes the escape;--help/--man/--markdownregenerate from the registry.run_testpins the escape rules (expand /%%/ bare-literal / unterminated);parser_testpins the strict-find rejection; a dogfoodxff_goldencase pins the find(reject)-vs-xff(expand) divergence. Fullbazel test //xff/...green (49); both clang-format versions + buildifier + pre-commit clean.