Skip to content

hal: Add halfileupdate to convert HAL configuration files - #4499

Draft
grandixximo wants to merge 1 commit into
LinuxCNC:masterfrom
grandixximo:halfileupdate
Draft

hal: Add halfileupdate to convert HAL configuration files#4499
grandixximo wants to merge 1 commit into
LinuxCNC:masterfrom
grandixximo:halfileupdate

Conversation

@grandixximo

@grandixximo grandixximo commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

@BsAtHome This is the .hal side of what we discussed in #4256, as a separate binary: halfileupdate.

It should be safe because it does not match strings. It reads the loadrt lines, works out which instances exist, and converts only names that resolve to one of those instances. count=, names= (the instance name is the user's, only the loadrt line changes) and components whose HAL prefix is not the module name, mux-gen and friends, all fall out of that instead of being special cases. Anything that does not resolve is left alone and reported.

Given an INI file it walks the [HAL] files in the order LinuxCNC runs them and follows source, which is the part that matters in practice: in stock configs the loadrt and the pins that use it are regularly in different files, sim_vmc.hal loads conv_float_s32 count=3 and toolchange_gray.hal uses conv-float-s32.2.in. It also picks up HAL files behind a GUI's own key such as CUSTOM_HALFILE, and rewrites HALCMD lines in the INI itself. On a single .hal file it converts what that file loads and says to run the INI for the rest.

Signals, aliases and comments are never rewritten, though a comment still naming something that changed is reported. Names built with a substitution or in a haltcl loop are reported rather than guessed at. Library files are skipped. Diff by default, -i keeps a .bak.

Per your last comment: no table in hal_lib, no hooks on the halcmd error paths, no CI mode. The renames are plain tables in the tool, taken from your wip_hal-types-and-isolation branch: the eleven conv_* converters, the mux_generic and demux_generic pins, demux sel-u32 and the reset pins. The four converters whose two sides collapse to one type, conv_s32_s64 and friends, are gone with no replacement there, so their uses are reported instead of rewritten. I left abs_s32, scaled_s32_sums and the tristate pair alone since you have not renamed them; if that changes the tables get regenerated.

I have not written a removal release into it, since 2.12 or 3.0 is not settled; it needs remembering at some point.

Testing: all 326 stock config INI files dry-run clean, 65 lines changed, no false positives. The test asserts that the old names are gone and that the replacements are consistent, not how they are spelled, so regenerating the tables will not invalidate it.

@grandixximo
grandixximo force-pushed the halfileupdate branch 3 times, most recently from d8e1890 to 3d52570 Compare September 4, 2026 08:06
@BsAtHome

BsAtHome commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

The four converters whose two sides collapse to one type, conv_s32_s64 and friends, are gone with no replacement there, so their uses are reported instead of rewritten.

That is good. Both conv_s32_s64, conv_s64_s32, conv_u32_u64 and conv_u64_u32 are superfluous now.

I left abs_s32, scaled_s32_sums and the tristate pair alone since you have not renamed them; if that changes the tables get regenerated.

I'm still working on them. The abs_s32 and abs_s64 will collapse into abs_sint. Anything else I find will also need to be added.

Also working on changing the components to replace si32/ui32 with sint/uint where ever possible.

Comment thread src/hal/utils/halfileupdate.py Outdated
Comment on lines +742 to +748
tcl = path.endswith('.tcl')
if tcl and re.search(r'(?m)^\s*(proc|for|foreach|while|if)\b', text):
self.rep.at(path)
self.rep.note("haltcl file that builds HAL names in code; the "
"plain commands are converted, a name a proc or a "
"loop builds is not, and has to be converted by "
"hand")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This makes me wonder... Why should we continue to support Tcl based hal files? Is there a (very) pressing case for having them?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

TCL other than innumerable parentheses, allows you to have multi model machines swappable configs with few INI changes per model, meaning a manufacturer could manage a single TCL, and have model only INI files, I am actually work in progress on moving my configs to TCL, but I'm too comfortable in Hal, and I find TCL less readable, Hal is easier to debug and hack new features on, so I'm conflicted about it, unfortunately I don't see other scripting languages coming to the rescue here...
Why wouldn't you want a way to script your Hal? I think is a valuable construct, just a painful language.

The biggest gripe is not being able to search a specific pin directly in the TCL file because it has been created from a variable, which is not listed anywhere, is that reason enough to drop the "scripted Hal" construct all together?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Sure, I get it why it is there ;-)
That said, not being able to grep your way to a pin is (very) annoying.

Anyway, there has been a continual push to move from Tcl to Python. That is my point... The Tcl support libraries are withering and Python would be the better choice in that light. Also seen in the light of our own updating of the python modules.

FWIW, I see a version 3 where TP is non-RT and all Tcl has been retired (rtai killed too; python modules in a namespace,...).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think that some of the shared files in the sample configs are Tcl HAL.
To be honest I didn't support that change, I think that all the sample configs should be flat files, to be easy to modify and for new users to comprehend. Yes that leads to a lot of redundancy, but so what?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There already is a huge copy/paste redundancy in the sample configs. It is no problem as long as they are maintained. But that is the hard problem.

@grandixximo grandixximo Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Having default TCL configs in tree is IMO quite user unfriendly, TCL configs IMO should be something a more advanced user reaches for, rather than being forced in the introductory configs, although that is how I learned they exist in the first place, but then again if we are going all Python... This feels like a larger topic for the agenda...

@BsAtHome

BsAtHome commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Do you also update the newsig lines?
newsig sig.name bit|float|s32|u32|s64|u64 --> newsig sig.name bool|real|sint|uint

@andypugh

andypugh commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

Why is this needed in addition to the existing update_ini script?

@BsAtHome

BsAtHome commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Why is this needed in addition to the existing update_ini script?

Factoring this out is a good thing because you may not hit all .hal files in the ini upgrade. There can be files located many places and a user may need to do some things more manually.

There is no problem of calling this from the ini update script to automate the 1.1->1.2 version upgrade. But when that fails, for whatever reason, you still want to offer some kind of automation for the hal files.

Removing the 32-bit HAL types renames components, pins and parameters
whose name spells a type that is gone (conv_s32_float -> conv_sint_real,
mux-gen.00.in-s32-00 -> mux-gen.00.in-sint-00), so a configuration using
those names fails to start.  halfileupdate rewrites them.

A name is rewritten only when it resolves to an instance of a component
that a loadrt in the files being read created, which covers count= and
names= instances and components whose HAL prefix is not the module name
without guessing; a name that does not resolve is left alone and
reported.  Given an INI file, the HAL files it names are converted in
the order LinuxCNC runs them, which is what makes a configuration
convertible: its loadrt and its pin uses are regularly in different
files.  Keys of a user interface's own and keys outside [HAL] count,
an INI value continued with a backslash is one command, and in haltcl
the Tcl form 'hal setp name value' is understood as well.  Signal names,
aliases, comments and names built with a substitution are never
rewritten, though the type word on a newsig line is converted, and a
linkpp line is reported since halcmd no longer has the command.  By
default a diff is printed and nothing is written;
--in-place rewrites atomically and keeps a .bak.

The renames are tables in the tool itself, following the 64-bit only
work: the eleven conv_* converters, the mux_generic and demux_generic
pins, demux sel-u32 and the reset pins.  They are regenerated if that
set changes.  No part of HAL knows the old names, and both the tool and
its tables are a migration aid for one release transition, not a
permanent part of HAL.  The test therefore checks that the old names are
gone and that what replaces them is consistent everywhere, not how any
one name is spelled.
@grandixximo

Copy link
Copy Markdown
Contributor Author

Both done.

newsig lines now convert the type word, newsig sig s32 to newsig sig sint, case-insensitive like halcmd, with the same map as the rest. It turns out to be the most common thing in a config by a distance: over the stock configs it takes the run from 65 changed lines to 201, and 148 of those are newsig.

linkpp now gets a warning that says the line will fail whatever its names are and has to become a net. The names on it are still converted so a hand rewrite lands on the right ones. I left linkps and linksp silent, per your second thought.

Tables get regenerated when abs_sint and the rest of your renames land; say the word when the set is settled and I will redo them in one go.

@grandixximo
grandixximo marked this pull request as draft September 4, 2026 13:01
@grandixximo

Copy link
Copy Markdown
Contributor Author

Draft till the renaming is settled...

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.

3 participants