Skip to content

Instantly share code, notes, and snippets.

@xor-gate
Last active November 26, 2015 19:23
Show Gist options
  • Save xor-gate/e917624e5248a1f175cf to your computer and use it in GitHub Desktop.
Save xor-gate/e917624e5248a1f175cf to your computer and use it in GitHub Desktop.
xmacro-codegen

X-Macros Code Generator in C11

Because we can and the C-preprocessor is wasting CPU cycles anyway

#include <stdio.h>
#include "obj.h"
int main(void)
{
struct coordinate a;
struct blaat b;
struct big c;
a.x = 1;
a.y = 2;
a.z = 3;
b.coord = &a;
OBJ_SERIALIZE(&a);
OBJ_SERIALIZE(&b);
OBJ_SERIALIZE(&c);
return 0;
}
CFLAGS:=-Wall -Wextra -std=c11
main: main.c obj.def obj.h
clang $(CFLAGS) -o main main.c
main.c.pp: main.c obj.def obj.h
clang $(CFLAGS) -E -P main.c > main.c.pp
test: main
./main
clean:
rm -f main main.c.pp
#ifndef OBJ_SERIALIZE
#define OBJ_SERIALIZE(x) \
_Generic((x), \
struct big *: big_serialize, \
struct coordinate *: coordinate_serialize, \
struct blaat *: blaat_serialize, \
uint8_t: obj_serialize_u8, \
uint16_t: obj_serialize_u16, \
uint32_t: obj_serialize_u32 \
)(x)
#endif
OBJ_DECL(big)
OBJ_MEMBER(uint8_t, a)
OBJ_MEMBER(uint16_t, b)
OBJ_MEMBER(uint32_t, c)
OBJ_DECL_END()
OBJ_DECL(coordinate)
OBJ_MEMBER(uint32_t, x)
OBJ_MEMBER(uint32_t, y)
OBJ_MEMBER(uint32_t, z)
OBJ_DECL_END()
OBJ_DECL(blaat)
OBJ_MEMBER(uint16_t, uid)
OBJ_MEMBER(struct coordinate *, coord)
OBJ_DECL_END()
#include <stdint.h>
#ifndef OBJ_H_
#define OBJ_H_
#define OBJ_XSTR(s) OBJ_STR(s)
#define OBJ_STR(s) #s
/* Start with macro declaration */
#ifndef OBJ_PP_DECLARE
#define OBJ_PP_DECLARE
#endif
/* Generate structs */
#define OBJ_DECL(name) \
struct name {
#define OBJ_MEMBER(type, name) type name;
#define OBJ_DECL_END() \
};
#include "obj.h"
#include "obj.def"
#include "obj.h"
void obj_serialize_u8(uint8_t v){ (void)v; printf("\t-> %s (%u)\n", __func__, v);}
void obj_serialize_u16(uint16_t v){ (void)v; printf("\t-> %s (%u)\n", __func__, v);}
void obj_serialize_u32(uint32_t v){ (void)v; printf("\t-> %s (%u)\n", __func__, v);}
/* Generate functions */
#define OBJ_DECL(name) \
void name##_serialize(struct name *val) \
{ \
(void)val; \
if (!val)\
return;\
\
printf("func: %s (struct %s)\n", __func__, OBJ_STR(name));
#define OBJ_MEMBER(type, name) \
printf("\tmember %s %s", OBJ_STR(type), OBJ_STR(name)); \
OBJ_SERIALIZE(val->name);
#define OBJ_DECL_END() \
}
#include "obj.h"
#include "obj.def"
#include "obj.h"
#endif
#ifdef OBJ_PP_DECLARE
# ifndef OBJ_DECL
# define OBJ_DECL(name)
# endif
# ifndef OBJ_MEMBER
# define OBJ_MEMBER(type, name)
# endif
# ifndef OBJ_DECL_END
# define OBJ_DECL_END()
# endif
#undef OBJ_PP_DECLARE
#else
# ifdef OBJ_DECL
# undef OBJ_DECL
# endif
# ifdef OBJ_MEMBER
# undef OBJ_MEMBER
# endif
# ifdef OBJ_DECL_END
# undef OBJ_DECL_END
# endif
#define OBJ_PP_DECLARE
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment