[ccan] [PATCH 1/5] cppmagic: New module

David Gibson david at gibson.dropbear.id.au
Wed Jan 27 22:39:57 AEDT 2016


A module for some of the awesome / horrifying techniques described at:
    http://jhnet.co.uk/articles/cpp_magic
    https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms

Start off with just some simple things.

Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
---
 ccan/cppmagic/LICENSE    |  1 +
 ccan/cppmagic/_info      | 30 ++++++++++++++++++++++++++++++
 ccan/cppmagic/cppmagic.h | 42 ++++++++++++++++++++++++++++++++++++++++++
 ccan/cppmagic/test/run.c | 34 ++++++++++++++++++++++++++++++++++
 4 files changed, 107 insertions(+)
 create mode 120000 ccan/cppmagic/LICENSE
 create mode 100644 ccan/cppmagic/_info
 create mode 100644 ccan/cppmagic/cppmagic.h
 create mode 100644 ccan/cppmagic/test/run.c

diff --git a/ccan/cppmagic/LICENSE b/ccan/cppmagic/LICENSE
new file mode 120000
index 0000000..2354d12
--- /dev/null
+++ b/ccan/cppmagic/LICENSE
@@ -0,0 +1 @@
+../../licenses/BSD-MIT
\ No newline at end of file
diff --git a/ccan/cppmagic/_info b/ccan/cppmagic/_info
new file mode 100644
index 0000000..aad394b
--- /dev/null
+++ b/ccan/cppmagic/_info
@@ -0,0 +1,30 @@
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+
+/**
+ * cppmagic - Abuse of the C preprocessor
+ *
+ * This contains a bunch of fancy macro techniques such as
+ * preprocessor-time evaluated conditionals and (quasi) recursion and
+ * iteration.
+ *
+ * It's based on these articles:
+ *  - http://jhnet.co.uk/articles/cpp_magic
+ *  - https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms
+ * and code from the Boost C++ library.
+ *
+ * License: BSD-MIT
+ */
+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;
+}
diff --git a/ccan/cppmagic/cppmagic.h b/ccan/cppmagic/cppmagic.h
new file mode 100644
index 0000000..f29e0ec
--- /dev/null
+++ b/ccan/cppmagic/cppmagic.h
@@ -0,0 +1,42 @@
+/* MIT (BSD) license - see LICENSE file for details */
+#ifndef CCAN_CPPMAGIC_H
+#define CCAN_CPPMAGIC_H
+
+/**
+ * CPPMAGIC_NOTHING - expands to nothing
+ */
+#define CPPMAGIC_NOTHING()
+
+/**
+ * CPPMAGIC_STRINGIFY - convert arguments to a string literal
+ */
+#define _CPPMAGIC_STRINGIFY(...)	#__VA_ARGS__
+#define CPPMAGIC_STRINGIFY(...)		_CPPMAGIC_STRINGIFY(__VA_ARGS__)
+
+/**
+ * CPPMAGIC_GLUE2 - glue arguments together
+ *
+ * CPPMAGIC_GLUE2(@a_, @b_)
+ *	expands to the expansion of @a_ followed immediately
+ *	(combining tokens) by the expansion of @b_
+ */
+#define _CPPMAGIC_GLUE2(a_, b_)		a_##b_
+#define CPPMAGIC_GLUE2(a_, b_)		_CPPMAGIC_GLUE2(a_, b_)
+
+/**
+ * CPPMAGIC_1ST - return 1st argument
+ *
+ * CPPMAGIC_1ST(@a_, ...)
+ *	expands to the expansion of @a_
+ */
+#define CPPMAGIC_1ST(a_, ...)		a_
+
+/**
+ * CPPMAGIC_2ND - return 2nd argument
+ *
+ * CPPMAGIC_2ST(@a_, @b_, ...)
+ *	expands to the expansion of @b_
+ */
+#define CPPMAGIC_2ND(a_, b_, ...)	b_
+
+#endif /* CCAN_CPPMAGIC_H */
diff --git a/ccan/cppmagic/test/run.c b/ccan/cppmagic/test/run.c
new file mode 100644
index 0000000..0ed830d
--- /dev/null
+++ b/ccan/cppmagic/test/run.c
@@ -0,0 +1,34 @@
+#include "config.h"
+
+#include <string.h>
+
+#include <ccan/cppmagic/cppmagic.h>
+#include <ccan/tap/tap.h>
+
+static inline void check1(const char *orig, const char *expand,
+			  const char *match)
+{
+	ok(strcmp(expand, match) == 0,
+	   "%s => %s : %s", orig, expand, match);
+}
+
+#define CHECK1(orig, match) \
+	check1(#orig, CPPMAGIC_STRINGIFY(orig), match)
+
+int main(void)
+{
+	plan_tests(7);
+
+	CHECK1(CPPMAGIC_NOTHING(), "");
+	CHECK1(CPPMAGIC_GLUE2(a, b), "ab");
+
+	CHECK1(CPPMAGIC_1ST(a), "a");
+	CHECK1(CPPMAGIC_1ST(a, b), "a");
+	CHECK1(CPPMAGIC_1ST(a, b, c), "a");
+
+	CHECK1(CPPMAGIC_2ND(a, b), "b");
+	CHECK1(CPPMAGIC_2ND(a, b, c), "b");
+
+	/* This exits depending on whether all tests passed */
+	return exit_status();
+}
-- 
2.5.0



More information about the ccan mailing list