Browse Source
structeq() is too dangerous: if a structure has padding, it can fail silently. The new ccan/structeq instead provides a macro to define foo_eq(), which does the right thing in case of padding (which none of our structures currently have anyway). Upgrade ccan, and use it everywhere. Except run-peer-wire.c, which is only testing code and can use raw memcmp(): valgrind will tell us if padding exists. Interestingly, we still declared short_channel_id_eq, even though we didn't define it any more! Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>ppa-0.6.1
committed by
Christian Decker
44 changed files with 172 additions and 140 deletions
@ -1,3 +1,3 @@ |
|||||
CCAN imported from http://ccodearchive.net. |
CCAN imported from http://ccodearchive.net. |
||||
|
|
||||
CCAN version: init-2434-gac8694de |
CCAN version: init-2435-g92be2eff |
||||
|
@ -1 +1 @@ |
|||||
../../licenses/CC0 |
../../licenses/BSD-MIT |
@ -1,17 +1,45 @@ |
|||||
/* CC0 (Public domain) - see LICENSE file for details */ |
/* MIT (BSD) license - see LICENSE file for details */ |
||||
#ifndef CCAN_STRUCTEQ_H |
#ifndef CCAN_STRUCTEQ_H |
||||
#define CCAN_STRUCTEQ_H |
#define CCAN_STRUCTEQ_H |
||||
|
#include <ccan/build_assert/build_assert.h> |
||||
|
#include <ccan/cppmagic/cppmagic.h> |
||||
#include <string.h> |
#include <string.h> |
||||
|
#include <stdbool.h> |
||||
|
|
||||
/**
|
/**
|
||||
* structeq - are two structures bitwise equal (including padding!) |
* STRUCTEQ_DEF - define an ..._eq function to compare two structures. |
||||
* @a: a pointer to a structure |
* @sname: name of the structure, and function (<sname>_eq) to define. |
||||
* @b: a pointer to a structure of the same type. |
* @padbytes: number of bytes of expected padding, or -1 if unknown. |
||||
|
* @...: name of every member of the structure. |
||||
* |
* |
||||
* If you *know* a structure has no padding, you can memcmp them. At |
* This generates a single memcmp() call in the common case where the |
||||
* least this way, the compiler will issue a warning if the structs are |
* structure contains no padding. Since it can't tell the difference between |
||||
* different types! |
* padding and a missing member, @padbytes can be used to assert that |
||||
|
* there isn't any, or how many we expect. -1 means "expect some", since |
||||
|
* it can be platform dependent. |
||||
*/ |
*/ |
||||
#define structeq(a, b) \ |
#define STRUCTEQ_DEF(sname, padbytes, ...) \ |
||||
(memcmp((a), (b), sizeof(*(a)) + 0 * sizeof((a) == (b))) == 0) |
static inline bool CPPMAGIC_GLUE2(sname, _eq)(const struct sname *_a, \ |
||||
|
const struct sname *_b) \ |
||||
|
{ \ |
||||
|
BUILD_ASSERT(((padbytes) < 0 && \ |
||||
|
CPPMAGIC_JOIN(+, CPPMAGIC_MAP(STRUCTEQ_MEMBER_SIZE_, \ |
||||
|
__VA_ARGS__)) \ |
||||
|
> sizeof(*_a)) \ |
||||
|
|| CPPMAGIC_JOIN(+, CPPMAGIC_MAP(STRUCTEQ_MEMBER_SIZE_, \ |
||||
|
__VA_ARGS__)) \ |
||||
|
+ (padbytes) == sizeof(*_a)); \ |
||||
|
if (CPPMAGIC_JOIN(+, CPPMAGIC_MAP(STRUCTEQ_MEMBER_SIZE_, __VA_ARGS__)) \ |
||||
|
== sizeof(*_a)) \ |
||||
|
return memcmp(_a, _b, sizeof(*_a)) == 0; \ |
||||
|
else \ |
||||
|
return CPPMAGIC_JOIN(&&, \ |
||||
|
CPPMAGIC_MAP(STRUCTEQ_MEMBER_CMP_, \ |
||||
|
__VA_ARGS__)); \ |
||||
|
} |
||||
|
|
||||
|
/* Helpers */ |
||||
|
#define STRUCTEQ_MEMBER_SIZE_(m) sizeof((_a)->m) |
||||
|
#define STRUCTEQ_MEMBER_CMP_(m) memcmp(&_a->m, &_b->m, sizeof(_a->m)) == 0 |
||||
|
|
||||
#endif /* CCAN_STRUCTEQ_H */ |
#endif /* CCAN_STRUCTEQ_H */ |
||||
|
Loading…
Reference in new issue