geometry: accept tab as a numeric field separator - #125
Merged
Conversation
added 2 commits
August 2, 2026 21:56
The integer and real field scanners in parse_geometry_card_line() only terminated a field on space, comma, or NUL. A tab immediately after a field was consumed as part of the field instead of ending it, so decks using tabs to separate geometry-card values (e.g. 86-2-ex9.nec) aborted with "NON-NUMERICAL CHARACTER '<TAB>' IN INTEGER FIELD" at the tab position. - add geometry_field_separator(), classifying isspace(), comma, and NUL as one shared separator rule - replace both duplicated scan-loop conditions with the new helper so the integer and real paths cannot diverge on what ends a field Signed-off-by: Eric Wheeler <necpp@z.ewheeler.org>
The geometry parser previously rejected tab characters between fields on geometry cards, aborting at the first tab following an integer field. This adds a permanent regression test exercising that failure through the public file parser. - add a GW/GE deck delimited entirely by tabs and parse it through c_geometry::parse_geometry(nec_context *, FILE *), asserting n_segments == 3 to confirm tab termination works in both the integer and real field scanners Signed-off-by: Eric Wheeler <necpp@z.ewheeler.org>
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.
Description
Decks that separate geometry-card fields with tabs failed to load. Any card whose
numeric fields are tab-delimited aborted parsing at the first tab, so otherwise
valid models could not be solved. Spaces and commas already worked; tab was
simply absent from the terminator set used to close a numeric field.
The integer and real field scanners each carried their own inline terminator
test, so the two could disagree. This change gives both one shared separator
rule and adds a permanent regression test through the public file parser.
Type of Change
Implementation Details
src/c_geometry.cpp: adds the file-local querygeometry_field_separator(),which classifies
std::isspace()whitespace, the NEC comma, and the NULterminating the loaded card. The character is converted to
unsigned charbefore classification so negative plain-
charvalues never reach the Ccharacter-classification interface. Both post-conversion scans in
parse_geometry_card_line()call it, so the integer and real paths cannotdrift apart. Numeric syntax checking stays in the existing scanner loops.
src/nec2cpp_tb.cpp: adds the regression described below.Reproduction
<TAB>denotes one horizontal-tab byte,0x09. Original failing deck line from86-2-ex9.nec:Before: parsing aborts at character 5, the tab immediately following the first
integer field:
After: the deck reaches its end card and reports
TOTAL RUN TIME:.Testing
The permanent regression writes this complete input to a temporary file, parses
it with
c_geometry::parse_geometry(nec_context *, FILE *), and asserts thesegment count. It exercises tab termination in both the integer and the real
scanner.
Before: parsing aborts at the first tab after an integer field.
After: parsing completes with
n_segments == 3.Result: