X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=adns.git;a=blobdiff_plain;f=src%2Finternal.h;h=38168814e8d32029beaecab2979874dffe337869;hp=9df4da5f839ea89bc299a2400c86c6dbf33e3aad;hb=be4d66dc60264126ba6b3fbd67609ef0b6c0d266;hpb=18c0d1f23dbe9f9dc2863dc2ca259643e7b1f9fa diff --git a/src/internal.h b/src/internal.h index 9df4da5..3816881 100644 --- a/src/internal.h +++ b/src/internal.h @@ -72,6 +72,27 @@ typedef unsigned char byte; #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, @@ -103,6 +124,20 @@ typedef struct { 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; @@ -178,15 +213,6 @@ union maxalign { union maxalign *up; } data; -typedef struct { - void *ext; - void (*callback)(adns_query parent, adns_query child); - union { - adns_rr_addr ptr_parent_addr; - adns_rr_hostaddr *hostaddr; - } info; -} qcontext; - struct adns__query { adns_state ads; enum { query_tosend, query_tcpw, query_childw, query_done } state; @@ -429,7 +455,7 @@ adns_status adns__internal_submit(adns_state ads, adns_query *query_r, const typeinfo *typei, vbuf *qumsg_vb, int id, adns_queryflags flags, struct timeval now, - const qcontext *ctx); + qcontext *ctx); /* Submits a query (for internal use, called during external submits). * * The new query is returned in *query_r, or we return adns_s_nomemory. @@ -438,7 +464,8 @@ adns_status adns__internal_submit(adns_state ads, adns_query *query_r, * the memory for it is _taken over_ by this routine whether it * succeeds or fails (if it succeeds, the vbuf is reused for qu->vb). * - * *ctx is copied byte-for-byte into the query. + * *ctx is copied byte-for-byte into the query. Before doing this, its tinfo + * field may be modified by type hooks. * * When the child query is done, ctx->callback will be called. The * child will already have been taken off both the global list of