Skip to content

Instantly share code, notes, and snippets.

@Silva97
Created August 19, 2021 16:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Silva97/4704276a3d579fe43c7b153d9f48fe33 to your computer and use it in GitHub Desktop.
Save Silva97/4704276a3d579fe43c7b153d9f48fe33 to your computer and use it in GitHub Desktop.
C macro for print struct's fields
#include <stdio.h>
#include "printstruct.h"
typedef struct
{
int a;
char *b;
char c;
long int d;
long long int e;
unsigned long int f;
unsigned long long int g;
short int h;
unsigned short i;
float sprec;
double dprec;
long double tprec;
void *ptr;
struct
{
int a;
int b;
} sub;
} mytest;
int main(void)
{
mytest test = {
.a = 3,
.b = "test",
.c = 'x',
.sprec = 3.141592f,
.dprec = 81.0,
.tprec = 625.0,
.ptr = "any_value",
.sub = {
.a = 1,
.b = 2,
},
};
PRINT_STRUCT(0, test.sub, a, b);
putchar('\n');
PRINT_STRUCT(0, test, a, b, c, d, e, f, g, h, i, sprec, dprec, tprec, ptr);
return 0;
}
#ifndef _PRINTSTRUCT_H
#define _PRINTSTRUCT_H
#include <stdio.h>
#if __GNUC__ < 8
#define __VA_OPT__(...)
#error "printstruct needs __VA_OPT__ extension to be used. Please compile with GCC 8+."
#endif
#define PRINT_STRUCT(ident, _struct, ...) \
printf("%*c%s {\n", ident + 1, *#_struct, (#_struct) + 1); \
PRINT_STRUCT_1(ident, _struct, __VA_ARGS__); \
printf("%*c\n", ident + 1, '}')
#define PRINT_STRUCT_FIELD(ident, _struct, field) \
printf(" %*c%s", ident + 1, *#field, (#field) + 1); \
printf(MASKTYPE(_struct.field), (int)(25 - sizeof(#field)), ":", _struct.field); \
putchar('\n')
#define MASKTYPE(expr) \
_Generic((expr), \
char * \
: "%*s \"%s\"", \
char \
: "%*s '%c'", \
int \
: "%2$*1$s %3$d (0x%3$x)", \
unsigned int \
: "%2$*1$s %3$u (0x%3$x)", \
short int \
: "%2$*1$s %3$hd (0x%3$hx)", \
unsigned short int \
: "%2$*1$s %3$hd (0x%3$hx)", \
long int \
: "%2$*1$s %3$ld (0x%3$lx)", \
unsigned long int \
: "%2$*1$s %3$ld (0x%3$lx)", \
long long int \
: "%2$*1$s %3$lld (0x%3$llx)", \
unsigned long long int \
: "%2$*1$s %3$lld (0x%3$llx)", \
float \
: "%*s %f", \
double \
: "%*s %f", \
long double \
: "%*s %Lf", \
default \
: "%*s %p")
#define PRINT_STRUCT_1(ident, _struct, _1, ...) \
PRINT_STRUCT_FIELD(ident, _struct, _1); \
__VA_OPT__(PRINT_STRUCT_2(ident, _struct, __VA_ARGS__))
#define PRINT_STRUCT_2(ident, _struct, _1, ...) \
PRINT_STRUCT_FIELD(ident, _struct, _1); \
__VA_OPT__(PRINT_STRUCT_3(ident, _struct, __VA_ARGS__))
#define PRINT_STRUCT_3(ident, _struct, _1, ...) \
PRINT_STRUCT_FIELD(ident, _struct, _1); \
__VA_OPT__(PRINT_STRUCT_4(ident, _struct, __VA_ARGS__))
#define PRINT_STRUCT_4(ident, _struct, _1, ...) \
PRINT_STRUCT_FIELD(ident, _struct, _1); \
__VA_OPT__(PRINT_STRUCT_5(ident, _struct, __VA_ARGS__))
#define PRINT_STRUCT_5(ident, _struct, _1, ...) \
PRINT_STRUCT_FIELD(ident, _struct, _1); \
__VA_OPT__(PRINT_STRUCT_6(ident, _struct, __VA_ARGS__))
#define PRINT_STRUCT_6(ident, _struct, _1, ...) \
PRINT_STRUCT_FIELD(ident, _struct, _1); \
__VA_OPT__(PRINT_STRUCT_7(ident, _struct, __VA_ARGS__))
#define PRINT_STRUCT_7(ident, _struct, _1, ...) \
PRINT_STRUCT_FIELD(ident, _struct, _1); \
__VA_OPT__(PRINT_STRUCT_8(ident, _struct, __VA_ARGS__))
#define PRINT_STRUCT_8(ident, _struct, _1, ...) \
PRINT_STRUCT_FIELD(ident, _struct, _1); \
__VA_OPT__(PRINT_STRUCT_9(ident, _struct, __VA_ARGS__))
#define PRINT_STRUCT_9(ident, _struct, _1, ...) \
PRINT_STRUCT_FIELD(ident, _struct, _1); \
__VA_OPT__(PRINT_STRUCT_10(ident, _struct, __VA_ARGS__))
#define PRINT_STRUCT_10(ident, _struct, _1, ...) \
PRINT_STRUCT_FIELD(ident, _struct, _1); \
__VA_OPT__(PRINT_STRUCT_11(ident, _struct, __VA_ARGS__))
#define PRINT_STRUCT_11(ident, _struct, _1, ...) \
PRINT_STRUCT_FIELD(ident, _struct, _1); \
__VA_OPT__(PRINT_STRUCT_12(ident, _struct, __VA_ARGS__))
#define PRINT_STRUCT_12(ident, _struct, _1, ...) \
PRINT_STRUCT_FIELD(ident, _struct, _1); \
__VA_OPT__(PRINT_STRUCT_13(ident, _struct, __VA_ARGS__))
#define PRINT_STRUCT_13(ident, _struct, _1, ...) \
PRINT_STRUCT_FIELD(ident, _struct, _1); \
__VA_OPT__(PRINT_STRUCT_14(ident, _struct, __VA_ARGS__))
#define PRINT_STRUCT_14(ident, _struct, _1, ...) \
PRINT_STRUCT_FIELD(ident, _struct, _1); \
__VA_OPT__(PRINT_STRUCT_15(ident, _struct, __VA_ARGS__))
#define PRINT_STRUCT_15(ident, _struct, _1, ...) \
PRINT_STRUCT_FIELD(ident, _struct, _1); \
__VA_OPT__(PRINT_STRUCT_16(ident, _struct, __VA_ARGS__))
#define PRINT_STRUCT_16(ident, _struct, _1, ...) \
PRINT_STRUCT_FIELD(ident, _struct, _1)
#endif /* _PRINTSTRUCT_H */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment