Skip to content

Fix Partials merging adjacent #define macros when one has a comment with an apostrophe (#1262) - #1269

Merged
mkarlesky merged 2 commits into
next_versionfrom
fix/1262-partials-macro-newline
Sep 8, 2026
Merged

Fix Partials merging adjacent #define macros when one has a comment with an apostrophe (#1262)#1269
mkarlesky merged 2 commits into
next_versionfrom
fix/1262-partials-macro-newline

Conversation

@mkarlesky

Copy link
Copy Markdown
Member

Fixes #1262.

Root cause

_collect_directive (the #define/directive scanner in c_extractor_preprocessing.rb) scanned every " or ' character on a directive line as the start of a string/char literal — including one appearing inside a trailing // or /* */ comment. An ordinary English contraction in a macro's comment, e.g.:

#define START_ADDRESS 0x00 // don't change this
#define IDX_DATARATE (ADS124S08_REG_ADDR_DATARATE - START_ADDRESS)

opened what looked like an unterminated char literal at the apostrophe in "don't", sending skip_c_string hunting for a closing ' straight through this directive's own newline and into the following #define line(s) — silently merging them into a single macro_definitions entry with no separating newline.

Partials generation (generator_partials.rb) then faithfully wrote that already-corrupted, newline-less text back out, producing a generated ..._impl.h with two #define lines concatenated onto one physical line — a hard stray '#' in program compile error, exactly as reported.

Fix

Comment content (both // and /* */) is now captured verbatim without being scanned for string/char literal delimiters. A \ immediately before the newline inside a // comment still splices lines (matching how backslash-newline continuation already works everywhere else in a directive), so a multi-line macro whose continuation line happens to start with a comment still extracts correctly.

Diagnostic methodology

Per the repo maintainer's own investigation notes on the issue, this was diagnosed by first closing an existing unit-test coverage gap — no test anywhere asserted on the exact joined/assembled text of two-or-more consecutive same-kind Partials items (macros, typedefs, aggregates) — then using targeted, empirically-constructed repro tests against the real CExtractor to isolate the actual trigger, rather than assuming the originally-suspected mechanism (a collect_balanced comment-to-space collapse, which turned out not to be reachable from macro scanning at all).

Tests

  • spec/units/c_extractor/c_extractor_preprocessing_spec.rb: new #try_extract_directive cases for a trailing ////* */ comment containing an apostrophe or quote, and for backslash-continuation across a comment line — verified failing against pre-fix code, passing after.
  • spec/units/c_extractor/c_extractor_integration_spec.rb: new adjacency-reconstruction tests (element_sequence joined by \n) for plain adjacent macros and for the exact reported comment-with-apostrophe shape.
  • spec/units/generators/generator_partials_spec.rb: new byte-exact adjacency tests for consecutive macros (generate_header's previously-uncovered inline CStatement path), consecutive typedefs, and consecutive aggregate definitions via generate_types — closing the coverage gap for kinds beyond variables/functions, which already had this coverage.

Unit tests only, per the maintainer's own scoping for this fix — no system tests. Full bundle exec rake specs:units run clean (3215 examples, 0 failures) on host.

🤖 Generated with Claude Code

…ith an apostrophe

_collect_directive scanned every '"' or "'" on a directive line as the start
of a string/char literal, including inside a trailing // or /* */ comment.
An ordinary contraction like "don't" in a macro's comment opened what looked
like an unterminated char literal, sending skip_c_string hunting for a
closing match straight through the directive's own newline and into
whatever followed -- silently merging the next #define(s) into one
macro_definitions entry with no separating newline between them.

Partials generation faithfully wrote that corrupted, newline-less text back
out, producing a generated ..._impl.h with two #define lines concatenated
onto one physical line -- a hard "stray '#' in program" compile error
(GH #1262).

Comment content (both // and /* */) is now captured verbatim without being
scanned for literal delimiters. A '\' immediately before the newline inside
a // comment still splices lines, matching how backslash-newline
continuation already works everywhere else in a directive.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
[skip ci]

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@mkarlesky
mkarlesky merged commit ab20703 into next_version Sep 8, 2026
@mkarlesky
mkarlesky deleted the fix/1262-partials-macro-newline branch September 8, 2026 20:41
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