#ifndef EE_DEBUG_H #define EE_DEBUG_H #define _ee_debug_EXPAND(...) __VA_ARGS__ #define _ee_debug_CONCAT_(x, y) x##y #define _ee_debug_CONCAT(x, y) _ee_debug_CONCAT_(x, y) #define _ee_debug_SWITCH_( \ w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, wa, wb, wc, wd, we, wf, \ x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, xa, xb, xc, xd, xe, xf, \ y0, y1, y2, y3, y4, y5, y6, y7, y8, y9, ya, yb, yc, yd, ye, yf, \ z0, z1, z2, z3, z4, z5, z6, z7, z8, z9, za, zb, zc, zd, ze, zf, ...) zf #define _ee_debug_SWITCH(cond, a, b) _ee_debug_CONCAT(_ee_debug_CASE_, \ _ee_debug_SWITCH_(cond, \ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, ))(a, b) #define _ee_debug_CASE_0(a, b) b #define _ee_debug_CASE_1(a, b) a /* for one extra arg */ #define _ee_debug_ADD_afterfirst(x, y) y, x #define _ee_debug_INSERT_afterfirst(x, y, ...) y, x, __VA_ARGS__ #define _ee_debug_NIP_afterfirst(x, ...) \ _ee_debug_CONCAT(_ee_debug_SWITCH(_ee_debug_EXPAND(__VA_ARGS__), \ _ee_debug_INSERT, _ee_debug_ADD), _afterfirst)(x, __VA_ARGS__) /* use for two extra args */ #define _ee_debug_ADD_aftersecond(x, y, z) z, x, y #define _ee_debug_INSERT_aftersecond(x, y, z, ...) z, x, y, __VA_ARGS__ #define _ee_debug_NIP_aftersecond(x, y, ...) \ _ee_debug_CONCAT(_ee_debug_SWITCH(_ee_debug_EXPAND(__VA_ARGS__), \ _ee_debug_INSERT, _ee_debug_ADD), _aftersecond)(x, y, __VA_ARGS__) #define TEST1(...) fprintf(stderr, "TEST1:%s():%d:" \ _ee_debug_NIP_aftersecond(__func__, __LINE__, __VA_ARGS__)) #define TEST2(...) fprintf(stderr, "TEST2:%d:" \ _ee_debug_NIP_afterfirst(__LINE__, __VA_ARGS__)) /* Usage: * * TEST1("Test\n"); * TEST1("%s %s\n", "Hello", "World"); * TEST1("%d %d %d\n", 1, 2, 3); * TEST1("%g %g %g %g\n", 1e1, 1e2, 1e3, 1e4); * * TEST2("Test\n"); * TEST2("%s %s\n", "Hello", "World"); * TEST2("%d %d %d\n", 1, 2, 3); * TEST2("%g %g %g %g\n", 1e1, 1e2, 1e3, 1e4); */ #endif