Add HexStringToUDINT() and UDINTToHexString() - #12
Merged
Conversation
HexStringToDINT() cannot represent the top half of the 32-bit range -
strtol() saturates 16#FFFFFFFF to 16#7FFFFFFF - and neither it nor
atoui() can report a parse failure, since the return value is the parsed
value and a failure is indistinguishable from a valid 0. That makes both
unusable for reading bit string types (BYTE/WORD/DWORD) out of a file,
where an invalid literal has to be rejected rather than quietly read as
zero.
HexStringToUDINT() returns a status and writes the value through a
pointer. It accepts several notations, since projects and tools differ:
0xFF 0XFF C style
16#FF IEC 61131-3 style
$FF Pascal style
FF bare
Leading and trailing white space is allowed; any other trailing
character is an error, so a truncated or mistyped literal is rejected
instead of being parsed up to the bad character. A sign is rejected
explicitly - strtoul() would otherwise silently negate it. Leading zeros
are ignored when checking width, so 16#000000FF is not an overflow.
UDINTToHexString() formats with a selectable prefix
(STREXT_HEXPREFIX_enum) and optional zero padding, and writes nothing at
all unless the whole string fits in the destination.
The example project gains a self test covering every prefix, the full
range, malformed input, null pointers, buffer overflow, and round trip
at each prefix. Set hexTest to run it; hexTestFail must come back 0.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Groundwork for BYTE/WORD/DWORD support in CSVFileLib (CSVFileLib#9 discussion). The parse/format primitives belong here rather than in CSVFileLib, since StringExt is already the home of
atoui/uitoa/HexStringToDINT/ByteToHexStringand is already a dependency of both CSVFileLib and VarTools.Why not the existing functions
HexStringToDINTisstrtol(s, 0, 16)returning signed long.16#FFFFFFFFsaturates to16#7FFFFFFF— the top half of the range is unrepresentable.atouiis a decimal-only loop that stops at the first non-digit.atoui("16#FF")returns16, reported as success.0. That's disqualifying for reading values out of a file, where bad input must be rejected rather than silently read as zero.What's added
Multiple prefixes accepted on parse, since projects and tools differ on notation:
0xFF,0XFF16#FF$FFFFSTREXT_HEXPREFIX_enum(NONE/0X/IEC/DOLLAR) selects the notation on output, so the caller owns the format decision.Details worth flagging:
strtoulwould silently negate-0x10into0xFFFFFFF0."0xFF junk"is rejected rather than parsed up to the space — a truncated or mistyped value should not read as a plausible number. Trailing whitespace is fine.16#000000FFis 8 significant digits after the zeros are skipped, not 10.strtoul, which would otherwise accept a second prefix in0x0xFF.Error codes
STREXT_ERR_enumgainsSTREXT_ERR_INVALID_FORMAT(-2),STREXT_ERR_RANGE(-3),STREXT_ERR_BUFFER_TOO_SMALL(-4). ExistingSTREXT_ERR_INVALID_INPUT(-1) is unchanged.Verification
hexTest→hexTestPass/hexTestFail/hexTestFirstFail) covering every prefix, case handling, padding, whitespace, the full 32-bit range, out-of-range, malformed input, null pointers, buffer-too-small, and round trip at each prefix.Note: I could not run the self test on hardware here — this machine's AR install has no firmware module for the example's
5PC900, so no RUC package is produced locally. CI builds against the pinned AR 6.6.2.Not addressed here: whether VarTools should adopt hex output. It currently formats DWORD as decimal deliberately, for interop with systems that don't take hex — that stays as it is.
🤖 Generated with Claude Code