On Wed, May 11, 2011 at 14:13:29 -0600, Eric Blake wrote: > This one's tricker than the VIR_DEBUG0() removal, but the end > result is still C99 compliant, and reasonable with enough comments. > > * src/libvirt.c (VIR_ARG10, VIR_HAS_COMMA) > (VIR_DOMAIN_DEBUG_EXPAND, VIR_DOMAIN_DEBUG_PASTE): New macros. > (VIR_DOMAIN_DEBUG): Rewrite to handle one argument, moving > multi-argument guts to... > (VIR_DOMAIN_DEBUG_1): New macro. > (VIR_DOMAIN_DEBUG0): Rename to VIR_DOMAIN_DEBUG_0. > --- > > This one was much tougher, because both fmt and its arguments were > optional, and because the expansion does not stick fmt next to > __VA_ARGS__. But the end result is still that you can blindly > use VIR_DOMAIN_DEBUG with 1 or 3+ arguments, and get the right > behavior automagically, instead of having to remember to call > a different macro for the 1-arg case. > > I specifically did not cater to the 2-arg case; that would be > easy enough to support, though, if we had a reason for it. > > src/libvirt.c | 67 +++++++++++++++++++++++++++++++++++++++----------------- > 1 files changed, 46 insertions(+), 21 deletions(-) > > diff --git a/src/libvirt.c b/src/libvirt.c > index 13cb74a..79278b9 100644 > --- a/src/libvirt.c > +++ b/src/libvirt.c > @@ -311,10 +311,26 @@ static struct gcry_thread_cbs virTLSThreadImpl = { > NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL > }; > > -/* Helper macro to print debugging information about a domain DOM, > - * followed by a literal string FMT and any other printf arguments. > - */ > -#define VIR_DOMAIN_DEBUG(dom, fmt, ...) \ > +/* Helper macros to implement VIR_DOMAIN_DEBUG using just C99. This > + * assumes you pass fewer than 10 arguments to VIR_DOMAIN_DEBUG, but > + * can easily be expanded if needed. */ > +#define VIR_ARG10(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, ...) _10 > +#define VIR_HAS_COMMA(...) VIR_ARG10(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 0) > + > +/* Form the name VIR_DOMAIN_DEBUG_[01], then call that macro, > + * according to how many arguments are present. Two-phase due to > + * macro expansion rules. */ > +#define VIR_DOMAIN_DEBUG_EXPAND(a, b, ...) \ > + VIR_DOMAIN_DEBUG_PASTE(a, b, __VA_ARGS__) > +#define VIR_DOMAIN_DEBUG_PASTE(a, b, ...) \ > + a##b(__VA_ARGS__) > + > +/* Internal use only, when VIR_DOMAIN_DEBUG has one argument. */ > +#define VIR_DOMAIN_DEBUG_0(dom) \ > + VIR_DOMAIN_DEBUG_1(dom, "%s", "") > + > +/* Internal use only, when VIR_DOMAIN_DEBUG has three or more arguments. */ > +#define VIR_DOMAIN_DEBUG_1(dom, fmt, ...) \ > char _uuidstr[VIR_UUID_STRING_BUFLEN]; \ > const char *_domname = NULL; \ > \ Personally I would prefer this macro to be ``do { ... } while (0)'' but that a preexisting issue and given that it's only used at the beginning of functions I guess I can live without this modification. Heh, that's a pure ugliness. But at least it's a self-contained ugliness and serves a good purpose. ACK Jirka -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list