chiark / gitweb /
src/internal.h: Hoist the qcontext definition to before typeinfo.
[adns.git] / src / internal.h
index 512a2b11e4e4511b61e946482fe823b7886ac089..fed84663626f2eeae1c1709a04b425451a995789 100644 (file)
@@ -72,6 +72,27 @@ typedef unsigned char byte;
 
 #define MAX_POLLFDS  ADNS_POLLFDS_RECOMMENDED
 
 
 #define MAX_POLLFDS  ADNS_POLLFDS_RECOMMENDED
 
+/* Some preprocessor hackery */
+
+#define GLUE(x, y) GLUE_(x, y)
+#define GLUE_(x, y) x##y
+
+/* C99 macro `...' must match at least one argument, so the naive definition
+ * `#define CAR(car, ...) car' won't work.  But it's easy to arrange for the
+ * tail to be nonempty if we're just going to discard it anyway. */
+#define CAR(...) CAR_(__VA_ARGS__, _)
+#define CAR_(car, ...) car
+
+/* Extracting the tail of an argument list is rather more difficult.  The
+ * following trick is based on one by Laurent Deniau to count the number of
+ * arguments to a macro, simplified in two ways: (a) it only handles up to
+ * eight arguments, and (b) it only needs to distinguish the one-argument
+ * case from many arguments. */
+#define CDR(...) CDR_(__VA_ARGS__, m, m, m, m, m, m, m, 1, _)(__VA_ARGS__)
+#define CDR_(_1, _2, _3, _4, _5, _6, _7, _8, n, ...) CDR_##n
+#define CDR_1(_)
+#define CDR_m(_, ...) __VA_ARGS__
+
 typedef enum {
   cc_user,
   cc_entex,
 typedef enum {
   cc_user,
   cc_entex,
@@ -103,6 +124,20 @@ typedef struct {
   struct timeval now;
 } parseinfo;
 
   struct timeval now;
 } parseinfo;
 
+typedef struct {
+  void *ext;
+  void (*callback)(adns_query parent, adns_query child);
+
+  union {
+    adns_rr_addr ptr_addr;
+  } tinfo; /* type-specific state for the query itself: zero-init if you
+           * don't know better. */
+
+  union {
+    adns_rr_hostaddr *hostaddr;
+  } pinfo; /* state for use by parent's callback function */
+} qcontext;
+
 typedef struct typeinfo {
   adns_rrtype typekey;
   const char *rrtname;
 typedef struct typeinfo {
   adns_rrtype typekey;
   const char *rrtname;
@@ -178,20 +213,6 @@ union maxalign {
   union maxalign *up;
 } data;
 
   union maxalign *up;
 } data;
 
-typedef struct {
-  void *ext;
-  void (*callback)(adns_query parent, adns_query child);
-
-  union {
-    adns_rr_addr ptr_addr;
-  } tinfo; /* type-specific state for the query itself: zero-init if you
-           * don't know better. */
-
-  union {
-    adns_rr_hostaddr *hostaddr;
-  } pinfo; /* state for use by parent's callback function */
-} qcontext;
-
 struct adns__query {
   adns_state ads;
   enum { query_tosend, query_tcpw, query_childw, query_done } state;
 struct adns__query {
   adns_state ads;
   enum { query_tosend, query_tcpw, query_childw, query_done } state;