Simple idea:
I'm using X-macros to define command list structure and declare command callbacks.
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#define COMMAND_LIST(X) \
X(toto_all) \
X(help) \
//end of list
typedef void (*callback_t)(int a, int b);
typedef struct
{
char * name;
callback_t callback;
}command_t;
#define CALLBACK_DEC(COMMAND_NAME) void _##COMMAND_NAME(int a, int b);
COMMAND_LIST(CALLBACK_DEC)
#define COMMAND_DEF(COMMAND_NAME) { #COMMAND_NAME, & _##COMMAND_NAME },
static command_t commands[] =
{
COMMAND_LIST(COMMAND_DEF)
};
#define COMMAND(COMMAND_NAME,CODE) void _##COMMAND_NAME(int A, int B) { CODE }
COMMAND(toto_all,
printf("helloworld\n");
)
COMMAND(help,
printf("help!\n");
)
int main()
{
commands[0].callback(1,2);
commands[1].callback(1,2);
return 0;
}
it works.
helloworld
help!
Adding some parameters:
If you change the first command list to this (by adding parameters)
#define COMMAND_LIST(X) \
X(toto_all, 1, 3, 5) \
X(help, 0, 0, 0) \
//end of list
typedef struct
{
callback_t callback;
char * name;
int arg_min;
int arg_max;
int arg_num;
}command_t;
then, when running it I get the following error:
macro "CALLBACK_DEC" passed 4 arguments, but takes just 1
I have to use all the parameters for the command list definition (command declaration):
#define COMMAND_DEF(COMMAND_NAME, ARG_MIN, ARG_MAX, ARG_MAX, ARG_NUM) (command_t){ #COMMAND_NAME, & _##COMMAND_NAME, ARG_MIN, ARG_MAX, ARG_NUM},
but it's quite tricky to now use it for the callback declaration...
Is there a clever way for this X-macro to avoid this error?
I thought about the non-macro way to mask unused parameters:
which is by using (void)param;
,
which gives the ugly
#define CALLBACK_DEC(COMMAND_NAME, ARG_MIN, ARG_MAX, ARG_NUM) void _##COMMAND_NAME(int a, int b); void(ARG_MIN); void(ARG_MAX); void(ARG_NUM)
and this does not work...I get a strange:
main.c:27:20: error: expected identifier or ‘(’ before numeric constant
X(toto_all,0,0,0) \
I think there is another way:
maybe using something like this...
#define COMMAND_LIST(X,Y) \
X(Y(toto_all, 0, 0, 0)) \
X(Y(help, 0, 0, 0)) \
//command name, arg min, arg max, arg num, string?
//end of list
typedef void (*callback_t)(int a, int b);
typedef struct
{
char * name;
callback_t callback;
}command_t;
#define GET_ONLY_NAME(COMMAND_NAME1, ARG_MIN, ARG_MAX, ARG_NUM) COMMAND_NAME1
#define CALLBACK_DEC(COMMAND_NAME) void _##COMMAND_NAME(int a, int b);
COMMAND_LIST(CALLBACK_DEC,GET_ONLY_NAME);
#undef CALLBACK_DEC
#define GET_FULL_LIST(X) X
#define COMMAND_DEF(COMMAND_NAME, ARG_MIN, ARG_MAX, ARG_NUM) (command_t){ #COMMAND_NAME, & _##COMMAND_NAME, ARG_MIN, ARG_MAX, ARG_NUM},
static command_t commands[] =
{
COMMAND_LIST(COMMAND_DEF,GET_FULL_LIST)
};
#undef COMMAND_DEF
但是我仍然收到以下奇怪的错误,扩展中有问题但我看不到在哪里...
main.c:27:31: error: expected ‘)’ before numeric constant
X(Y(toto_all, 0, 0, 0)) \
也许真相在别处...... :)
任何提示?