These blocks mostly consisted of redundant structure, following the same
#ifndef pattern over and over, with only minimal variation.
It's easier to maintain if the common structure is only written once and
encapsulated in a macro.
To avoid "defined but unused" warnings from GCC in the case where
MAKE_NATIVE is not defined, I had to add volatile. Adding
MAKE_ATTR_UNUSED alone would not preserve the rcsid variable in the
resulting binary.
The functions LstIsValid and LstNodeIsValid are only used in assertions.
Without the always-false assertion, Enum_ValueToString could have
returned undefined behavior.
A string like OP_DEPENDS|OP_OPTIONAL|OP_PRECIOUS is much easier to read
and understand than the bit pattern 00000089.
The implementation in enum.h looks really bloated and ugly, but using
this API is as simple and natural as possible. That's the trade-off.
In enum.h, I thought about choosing the numbers in the macros such that
it is always possible to combine two of them in order to reach an
arbitrary number, because of the "part1, part2" in the ENUM__SPEC macro.
The powers of 2 are not these numbers, as 7 cannot be expressed as the
sum of two of them. Neither are the fibonacci numbers since 12 cannot
be expressed as the sum of 2 fibonacci numbers. I tried to find a
general pattern to generate these minimal 2-sum numbers, but failed.
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.