Skip to content

check_config: assert INI datatypes before comparing limits#4190

Open
tzuohann wants to merge 1 commit into
LinuxCNC:2.9from
tzuohann:check_config-2.9-datatypes
Open

check_config: assert INI datatypes before comparing limits#4190
tzuohann wants to merge 1 commit into
LinuxCNC:2.9from
tzuohann:check_config-2.9-datatypes

Conversation

@tzuohann

Copy link
Copy Markdown

Problem

A user who puts an inline comment on a limit line — e.g. MAX_LIMIT = 100 # travel, easy to do without carefully reading the manual — is currently served a very confusing error from the pre-run config check:

[JOINT_0]MAX_LIMIT < [AXIS_X]MAX_LIMIT (100 < {100   # travel})

It appears to claim 100 < 100 and points at the wrong problem entirely (a phantom joint/axis limit violation), when the real issue is the stray inline comment.

Cause: the [JOINT_n]/[AXIS_L] limit check in check_config.tcl compares values with Tcl > / <, which silently falls back to string comparison when a value isn't a valid number. The comment text makes the value a string, so the outcome depends on trailing whitespace rather than the numbers. A duplicated key behaves the same way (the multi-valued list is compared as a string).

This affects all of 2.9 — the inline-comment-stripping parser rewrite only exists in master/2.10.

Reproduce

Minimal trivkins config (bad.ini):

[KINS]
JOINTS = 1
KINEMATICS = trivkins coordinates=X
[AXIS_X]
MAX_LIMIT = 100   # travel
[JOINT_0]
MAX_LIMIT = 100

Run the checker against it:

$ tclsh lib/hallib/check_config.tcl bad.ini

Before this patch it reports the phantom [JOINT_0]MAX_LIMIT < [AXIS_X]MAX_LIMIT (100 < {100 # travel}).

Fix

Add assert_ini_datatypes(), run once right after parse_ini, before any comparison. For each [JOINT_n]/[AXIS_L] item it validates the value LinuxCNC actually uses — the first occurrence (IniFile::Find defaults to num=1; the manual, The INI File → Comments, likewise states the first value is used):

  • numeric items (limits, vels, accels, scales, PID terms, home vels, …) must pass string is double;
  • enum items must match a fixed set, case-insensitively, mirroring LinuxCNC's own caseless parsers (TYPE → LINEAR/ANGULAR; bool set for HOME_*, VOLATILE_HOME, LOCKING_INDEXER).

A non-numeric value containing # or ; additionally reports that inline comments are not allowed and cites the manual section, so the user is pointed at the real mistake:

[AXIS_X]MAX_LIMIT must be numeric, got: <100   # travel>
    Inline comments are not allowed: '#' and ';' start a comment
    only at the start of a line, not after a value. Move the comment
    to its own line. See the LinuxCNC manual, "The INI File" ->
    "Comments": https://linuxcnc.org/docs/stable/html/config/ini-config.html#_comments

Duplicate (multi-valued) keys are not fatal — LinuxCNC uses the first occurrence — so they emit a warning and the array is collapsed to that first value (so the downstream limit comparison uses the same value LinuxCNC would). This subsumes the warn-only warn_for_multiple_ini_values, which is removed.

Testing

Verified with minimal trivkins configs:

Case Result
inline comment on a limit error + manual citation (exit 1)
duplicate key, first value valid warning only, passes (exit 0)
duplicate key, first value has a comment warning + error on first (exit 1)
clean config passes (exit 0)

A user who puts an inline comment on a limit line -- e.g.
"MAX_LIMIT = 100  # travel", easy to do without carefully reading the
manual -- is currently served a very confusing error. The check reports
a phantom limit violation like "[JOINT_0]MAX_LIMIT < [AXIS_X]MAX_LIMIT
(100 < {100   # travel})", which appears to claim 100 < 100 and points
at the wrong problem entirely.

The cause: the [JOINT_n]/[AXIS_L] limit check compares values with Tcl
> / <, which silently falls back to *string* comparison when a value
isn't a valid number (the stray comment text makes it a string). The
result then depends on trailing whitespace rather than the numbers. A
duplicated key behaved the same way, since the multi-valued list was
compared as a string.

Add assert_ini_datatypes(), run once right after parse_ini, before any
comparison. For each [JOINT_n]/[AXIS_L] item it validates the value
LinuxCNC actually uses -- the first occurrence (IniFile::Find defaults
to num=1; the manual, 'The INI File' -> 'Comments', likewise states the
first value is used):
  - numeric items (limits, vels, accels, scales, PID terms, home vels,
    ...) must pass `string is double` (accepts ints and reals);
  - enum items must match a fixed set, case-insensitively, mirroring
    LinuxCNC's own caseless parsers:
      TYPE  -> {LINEAR ANGULAR}                 (IniFile::mapJointType)
      bools -> {TRUE YES 1 ON FALSE NO 0 OFF}   (IniFile::convertBool)
  - unknown items are left untouched.

A non-numeric value whose text contains '#' or ';' additionally reports
that inline comments are not allowed and cites the manual section, so the
user is pointed at the real mistake.

Duplicate (multi-valued) [JOINT_]/[AXIS_] keys are not fatal -- LinuxCNC
uses the first occurrence -- so they emit a warning and the array is
collapsed to that first value so the downstream limit comparison uses it
too. This subsumes the warn-only warn_for_multiple_ini_values, which is
removed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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