Commit 8e6c2fec authored by Rusty Russell's avatar Rusty Russell

structeq: fix case where we mark padding as unknown.

And change semantics: a negative number means "up to this much padding".
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent d98e77e5
......@@ -9,14 +9,15 @@
/**
* STRUCTEQ_DEF - define an ..._eq function to compare two structures.
* @sname: name of the structure, and function (<sname>_eq) to define.
* @padbytes: number of bytes of expected padding, or -1 if unknown.
* @padbytes: number of bytes of expected padding, or negative "max".
* @...: name of every member of the structure.
*
* This generates a single memcmp() call in the common case where the
* structure contains no padding. Since it can't tell the difference between
* 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.
* there isn't any, or how many we expect. A negative number means
* "up to or equal to that amount of padding", as padding can be
* platform dependent.
*/
#define STRUCTEQ_DEF(sname, padbytes, ...) \
static inline bool CPPMAGIC_GLUE2(sname, _eq)(const struct sname *_a, \
......@@ -25,7 +26,7 @@ static inline bool CPPMAGIC_GLUE2(sname, _eq)(const struct sname *_a, \
BUILD_ASSERT(((padbytes) < 0 && \
CPPMAGIC_JOIN(+, CPPMAGIC_MAP(STRUCTEQ_MEMBER_SIZE_, \
__VA_ARGS__)) \
> sizeof(*_a)) \
- (padbytes) >= sizeof(*_a)) \
|| CPPMAGIC_JOIN(+, CPPMAGIC_MAP(STRUCTEQ_MEMBER_SIZE_, \
__VA_ARGS__)) \
+ (padbytes) == sizeof(*_a)); \
......
......@@ -2,11 +2,12 @@
struct mydata {
int start, end;
int pad;
};
#ifdef FAIL
#define PADDING -1
#define PADDING -1 /* We have more than 1 byte padding */
#else
#define PADDING 0
#define PADDING sizeof(int)
#endif
STRUCTEQ_DEF(mydata, PADDING, start, end);
......
#include <ccan/structeq/structeq.h>
struct mydata {
int start, end;
int pad;
};
#ifdef FAIL
#define PADDING -1
#else
#define PADDING -(int)sizeof(int)
#endif
STRUCTEQ_DEF(mydata, PADDING, start, end);
int main(void)
{
struct mydata a = { 0, 100 };
return mydata_eq(&a, &a);
}
#include <ccan/structeq/structeq.h>
#include <ccan/tap/tap.h>
/* In theory, this could be generated without padding, if alignof(int) were 0,
* and test would fail. Call me when that happens. */
struct mydata {
char start;
int end;
};
STRUCTEQ_DEF(mydata, -3, start, end);
struct mydata2 {
char start;
int end;
};
STRUCTEQ_DEF(mydata2, -4, start, end);
int main(void)
{
struct mydata a, b;
/* This is how many tests you plan to run */
plan_tests(3);
a.start = 0;
a.end = 100;
ok1(mydata_eq(&a, &a));
b = a;
ok1(mydata_eq(&a, &b));
b.end++;
ok1(!mydata_eq(&a, &b));
/* This exits depending on whether all tests passed */
return exit_status();
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment