Having only 8 dollar signs does not prove anything. It might still be
the result of 3 substitutions in a row. Having 5 substitutions in a row
is less likely though.
Declaring the ToStringSize as "static const size_t" made it an ordinary
integer expression. To avoid variable length arrays, the commonly
accepted way is to declare the length as an enum constant, as that is
considered an integer constant expression, which in turn makes the
declaration a fixed-size array.
Swapped the two halves (only gcc does that, I think) and wrote j,i
backwards, oops.
(I don't have a big-endian arm clang build handy to test; hoping this
works.)
When allocating for a Char **, it should use sizeof(Char *), not
sizeof(Char **). This doesn't actually affect the results except
on DS9000 though :-)
(part 2, the instance in this file was as far as I can tell
inexplicably missed by CVS on the first go...)
This Z had been useful during the migration from int to size_t. This
migration is finished, at least for the Buffer type, so the Z is no
longer necessary.
This will hopefully help with tracking down why the "Undefined variable"
error message is not triggered.
There is some other non-obvious behavior nearby. In Parse_DoVar, the !=
assignment operator evaluates the variable using VARE_UNDEFERR, but
there is not even a warning for the following line:
!= echo err ${UNDEFINED} 1>&2
Many of the functions in cond.c are so small that it's faster to read
their code instead of a large block of documentation.
There are other functions that actually need a detailed description.
These have been left as-is.
New macros such as VQ_N_U32(a,b,c,d) for NEON vector initializers.
Needed because GCC and Clang disagree on the ordering of lanes,
depending on whether it's 64-bit big-endian, 32-bit big-endian, or
little-endian -- and, bizarrely, both of them disagree with the
architectural numbering of lanes.
Experimented with using
static const uint8_t x8[16] = {...};
uint8x16_t x = vld1q_u8(x8);
which doesn't require knowing anything about the ordering of lanes,
but this generates considerably worse code and apparently confuses
GCC into not recognizing the constant value of x8.
Fix some clang mistakes while here too.
The error marker var_Error is just an empty string. In the debug log
this empty string was not distinguishable from an otherwise empty
string.
Having this distinction helps in understanding the exact data flow.
Before a modifier is applied to a variable, it is not yet parsed,
therefore it is only possible to log a rough estimate of the modifier.
But after applying it, the parsing position has advanced, and the full
modifier can be logged.
In addition, to fully understand how the modifiers work, it's not enough
to just know the variable names and values, there are also some flags
that influence how the modifiers behave. The most influential is
VARE_WANTRES.
Thanks to sjg for the extensive review and valuable feedback on the
first drafts.