diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-07 14:41:07 -0700 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2014-06-07 19:40:28 -0700 |
commit | f46f9139a82fd93bcdb84735649b804c27b0b9c1 (patch) | |
tree | bb239a9966262b38639510dba2e4848160c95cee /packaging | |
parent | 72362d09932426dad0c27553010ffac89d681d32 (diff) | |
download | subsurface-f46f9139a82fd93bcdb84735649b804c27b0b9c1.tar.gz |
Make parse-xml callbacks be type-safe
.. and fix the type breakage brought in by commit eaf6d564874a ("CCR code:
Change to sample structure")
The XML parsing callbacks pass a "void *" around, because the helper
function that matches the XML node names ("match()") does so for all the
different dive/sample/dc member nodes that all have different types.
But that also hid the fact that it very much depended on the various types
being regular "int" etc, rather than the denser types that were introduced
so that the CCR data wouldn't expand memory use excessively. As a result,
XML loading would overwrite other members, and possibly even the
allocation, when it wrote an "int" value to something that only was a
8-bit allocation.
I left the "utf8_string()" without type checking - so it still uses
"void *_res" for the result type, with the cast happening inside the
function.
That's because the result destination ends up being a bit mixed-up wrt
"const char **" and just plain "char **". Note that the thing we modify
itself isn't const (it's not "char *const *"), but the pointer, but we
basically sometimes assign a "const char *", and sometimes a "char *".
I considered making two different versions of the callback, but it just
wasn't worth it. So "utf8_string()" users still aren't type-checked, and
you'd better give it a pointer to something that is some kind of "char *"
This patch doesn't really change the calling convention of the matching
function itself, but it makes the wrapper macro ("MATCH()") take a
properly type-checked function pointer instead (with a dummy call to do
type checking), and then casts the pointer to the "void *" type for the
actual real call.
The function pointer call is not really portable (although it works on
all sane architectures, particularly since the cast only changes one
argument from one type of pointer to another), and to make matters worse
uses the gcc statement-expression extension. But all the compilers we use
seem to support that gcc'ism, so in practice this gives us type-safety
with no downsides.
(If we ever want to use MSVC to compile subsurface, I suspect we'll have
to ifdef out the statement expression use and not type-check things. Or
perhaps re-write the thing as a ternary expression instead, or something).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'packaging')
0 files changed, 0 insertions, 0 deletions