Here's a proof of concept:
#include <stdio.h>
#include <string.h>
#define MEMBER(TYPE,NAME,MORE) TYPE NAME MORE
#define TSTRUCT(NAME,MEMBERS)
typedef struct NAME {
MEMBERS
} NAME;
const char* const NAME##_Members = #MEMBERS;
#define PRINT_STRUCT_MEMBERS(NAME) printStructMembers(NAME##_Members)
TSTRUCT(S,
MEMBER(int,x;,
MEMBER(void*,z[2];,
MEMBER(char,(*f)(char,char);,
MEMBER(char,y;,
)))));
void printStructMembers(const char* Members)
{
int level = 0;
int lastLevel = 0;
const char* p;
const char* pLastType = NULL;
const char* pLastTypeEnd = NULL;
for (p = Members; *p; p++)
{
if (strstr(p, "MEMBER(") == p)
{
p += 6; // strlen("MEMBER")
level++;
lastLevel = level;
pLastType = p + 1;
}
else if (*p == '(')
{
level++;
}
else if (*p == ')')
{
level--;
}
else if (*p == ',')
{
if (level == lastLevel)
{
if ((pLastType != NULL) && (pLastTypeEnd == NULL))
{
pLastTypeEnd = p;
}
}
}
else if (strstr(p, ";,") == p)
{
if ((pLastType != NULL) && (pLastTypeEnd != NULL))
{
const char* pp;
printf("[");
for (pp = pLastType; pp < pLastTypeEnd; pp++)
printf("%c", *pp); // print type
printf("] [");
for (pp = pLastTypeEnd + 1; pp < p; pp++)
printf("%c", *pp); // print name
printf("]
");
}
pLastType = pLastTypeEnd = NULL;
}
}
}
char fadd(char a, char b)
{
return a + b;
}
S s =
{
1,
{ NULL, NULL },
&fadd,
'a'
};
int main(void)
{
PRINT_STRUCT_MEMBERS(S);
return 0;
}
This is it's output:
[int] [x]
[void*] [z[2]]
[char] [(*f)(char,char)]
[char] [y]
You can improve it to better support more complex member types and to actually build a list of names of the members.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…