Skip to content

halcompile: warn about, and reject colliding, mangled HAL names - #4298

Open
tzuohann wants to merge 1 commit into
LinuxCNC:masterfrom
tzuohann:halcompile-halname-upstream
Open

halcompile: warn about, and reject colliding, mangled HAL names#4298
tzuohann wants to merge 1 commit into
LinuxCNC:masterfrom
tzuohann:halcompile-halname-upstream

Conversation

@tzuohann

@tzuohann tzuohann commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Problem

A name declared in a .comp file is a C identifier, but it is exported under a mangled HAL identifier: underscores become dashes, and a trailing dash or period is removed. This is documented — docs/src/hal/comp.adoc, HALNAME under Syntax — but nothing says so at the point of use:

pin in float my_input;      ->   component.N.my-input

halcompile compiles that without a word, and halcompile(1) has no naming section, so the author's first sign of it is a HAL file that does not work.

The same mangling has a sharper edge. check_name_ok() compares only declared names, so two declarations that mangle to one HAL name pass silently. x_y and x_y_ are exactly the two rows of the HALNAME table in comp.adoc that share a HAL identifier:

component collide;
pin in  float x_y;
pin out float x_y_;
$ halcompile --compile collide.comp
Compiling realtime collide.c
Linking collide.so                    # exit 0, no warning

$ halrun -f collide.hal
HAL: ERROR: duplicate variable 'collide.0.x-y'
collide: rtapi_app_main: Invalid argument (-22)
collide.hal:1: insmod for collide failed, returned -1

The failure names neither the .comp file, nor the line, nor the rule that caused it.

Change

  • check_hal_name() — a HAL-namespace counterpart to check_name_ok(). Two declarations that export the same HAL name are now an error at the offending line, instead of a loadrt failure later.

  • A once-per-file warning listing declared names whose HAL identifier differs, e.g.

    my_comp.comp:0: Warning: 3 declared name(s) are exported under a different HAL name:
    my_input -> my-input, my_output -> my-output, my_gain -> my-gain. Use the HAL name in
    HAL files, halcmd and halshow; see HALNAME under 'Syntax' in the Halcompile HAL
    Component Generator documentation, https://linuxcnc.org/docs/html/hal/comp.html
    

    Both messages point at the documentation that describes the mangling.

  • -N, --no-name-warnings suppresses that warning. src/hal/components/Submakefile passes it for in-tree components, whose HAL names are deliberate, so the build stays as quiet as it is today.

  • Docs: a NAMES section and the -N entry in halcompile.1.adoc; a note under the HALNAME table in comp.adoc.

Component names are left alone — loadrt my_comp keeps its underscores while its pins appear under my-comp.N., which the new NAMES section spells out but does not change.

Compatibility

The error only fires on a component that cannot load today, so no currently working .comp becomes unbuildable. All 133 in-tree .comp files preprocess with no new error; 74 of them would print the informational warning, which is why the in-tree rules pass -N and a full build gains no new output.

Testing

tests/halcompile/halname/ — two minimal components covering the warning, -N silencing it, and the rejected collision (error text, non-zero exit, no .c produced). tests/halcompile/names still passes unchanged.

Note

Companion PR for 2.9: #4299. It is the same change adapted to that branch's layout (troff halcompile.1 instead of the adoc, the --document rules, type/dir parameter names) — the branches are maintained separately, so neither supersedes the other.

🤖 Generated with Claude Code

A name declared in a .comp file is a C identifier, but it is exported
under a mangled HAL identifier: underscores become dashes and a trailing
dash or period is removed (comp.adoc, HALNAME). Nothing said so at
compile time, so "pin in float my_input" silently became
component.N.my-input.

Worse, check_name_ok() compares only declared names. Two declarations
that mangle to the same HAL name -- x_y and x_y_, the two rows of the
HALNAME table that share a HAL identifier -- therefore compiled cleanly
and failed much later, at load time:

    HAL: ERROR: duplicate variable 'collide.0.x-y'
    collide: rtapi_app_main: Invalid argument (-22)

Add check_hal_name(), which rejects that collision at the offending
line, and a once-per-file warning listing the names whose HAL identifier
differs from the declaration. Both messages point at the HALNAME
documentation. The warning is suppressed by -N (--no-name-warnings),
which the in-tree component rules pass, since those names are deliberate.

All 133 in-tree .comp files preprocess with no new error, and silently
under -N. tests/halcompile/halname covers the warning, -N, and the
rejected collision.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@BsAtHome

Copy link
Copy Markdown
Contributor

Name collisions are bad by default and fail to compile. Why is there an option for this? You should be able to check this much easier using a parallel name array for target names (which you apparently do) without complex regexes or lambdas by using a simple if name in array construct. Also note that functions have a different HAL namespace than pins/params.

Your second PR seems to be a duplicate and changes a generated (man) file that is not part of the repository. Why is this submitted twice?

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.

2 participants