Hi there,
I have a list of functions (all with suffix T). For each one, I need
to implement the following:
FunctionT()
{
if (some_condition)
{
// do some conversion first
FunctionW();
// then do some processing
}
else
{
// do some conversion first
FunctionA();
// then do some processing
}
}
The condition check, conversion and processing is the same for all
functions. Any way to use macros to save all the hassle? Or perhaps
with function pointers as well?
You can do this with macros:
--- File Tfunc.ct ---
#if defined FUNCNAME && defined RET_TYPE
#define CONCAT(A,B) A ## B
#define FUNCNAME_T(f) CONCAT(f, T)
#define FUNCNAME_W(f) CONCAT(f, W)
#define FUNCNAME_A(f) CONCAT(f, A)
#ifdef PARAM_LIST
RET_TYPE FUNCNAME_T(FUNCNAME) (PARAM_LIST)
#else
RET_TYPE FUNCNAME_T(FUNCNAME) (void)
#endif
{
if (some_condition)
{
// do some conversion first
#ifdef PARAM_LIST
FUNCNAME_W(FUNCNAME) (ARG_LIST);
#else
FUNCNAME_W(FUNCNAME) ();
#endif
// then do some processing
}
else
{
// do some conversion first
#ifdef PARAM_LIST
FUNCNAME_A(FUNCNAME) (ARG_LIST);
#else
FUNCNAME_A(FUNCNAME) ();
#endif
// then do some processing
}
}
#undef FUNCNAME_T
#undef FUNCNAME_W
#undef FUNCNAME_A
#else
#error FUNCNAME or RET_TYPE not defined
#endif
#undef FUNCNAME
#undef RET_TYPE
#ifdef PARAM_LIST
# undef PARAM_LIST
# undef ARG_LIST
#endif
---------------------
--- funcT.c ---------
#include "prototypes.h" /* prototypes for the A and W functions */
.....
#define FUNCNAME firstfun
#define RET_TYPE int
#include "Tfunc.ct"
#define FUNCNAME secondfun
#define RET_TYPE void
#define PARAM_LIST int a
#define ARG_LIST a
#include "Tfunc.ct"
.....
---------------------
However, this gets nasty when creating the corresponding headerfile
--- funcT.h ---------
.....
int firstfunT (void);
void secondfunT (int a);
.....
---------------------
I would not do this.
I'd rather consider a function pointer solution
typedef int (*AWfunptr)(int);
typedef struct {
AWfunptr Afunc;
AWfunptr Wfunc;
} AWpairing;
int TCall (AWpairing *aw, int arg)
{
if (some_condition)
{
// do some conversion first
(*aw->Wfunc)(arg);
// then do some processing
}
else
{
// do some conversion first
(*aw->Afunc)(arg);
// then do some processing
}
}
.....
Note: As the above snippets are not complete programs, I have
not tested them. Especially for the template solution (the one
with the macros), look at the preprocessor output to see whether
everything is as intended.
Apart from that: // are C++ or C99 style comments
Do not use them for C89 code.
Cheers
Michael