Skip to content

Fix parser bugs: colon truncation, file:line:error support, Tectonic filenames - #32

Open
dpezto wants to merge 1 commit into
stefanhepp:masterfrom
dpezto:upstream-parser-fixes
Open

Fix parser bugs: colon truncation, file:line:error support, Tectonic filenames#32
dpezto wants to merge 1 commit into
stefanhepp:masterfrom
dpezto:upstream-parser-fixes

Conversation

@dpezto

@dpezto dpezto commented Jul 30, 2026

Copy link
Copy Markdown

Five parser fixes, plus a fixture runner so the behavior changes are reviewable rather than asserted. Fixes #2, fixes #21, supersedes #18 and #19.

Test harness first. test/run.sh feeds each test/*.log through pplatex and diffs against test/expected/<name>.txt (--update regenerates). The expected files are committed, so each fix shows up as a reviewable diff. Four fixtures added for cases nothing covered.

1. Errors and warnings lost text after their first colon. Both patterns read .*:(.*) and the greedy .* runs to the last colon. Undefined-reference warnings and package errors quoting a filename or key always contain a second colon:

before:  intro' on page 1 undefined on input line 15.
after:   Reference `sec:intro' on page 1 undefined on input line 15.

Same fix as #19, extended to the error pattern, with the space after the colon optional so an empty message is not dropped.

2. file:line:error logs parsed as nothing (#2, open since 2013). With -file-line-error, errors read ./min.tex:3: Undefined control sequence. and no pattern matched; test/min.log reported zero errors. The new detector takes file and line straight off the line and emits immediately, since this format never prints the l.<n> the normal path waits for.

3. Errors from Tectonic had no filename (#21). The paren heuristic pushes a filename only once it is fairly sure it has one, but pops on every ). A ( that fails to push is still popped, so the stack drains — in the log from #21 the source file is discarded 21 lines in, after which every error reports no file. The trigger is several opens on one line:

) (tikz.sty (pgf.sty (pgfrcs.sty (pgfutil-common.tex

Only the last is pushed; the rest are followed by a space and fall through to fileExists(), which fails for distribution files that don't sit next to the document. pdflatex mostly escapes this by wrapping at 79 columns so names land at end-of-line. A candidate with a short alphanumeric extension is now accepted when it can't be confirmed on disk; prose like size option is still rejected. This also covers #18's page-marker case (./chapter.tex [12] [13] glued into the filename), verified by test/pagemarkers.log.

4. Filler leaked into messages. addMessage() compares lines against literals, but lines keep their trailing spaces (their untrimmed length is how wrapped words are detected), so the ... marker padded to the log width never equalled "...". The comparison is now right-trimmed.

5. Multi-line warnings never got a line number. The Warning-state branch passed an always-empty local to the line-number scan. It now scans the continuation line itself. This exposed a second bug in the wrapped-line fallback (.*)([0-9]+)\.$: the greedy group eats into the number, reporting Line 3 for a line wrapped as ...on input lin / e 13..

The existing fixtures change only in the intended ways: messages keep their text past a colon, ... filler disappears, and eight warning headers gain , Line N — each N cross-checked against the number stated in its own message text.

Independent of #30: this branch builds against PCRE1 as-is.

Five parser fixes, plus a fixture runner so behavior changes are reviewable.

test/run.sh feeds each test/*.log through pplatex and diffs against
test/expected/<name>.txt; --update regenerates them. Four fixtures are added
for cases nothing previously covered.

1. Errors and warnings lost text after their first colon. Both patterns read
   ".*:(.*)", and the greedy .* runs to the last colon on the line. Undefined
   reference warnings and package errors quoting a filename or key always
   contain a second colon and were consistently mangled:

       before:  intro' on page 1 undefined on input line 15.
       after:   Reference `sec:intro' on page 1 undefined on input line 15.

   Same as PR stefanhepp#19, extended to the error pattern, with the space after the
   colon optional so an empty message is not dropped.

2. file:line:error style logs parsed as nothing (issue #2). With
   -file-line-error, errors read "./min.tex:3: Undefined control sequence."
   and no pattern matched that shape; test/min.log reported zero errors. The
   new detector takes file and line straight off the line and emits the item
   immediately, since this format never prints the "l.<n>" the normal path
   waits for.

3. Errors from Tectonic had no filename (issue stefanhepp#21). The parenthesis heuristic
   pushes a filename only once it is fairly sure it has one, but pops on every
   ')'. A '(' that fails to push is still popped, so the stack drains; in the
   log from stefanhepp#21 the source file is discarded 21 lines in, and every error is
   then reported with no file. The trigger is several opens on one line:

       ) (tikz.sty (pgf.sty (pgfrcs.sty (pgfutil-common.tex

   Only the last is pushed; the others are followed by a space and fall
   through to fileExists(), which fails for distribution files. pdflatex
   mostly escapes this by wrapping at 79 columns. A candidate with a short
   alphanumeric extension is now accepted when it cannot be confirmed on disk.
   This also covers PR stefanhepp#18's case of page markers glued onto a filename,
   verified by test/pagemarkers.log.

4. Filler inside error contexts leaked through. addMessage() compares a line
   against literals, but lines keep trailing spaces (their untrimmed length is
   what detects wrapped words), so the "..." marker padded to the log width
   was never equal to "...". The comparison is now right-trimmed.

5. Multi-line warnings never got a line number: the Warning-state branch
   passed an always-empty local to the line-number scan. It now scans the
   continuation line itself. This exposed a second bug in the wrapped-line
   fallback "(.*)([0-9]+)\.$": the greedy group eats into the number,
   reporting Line 3 for a line wrapped as "...on input lin" / "e 13.". The
   first group must now end on a non-digit.

The existing pdflatex fixtures change only in the intended ways: messages keep
their text past a colon, "..." filler disappears, and eight warning headers
gain ", Line N", each N matching the number stated in its own message text.
Copilot AI review requested due to automatic review settings July 30, 2026 06:11

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants