Skip to content

Fix header_consumers.py silently blanking 79% of a file when a string contains "//" - #1153

Merged
aurelienpierre merged 1 commit into
masterfrom
fix/header-consumers-scanner
Aug 15, 2026
Merged

Fix header_consumers.py silently blanking 79% of a file when a string contains "//"#1153
aurelienpierre merged 1 commit into
masterfrom
fix/header-consumers-scanner

Conversation

@aurelienpierre

Copy link
Copy Markdown
Collaborator

strip_noise() applied three regexes in sequence — block comments, then line comments, then string literals. No ordering of three independent substitutions can be correct here, because each construct may contain the others' delimiters.

Comments-first — what it did — blanks from the // of a URL to the end of the line, taking the string's closing quote with it. The surviving opening quote then pairs with the next quote further down the file, and STRING_LIT replaces everything between with "".

Measured on src/gui/actions/help.c: 7550 of 9491 characters gone (79%), and its three dt_control_log() calls with them. 129 files in this tree contain // inside a string literal, including src/darktable.h and src/views/darkroom.c.

Strings-first fails symmetrically: an unbalanced " inside a comment starts a literal that eats real code. So this is a scanner, not a reordering.

Why this bucket is the dangerous one

CLAUDE.md is explicit that "files using nothing from it" does not mean the include can be dropped — those files reach the symbols through some other include and, under this tree's rule, need the include added explicitly. A false entry there invites deleting an include the file genuinely needs — precisely the failure that broke build-nofeatures when colorprofiles/colorspaces.h was split.

Two false entries were being reported:

header falsely "uses nothing" what it actually calls
control/control.h src/gui/actions/help.c dt_control_log ×3
gui/application.h src/gui/privacy_consent.c dt_gui_get_global, dt_gui_get_ui, dt_gui_main_window

Both hidden by a URL in a string literal.

The fix

One pass that tracks which construct it is inside. Newlines preserved, so line numbers stay meaningful.

Verified on eight adversarial inputs, each of which must keep the code after it and drop the noise: URL in a string, a quote inside a line comment, // and a quote inside a block comment, an escaped quote, a quoted apostrophe in a char literal, an apostrophe in a comment, an unterminated string, and /* inside a string. All eight pass — before the fix, the first alone swallowed the rest of the file.

Before/after on real headers (buggy → fixed count of the "using nothing" bucket): control/control.h 1 → 0, gui/application.h 1 → 0, and control/signal.h 7 → 7, develop/imageop.h 4 → 4, common/image.h 1 → 1 unchanged — the genuine ones stay put.

Found while acting on doc/control-split.md (#1152), whose PR1 depends on this tool telling the truth about control.h's 125 includers.

🤖 Generated with Claude Code

… contains "//"

strip_noise() applied three regexes in sequence: block comments, then line comments, then
string literals. No ordering of three independent substitutions can be correct here, because
each construct may contain the others' delimiters.

Comments-first -- what it did -- blanks from the `//` of a URL to the end of the line, taking
the string's closing quote with it. The surviving opening quote then pairs with the next quote
further down the file, and STRING_LIT replaces everything between them with "". Measured on
src/gui/actions/help.c: 7550 of 9491 characters gone, and its three dt_control_log() calls with
them. 129 files in this tree contain `//` inside a string literal, including src/darktable.h and
src/views/darkroom.c.

Strings-first fails symmetrically: an unbalanced `"` inside a comment starts a literal that eats
real code.

The damage lands in the worst possible bucket. CLAUDE.md documents that "files using nothing
from it" does NOT mean the include can be dropped -- those files reach the symbols through some
other include and, under this tree's rule, need the include added EXPLICITLY. A FALSE entry
there invites deleting an include the file genuinely needs, which is exactly the failure that
broke build-nofeatures when colorprofiles/colorspaces.h was split. Two false entries were being
reported: src/gui/actions/help.c against control/control.h (it calls dt_control_log three
times), and src/gui/privacy_consent.c against gui/application.h (dt_gui_get_global,
dt_gui_get_ui, dt_gui_main_window).

Replaced with a single pass that tracks which construct it is inside. Newlines are preserved so
line numbers stay meaningful. Verified on eight adversarial inputs -- URL in a string, a quote
inside a line comment, `//` and a quote inside a block comment, an escaped quote, a quoted
apostrophe in a char literal, an apostrophe in a comment, an unterminated string, and `/*`
inside a string -- each of which must keep the code after it and drop the noise. All eight pass;
before the fix the first one alone swallowed the rest of the file.

Found while acting on doc/control-split.md, whose PR1 depends on this tool telling the truth
about control.h's 125 includers.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@sonarqubecloud

Copy link
Copy Markdown

@aurelienpierre
aurelienpierre merged commit 4b7c3f7 into master Aug 15, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

1 participant