Browse Source

structeq: new module.

World's most trivial module, but I want it for pettycoin.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Rusty Russell 11 years ago
parent
commit
8b0bdb090e

+ 1 - 0
Makefile-ccan

@@ -23,6 +23,7 @@ MODS_NO_SRC := alignof \
 	minmax \
 	objset \
 	short_types \
+	structeq \
 	tcon \
 	tlist \
 	typesafe_cb \

+ 1 - 0
ccan/structeq/LICENSE

@@ -0,0 +1 @@
+../../licenses/CC0

+ 57 - 0
ccan/structeq/_info

@@ -0,0 +1,57 @@
+#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;
+}

+ 17 - 0
ccan/structeq/structeq.h

@@ -0,0 +1,17 @@
+/* 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 */

+ 22 - 0
ccan/structeq/test/compile_fail-different.c

@@ -0,0 +1,22 @@
+#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);
+}

+ 27 - 0
ccan/structeq/test/run.c

@@ -0,0 +1,27 @@
+#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();
+}