Skip to content

fix: Keep starting address 0 in 0-based projects (#142) - #143

Merged
sanny32 merged 1 commit into
sanny32:devfrom
ehlxr:fix/zero-based-address-zero
Nov 4, 2026
Merged

sanny32 merged 1 commit into
sanny32:devfrom
ehlxr:fix/zero-based-address-zero

Conversation

@ehlxr

@ehlxr ehlxr commented Nov 4, 2026

Copy link
Copy Markdown

Summary

Fixes #142. With a 0-based address base, a data view whose starting address is 0 was saved correctly (PointAddress="0" in the project file) but showed 1 after reopening the project, so address 0 could not be persisted.

Root cause

DataViewDefinitions::normalize() clamped the address unconditionally:

PointAddress = qMax<quint16>(1, PointAddress);

That clamp is only valid for 1-based projects. With a 0-based base the valid range starts at 0 (ModbusLimits::addressRange(space, /*zeroBased*/ true)), but normalize() is base-agnostic and is called by the XML reader, so 0 was destroyed on every load. The legacy 1.x loaders worked around this by re-reading the raw PointAddress attribute after normalize().

Changes

  • src/displaydefinition.h: normalize() no longer touches PointAddress; the lower bound depends on the address base, which this struct does not know.
  • src/formdataview.cpp: setDisplayDefinition() and setDisplayDefinitionSilent() clamp the starting address against the current address range before applying it, so 0-based projects keep 0 while 1-based projects still fall back from 0 to 1.
  • src/legacyprojectloader.cpp, src/legacyprojectparser.cpp: parse PointAddress normally and drop the now-unneeded re-read workaround.
  • src/tests/test_appproject.cpp: two regression tests.

Tests

  • preservesZeroBasedStartingAddressZeroAcrossReopen: a 0-based data view starting at address 0 survives two save/reload cycles, including the register values at address 0 (fails without the fix).
  • clampsZeroStartingAddressForOneBasedProject: a 1-based project file containing the invalid PointAddress="0" still opens at address 1.
  • Existing preservesZeroBasedStartingAddressAcrossReopen (issue Starting Address decreasing on save with 0-based addressing #130), legacy parser tests and the rest of omodsim_tests_appproject pass.

DataViewDefinitions::normalize() clamped PointAddress to a minimum of 1,
which is only correct for 1-based projects. With a 0-based address base a
data view starting at address 0 was saved as PointAddress="0" but loaded
back as 1, because normalize() runs from the XML reader.

normalize() no longer touches PointAddress; FormDataView clamps the value
against the current address range when the definition is applied, so
1-based projects still fall back from 0 to 1. The legacy 1.x loaders can
now parse PointAddress normally instead of re-reading it after normalize().

Add regression tests for the 0-based round trip and for the 1-based
fallback.
@sanny32
sanny32 self-requested a review November 4, 2026 13:40
@sanny32
sanny32 merged commit 41d6c42 into sanny32:dev Nov 4, 2026
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