I have a macro for checking results of some test methods:
#define Eval(func, ...) if (func == -1) { printf(__VA_ARGS__); return -1; }
I want to get this functionally:
Eval(Check_1(),"Check1 failed."); // case 1
Eval(Check_2()); // case 2
Eval(Check_3(), "some variable=%i", variableValue); // case 3
At case 1 I want to write comment to user ("Check1 failed") and then return -1 (it's work). At case 2 I just want to return from method, not print any information for user. So I must to detect situation of empty comment and not to call printf() - it's not work.
If any of "Check_x" methods failed, i need exit from current method by return code -1;
Is it any way to do this with macro?
Very similar question was here: Standard alternative to GCC's ##VA_ARGS trick? , but I can't modify this code for my situation.
EDIT: I use C99 standart. At current version of my code case 2 compiled with error "expected an expression" (I think it because of comma and empty argument). Also I need to use case 3 for print additional information (variable values). So, second argument not actually simple string.
EDIT2: I get solution for my task. Here I find it
// Macro to count of arguments
#define VA_NUM_ARGS(...) VA_NUM_ARGS_IMPL(__VA_ARGS__, 10,9,8,7,6,5,4,3,2,1)
#define VA_NUM_ARGS_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,N,...) N
// Macro dispatcher
#define macro_dispatcher(func, ...) macro_dispatcher_(func, VA_NUM_ARGS(__VA_ARGS__))
#define macro_dispatcher_(func, nargs) macro_dispatcher__(func, nargs)
#define macro_dispatcher__(func, nargs) func ## nargs
#define EVAL_UNIVERSAL(...) macro_dispatcher(EV, __VA_ARGS__)(__VA_ARGS__)
#define EV1(func) if (func == -1) return -1;
#define EV2(func, ...) if (func == -1) { printf(__VA_ARGS__); return -1; }
#define EV3(func, ...) EV2(func, __VA_ARGS__)
#define EV4(func, ...) EV2(func, __VA_ARGS__)
#define EV5(func, ...) EV2(func, __VA_ARGS__)
#define EV6(func, ...) EV2(func, __VA_ARGS__)
#define EV7(func, ...) EV2(func, __VA_ARGS__)
And I use it like this:
EVAL_UNIVERSAL(CheckInitialParameters());
EVAL_UNIVERSAL(CheckInitialParameters(), "text");
EVAL_UNIVERSAL(CheckInitialParameters(), "%i", 1);
EVAL_UNIVERSAL(CheckInitialParameters(), "%i %i", 1, 2);
Very thanks to Jens Gustedt, and rmn (http://efesx.com/)