World's most trivial module, but I want it for pettycoin.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
minmax \
objset \
short_types \
+ structeq \
tcon \
tlist \
typesafe_cb \
--- /dev/null
+../../licenses/CC0
\ No newline at end of file
--- /dev/null
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+
+/**
+ * structeq - bitwise comparison of structs.
+ *
+ * This is a replacement for memcmp, which checks the argument types are the
+ * same.
+ *
+ * License: CC0 (Public domain)
+ * Author: Rusty Russell <rusty@rustcorp.com.au>
+ *
+ * Example:
+ * #include <ccan/structeq/structeq.h>
+ * #include <ccan/build_assert/build_assert.h>
+ * #include <assert.h>
+ *
+ * struct mydata {
+ * int start, end;
+ * };
+ *
+ * int main(void)
+ * {
+ * struct mydata a, b;
+ *
+ * // No padding in struct, otherwise this doesn't work!
+ * BUILD_ASSERT(sizeof(a) == sizeof(a.start) + sizeof(a.end));
+ *
+ * a.start = 100;
+ * a.end = 101;
+ *
+ * b.start = 100;
+ * b.end = 101;
+ *
+ * // They are equal.
+ * assert(structeq(&a, &b));
+ *
+ * b.end++;
+ * // Now they are not.
+ * assert(!structeq(&a, &b));
+ *
+ * return 0;
+ * }
+ */
+int main(int argc, char *argv[])
+{
+ /* Expect exactly one argument */
+ if (argc != 2)
+ return 1;
+
+ if (strcmp(argv[1], "depends") == 0) {
+ return 0;
+ }
+
+ return 1;
+}
--- /dev/null
+/* CC0 (Public domain) - see LICENSE file for details */
+#ifndef CCAN_STRUCTEQ_H
+#define CCAN_STRUCTEQ_H
+#include <string.h>
+
+/**
+ * structeq - are two structures bitwise equal (including padding!)
+ * @a: a pointer to a structure
+ * @b: a pointer to a structure of the same type.
+ *
+ * If you *know* a structure has no padding, you can memcmp them. At
+ * least this way, the compiler will issue a warning if the structs are
+ * different types!
+ */
+#define structeq(a, b) \
+ (memcmp((a), (b), sizeof(*(a)) + 0 * sizeof((a) == (b))) == 0)
+#endif /* CCAN_STRUCTEQ_H */
--- /dev/null
+#include <ccan/structeq/structeq.h>
+
+struct mydata1 {
+ int start, end;
+};
+
+struct mydata2 {
+ int start, end;
+};
+
+int main(void)
+{
+ struct mydata1 a = { 0, 100 };
+#ifdef FAIL
+ struct mydata2
+#else
+ struct mydata1
+#endif
+ b = { 0, 100 };
+
+ return structeq(&a, &b);
+}
--- /dev/null
+#include <ccan/structeq/structeq.h>
+#include <ccan/tap/tap.h>
+
+struct mydata {
+ int 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(structeq(&a, &a));
+
+ b = a;
+ ok1(structeq(&a, &b));
+
+ b.end++;
+ ok1(!structeq(&a, &b));
+
+ /* This exits depending on whether all tests passed */
+ return exit_status();
+}