Skip to content

String literals: a raw CR is a line ending, not content - #174

Merged
revarbat merged 1 commit into
mainfrom
fix/string-literal-raw-cr
Sep 11, 2026
Merged

revarbat merged 1 commit into
mainfrom
fix/string-literal-raw-cr

Conversation

@revarbat

Copy link
Copy Markdown
Member

Reported as BelfrySCAD#404 — string continuation retaining newlines. The newline half was already fixed in #150; this is the CR that was left behind.

The remaining bug

A string wrapped across two source lines drops the newline and keeps the next line's indentation. A \ continuation over CRLF already took the whole line ending. A bare continuation in a CRLF file was the one path still keeping the CR, so the same source had different content depending on which machine saved it:

echo(len("ab⏎cd")); LF file CRLF file
before 4 5
after 4 4

The stray CR is invisible in every echo and every exported label, which is what makes it worth fixing rather than documenting.

Why diverge from the reference

This is the reference's behaviour — its lexer's <cond_string> \n rule only advances the line counter, so the CR falls through to . and is appended — but it isn't behaviour worth reproducing. A raw CR in source is a line ending in every real file (CRLF on Windows, a lone CR on a pre-OSX Mac), and a script that wants a real CR writes \r, which still works. Upstream reached the same conclusion for the \-continuation case in openscad/openscad@dabdc41d6 ("Fix string line continuation regression", 2026-08-10).

The change

unescapeStringLiteral drops CR wherever it already dropped LF. That also collapses the backslash-before-CRLF special case into the ordinary one, since a trailing LF is now dropped by the loop itself — net -4 lines.

Verification

  • StringEscapes.* extended: ARawCarriageReturnStandsForItself becomes ARawCarriageReturnIsALineEndingToo, covering CRLF, lone CR, kept indentation, and \r still producing a real CR.
  • Full C++ suite: 1257 passed.
  • tests/test_python_bindings.py: 42 passed.
  • End to end on real CRLF and LF files through the CLI: both now echo 4/4, previously 5/4.

🤖 Generated with Claude Code

https://claude.ai/code/session_01JFTVMTH6yEktHDPF5csksb

A string wrapped across two source lines drops the newline and keeps the
next line's indentation -- already the case, and already true of a `\`
continuation over CRLF. A *bare* continuation in a CRLF file was the one
path left keeping the CR, so the same string had different content
depending on which machine saved the file:

    echo(len("ab      <- LF file: 4, CRLF file: 5
    cd"));

That is the reference's behaviour (its lexer's `\n` rule drops only the
LF; the CR falls through to `.` and is appended), but it is not a
behaviour worth reproducing: a raw CR in source is a line ending in every
real file -- CRLF on Windows, a lone CR on a pre-OSX Mac -- and a script
that wants a real CR writes `\r`. Upstream came to the same conclusion
for the `\`-continuation case in openscad/openscad@dabdc41d6.

So `unescapeStringLiteral` now drops CR wherever it already dropped LF,
which also collapses the backslash-before-CRLF special case into the
ordinary one. Net -4 lines.

BelfrySCAD#404.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JFTVMTH6yEktHDPF5csksb
@revarbat
revarbat merged commit c1dd5ae into main Sep 11, 2026
3 checks passed
@revarbat
revarbat deleted the fix/string-literal-raw-cr branch September 11, 2026 16:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant