chiark / gitweb /
src/types.c: Rearrange the main typeinfo table.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 31 May 2014 14:24:41 +0000 (15:24 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Fri, 13 Jun 2014 08:57:41 +0000 (09:57 +0100)
Kill XTRA_TYPE, which won't scale at all well as new features are added
to the typeinfo structure.  Instead, allow additional arguments to
FLAT/DEEP_TYPE, which are used to carry designated initializers for the
more unusual fields.

I took the opportunity to factor out some common prefixes in the names
of the functions listed in the table, which gives us some additional
horizontal space.  This will come in useful later.

All of this involves a little nontrivial macrology, now in internal.h.

Signed-off-by: Mark Wooding <mdw@distorted.org.uk>
src/internal.h
src/types.c

index 512a2b1..f459a24 100644 (file)
@@ -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,
index 8bc7155..3765abb 100644 (file)
@@ -1250,45 +1250,46 @@ static void mf_flat(adns_query qu, void *data) { }
 
 #define TYPESZ_M(member)           (sizeof(*((adns_answer*)0)->rrs.member))
 
-#define DEEP_TYPE(code,rrt,fmt,memb,parser,comparer,printer)   \
- { adns_r_##code, rrt,fmt,TYPESZ_M(memb), mf_##memb,           \
-      printer,parser,comparer, adns__qdpl_normal,0 }
-#define FLAT_TYPE(code,rrt,fmt,memb,parser,comparer,printer)   \
- { adns_r_##code, rrt,fmt,TYPESZ_M(memb), mf_flat,             \
-     printer,parser,comparer, adns__qdpl_normal,0 }
-#define XTRA_TYPE(code,rrt,fmt,memb,parser,comparer,printer,qdpl,postsort) \
- { adns_r_##code, rrt,fmt,TYPESZ_M(memb), mf_##memb,                      \
-    printer,parser,comparer,qdpl,postsort }
+#define DEEP_TYPE(code,rrt,fmt,memb,parser,comparer,/*printer*/...)    \
+ { adns_r_##code, rrt,fmt,TYPESZ_M(memb), mf_##memb,                   \
+     GLUE(cs_, CAR(__VA_ARGS__)),pa_##parser,di_##comparer,            \
+     adns__qdpl_normal, CDR(__VA_ARGS__) }
+#define FLAT_TYPE(code,rrt,fmt,memb,parser,comparer,/*printer*/...)    \
+ { adns_r_##code, rrt,fmt,TYPESZ_M(memb), mf_flat,                     \
+     GLUE(cs_, CAR(__VA_ARGS__)),pa_##parser,di_##comparer,            \
+     adns__qdpl_normal, CDR(__VA_ARGS__) }
+
+#define di_0 0
 
 static const typeinfo typeinfos[] = {
 /* Must be in ascending order of rrtype ! */
 /* mem-mgmt code  rrt     fmt   member   parser      comparer  printer */
 
-FLAT_TYPE(a,      "A",     0,   inaddr,  pa_inaddr,  di_inaddr,cs_inaddr     ),
-DEEP_TYPE(ns_raw, "NS",   "raw",str,     pa_host_raw,0,        cs_domain     ),
-DEEP_TYPE(cname,  "CNAME", 0,   str,     pa_dom_raw, 0,        cs_domain     ),
-DEEP_TYPE(soa_raw,"SOA",  "raw",soa,     pa_soa,     0,        cs_soa        ),
-DEEP_TYPE(ptr_raw,"PTR",  "raw",str,     pa_host_raw,0,        cs_domain     ),
-DEEP_TYPE(hinfo,  "HINFO", 0, intstrpair,pa_hinfo,   0,        cs_hinfo      ),
-DEEP_TYPE(mx_raw, "MX",   "raw",intstr,  pa_mx_raw,  di_mx_raw,cs_inthost    ),
-DEEP_TYPE(txt,    "TXT",   0,   manyistr,pa_txt,     0,        cs_txt        ),
-DEEP_TYPE(rp_raw, "RP",   "raw",strpair, pa_rp,      0,        cs_rp         ),
-XTRA_TYPE(srv_raw,"SRV",  "raw",srvraw , pa_srvraw,  di_srv,   cs_srvraw,
-                                                      qdpl_srv, postsort_srv),
-
-FLAT_TYPE(addr,   "A",  "addr", addr,    pa_addr,    di_addr,  cs_addr       ),
-DEEP_TYPE(ns,     "NS", "+addr",hostaddr,pa_hostaddr,di_hostaddr,cs_hostaddr ),
-DEEP_TYPE(ptr,    "PTR","checked",str,   pa_ptr,     0,        cs_domain     ),
-DEEP_TYPE(mx,     "MX", "+addr",inthostaddr,pa_mx,   di_mx,    cs_inthostaddr),
-XTRA_TYPE(srv,    "SRV","+addr",srvha,   pa_srvha,   di_srv,   cs_srvha,
-                                                      qdpl_srv, postsort_srv),
-
-DEEP_TYPE(soa,    "SOA","822",  soa,     pa_soa,     0,        cs_soa        ),
-DEEP_TYPE(rp,     "RP", "822",  strpair, pa_rp,      0,        cs_rp         ),
+FLAT_TYPE(a,      "A",     0,   inaddr,    inaddr,  inaddr,inaddr          ),
+DEEP_TYPE(ns_raw, "NS",   "raw",str,       host_raw,0,     domain          ),
+DEEP_TYPE(cname,  "CNAME", 0,   str,       dom_raw, 0,     domain          ),
+DEEP_TYPE(soa_raw,"SOA",  "raw",soa,       soa,     0,     soa             ),
+DEEP_TYPE(ptr_raw,"PTR",  "raw",str,       host_raw,0,     domain          ),
+DEEP_TYPE(hinfo,  "HINFO", 0,   intstrpair,hinfo,   0,     hinfo           ),
+DEEP_TYPE(mx_raw, "MX",   "raw",intstr,    mx_raw,  mx_raw,inthost         ),
+DEEP_TYPE(txt,    "TXT",   0,   manyistr,  txt,     0,     txt             ),
+DEEP_TYPE(rp_raw, "RP",   "raw",strpair,   rp,      0,     rp              ),
+DEEP_TYPE(srv_raw,"SRV",  "raw",srvraw ,   srvraw,  srv,   srvraw,
+                          .qdparselabel= qdpl_srv, .postsort= postsort_srv),
+
+FLAT_TYPE(addr,   "A",  "addr", addr,      addr,    addr,  addr            ),
+DEEP_TYPE(ns,     "NS", "+addr",hostaddr,  hostaddr,hostaddr,hostaddr      ),
+DEEP_TYPE(ptr,    "PTR","checked",str,     ptr,     0,     domain          ),
+DEEP_TYPE(mx,     "MX", "+addr",inthostaddr,mx,     mx,    inthostaddr,    ),
+DEEP_TYPE(srv,    "SRV","+addr",srvha,     srvha,   srv,   srvha,
+                          .qdparselabel= qdpl_srv, .postsort= postsort_srv),
+
+DEEP_TYPE(soa,    "SOA","822",  soa,       soa,     0,     soa             ),
+DEEP_TYPE(rp,     "RP", "822",  strpair,   rp,      0,     rp              ),
 };
 
 static const typeinfo typeinfo_unknown=
-DEEP_TYPE(unknown,0, "unknown",byteblock,pa_opaque,  0,        cs_opaque     );
+DEEP_TYPE(unknown,0, "unknown",byteblock,opaque,  0,     opaque            );
 
 const typeinfo *adns__findtype(adns_rrtype type) {
   const typeinfo *begin, *end, *mid;