I have no idea if this will work with other compilers, but here goes...

This little bit of GNU CPP trickery allows the _sendv() macro in
id/libid.c to be used as arguments to itself.

_sendv_RCV_ARGS() tricks GNU CPP into macro-expansion on its output
after the varargs interpolation.

This technique could also be applied to idc-generated code, instead of
using oop temporaries.


=====================================================================
Your line-wraps may vary:

 diff -r d03aca954284 object/id/libid.c
--- a/object/id/libid.c Mon Apr 14 20:50:40 2008 -0600
+++ b/object/id/libid.c Fri Jun 06 00:29:31 2008 -0500
@@ -73,10 +73,30 @@
 void              _libid_leave(void *cookie);
 char             *_libid_backtrace(void);

+#if 1
+#define _sendv_RCV(RCV, ARGS...)RCV
+#define _sendv_ARGS(RCV, ARGS...)ARGS
+#define _sendv_RCV_ARGS(RCV, EATEN, ARGS...)RCV, ##ARGS
+#define _sendv(MSG, N, RCV_AND_ARGS...) ({                     \
+  struct __send _s= { (MSG), (N), _sendv_RCV(RCV_AND_ARGS) };     \
+  ((_imp_t)(_libid_bindv(&_s)))(&_s, _s.receiver,
_sendv_RCV_ARGS(_s.receiver, RCV_AND_ARGS)); \
+})
+
+#ifdef _sendv_ARGS_TEST
+XXXX
+_sendv(msg1, 1, rcv1);
+_sendv(msg2, 2, rcv2, arg2);
+_sendv(msg3, 3, rcv3, arg3, args4);
+_sendv(msg4, 2, rcv4, _sendv(msg5, 1, rcv5));
+_sendv(msg5, 1, _sendv(msg6, 1, rcv6));
+#endif
+
+#else
 #define _sendv(MSG, N, RCV, ARG...) ({                         \
   struct __send _s= { (MSG), (N), (RCV) };                     \
   ((_imp_t)(_libid_bindv(&_s)))(&_s, _s.receiver, _s.receiver, ##ARG);\
 })
+#endif


=====================================================================
Example CPP output:

  > cc -E -D_sendv_ARGS_TEST=1 -I. id/libid.c | grep -A 6 XXXX
XXXX
({ struct __send _s= { (msg1), (1), rcv1 };
((_imp_t)(_libid_bindv(&_s)))(&_s, _s.receiver, _s.receiver); });
({ struct __send _s= { (msg2), (2), rcv2 };
((_imp_t)(_libid_bindv(&_s)))(&_s, _s.receiver, _s.receiver, arg2); });
({ struct __send _s= { (msg3), (3), rcv3 };
((_imp_t)(_libid_bindv(&_s)))(&_s, _s.receiver, _s.receiver, arg3,
args4); });
({ struct __send _s= { (msg4), (2), rcv4 };
((_imp_t)(_libid_bindv(&_s)))(&_s, _s.receiver, _s.receiver,({ struct
__send _s= { (msg5), (1), rcv5 }; ((_imp_t)(_libid_bindv(&_s)))(&_s,
_s.receiver, _s.receiver); })); });
({ struct __send _s= { (msg5), (1), ({ struct __send _s= { (msg6), (1),
rcv6 }; ((_imp_t)(_libid_bindv(&_s)))(&_s, _s.receiver, _s.receiver); })
}; ((_imp_t)(_libid_bindv(&_s)))(&_s, _s.receiver, _s.receiver); });
# 101 "id/libid.c"

=====================================================================

Kurt Stephens
http://kurtstephens.com/


_______________________________________________
fonc mailing list
[email protected]
http://vpri.org/mailman/listinfo/fonc

Reply via email to