Created
August 19, 2021 16:35
-
-
Save Silva97/4704276a3d579fe43c7b153d9f48fe33 to your computer and use it in GitHub Desktop.
C macro for print struct's fields
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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