Last active
December 16, 2015 12:49
-
-
Save hildjj/5437270 to your computer and use it in GitHub Desktop.
Generate enums and their string versions.
This file contains hidden or 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 ENUM_H | |
#define ENUM_H | |
#include <stddef.h> | |
#include <string.h> | |
#include <stdbool.h> | |
/* Entry points */ | |
/* Define an enum, suitable for putting in a .h file */ | |
#define ENUM(NAME,...) SENUM(,NAME,__VA_ARGS__) | |
/* Implement functions for the given enum; put this in exactly one .c file */ | |
#define ENUM_IMPL(NAME) SENUM_IMPL(,NAME) | |
/* Both of the above, set up for static use in a single .c file */ | |
#define STATIC_ENUM(NAME, ...) SENUM(static,NAME, __VA_ARGS__) SENUM_IMPL(static,NAME) | |
/* implementation */ | |
#define VSTR_1(a) #a | |
#define VSTR_2(a,...) #a, VSTR_1(__VA_ARGS__) | |
#define VSTR_3(a,...) #a, VSTR_2(__VA_ARGS__) | |
#define VSTR_4(a,...) #a, VSTR_3(__VA_ARGS__) | |
#define VSTR_5(a,...) #a, VSTR_4(__VA_ARGS__) | |
#define VSTR_6(a,...) #a, VSTR_5(__VA_ARGS__) | |
#define VSTR_7(a,...) #a, VSTR_6(__VA_ARGS__) | |
#define VSTR_8(a,...) #a, VSTR_7(__VA_ARGS__) | |
#define VSTR_9(a,...) #a, VSTR_8(__VA_ARGS__) | |
#define VSTR_10(a,...) #a, VSTR_9(__VA_ARGS__) | |
#define VSTR_11(a,...) #a, VSTR_10(__VA_ARGS__) | |
#define VSTR_12(a,...) #a, VSTR_11(__VA_ARGS__) | |
#define VSTR_13(a,...) #a, VSTR_12(__VA_ARGS__) | |
#define VSTR_14(a,...) #a, VSTR_13(__VA_ARGS__) | |
#define VSTR_15(a,...) #a, VSTR_14(__VA_ARGS__) | |
#define VSTR_16(a,...) #a, VSTR_15(__VA_ARGS__) | |
#define VSTR_17(a,...) #a, VSTR_16(__VA_ARGS__) | |
#define VSTR_18(a,...) #a, VSTR_17(__VA_ARGS__) | |
#define VSTR_19(a,...) #a, VSTR_18(__VA_ARGS__) | |
#define VSTR_20(a,...) #a, VSTR_19(__VA_ARGS__) | |
#define VSTR_21(a,...) #a, VSTR_20(__VA_ARGS__) | |
#define VSTR_22(a,...) #a, VSTR_21(__VA_ARGS__) | |
#define VSTR_23(a,...) #a, VSTR_22(__VA_ARGS__) | |
#define VSTR_24(a,...) #a, VSTR_23(__VA_ARGS__) | |
#define VSTR_25(a,...) #a, VSTR_24(__VA_ARGS__) | |
#define VSTR_26(a,...) #a, VSTR_25(__VA_ARGS__) | |
#define VSTR_27(a,...) #a, VSTR_26(__VA_ARGS__) | |
#define VSTR_28(a,...) #a, VSTR_27(__VA_ARGS__) | |
#define VSTR_29(a,...) #a, VSTR_28(__VA_ARGS__) | |
#define VSTR_30(a,...) #a, VSTR_29(__VA_ARGS__) | |
#define VSTR_31(a,...) #a, VSTR_30(__VA_ARGS__) | |
#define VSTR_32(a,...) #a, VSTR_31(__VA_ARGS__) | |
#define VSTR_33(a,...) #a, VSTR_32(__VA_ARGS__) | |
#define VSTR_34(a,...) #a, VSTR_33(__VA_ARGS__) | |
#define VSTR_35(a,...) #a, VSTR_34(__VA_ARGS__) | |
#define VSTR_36(a,...) #a, VSTR_35(__VA_ARGS__) | |
#define VSTR_37(a,...) #a, VSTR_36(__VA_ARGS__) | |
#define VSTR_38(a,...) #a, VSTR_37(__VA_ARGS__) | |
#define VSTR_39(a,...) #a, VSTR_38(__VA_ARGS__) | |
#define VSTR_40(a,...) #a, VSTR_39(__VA_ARGS__) | |
#define VSTR_41(a,...) #a, VSTR_40(__VA_ARGS__) | |
#define VSTR_42(a,...) #a, VSTR_41(__VA_ARGS__) | |
#define VSTR_43(a,...) #a, VSTR_42(__VA_ARGS__) | |
#define VSTR_44(a,...) #a, VSTR_43(__VA_ARGS__) | |
#define VSTR_45(a,...) #a, VSTR_44(__VA_ARGS__) | |
#define VSTR_46(a,...) #a, VSTR_45(__VA_ARGS__) | |
#define VSTR_47(a,...) #a, VSTR_46(__VA_ARGS__) | |
#define VSTR_48(a,...) #a, VSTR_47(__VA_ARGS__) | |
#define VSTR_49(a,...) #a, VSTR_48(__VA_ARGS__) | |
#define VSTR_50(a,...) #a, VSTR_49(__VA_ARGS__) | |
#define VSTR_51(a,...) #a, VSTR_50(__VA_ARGS__) | |
#define VSTR_52(a,...) #a, VSTR_51(__VA_ARGS__) | |
#define VSTR_53(a,...) #a, VSTR_52(__VA_ARGS__) | |
#define VSTR_54(a,...) #a, VSTR_53(__VA_ARGS__) | |
#define VSTR_55(a,...) #a, VSTR_54(__VA_ARGS__) | |
#define VSTR_56(a,...) #a, VSTR_55(__VA_ARGS__) | |
#define VSTR_57(a,...) #a, VSTR_56(__VA_ARGS__) | |
#define VSTR_58(a,...) #a, VSTR_57(__VA_ARGS__) | |
#define VSTR_59(a,...) #a, VSTR_58(__VA_ARGS__) | |
#define VSTR_60(a,...) #a, VSTR_59(__VA_ARGS__) | |
#define VSTR_61(a,...) #a, VSTR_60(__VA_ARGS__) | |
#define VSTR_62(a,...) #a, VSTR_61(__VA_ARGS__) | |
#define VSTR_63(a,...) #a, VSTR_62(__VA_ARGS__) | |
#define VSTR_64(a,...) #a, VSTR_63(__VA_ARGS__) | |
#define VSTR_65(a,...) #a, VSTR_64(__VA_ARGS__) | |
#define VSTR_66(a,...) #a, VSTR_65(__VA_ARGS__) | |
#define VSTR_67(a,...) #a, VSTR_66(__VA_ARGS__) | |
#define VSTR_68(a,...) #a, VSTR_67(__VA_ARGS__) | |
#define VSTR_69(a,...) #a, VSTR_68(__VA_ARGS__) | |
#define VSTR_70(a,...) #a, VSTR_69(__VA_ARGS__) | |
#define VSTR_71(a,...) #a, VSTR_70(__VA_ARGS__) | |
#define VSTR_72(a,...) #a, VSTR_71(__VA_ARGS__) | |
#define VSTR_73(a,...) #a, VSTR_72(__VA_ARGS__) | |
#define VSTR_74(a,...) #a, VSTR_73(__VA_ARGS__) | |
#define VSTR_75(a,...) #a, VSTR_74(__VA_ARGS__) | |
#define VSTR_76(a,...) #a, VSTR_75(__VA_ARGS__) | |
#define VSTR_77(a,...) #a, VSTR_76(__VA_ARGS__) | |
#define VSTR_78(a,...) #a, VSTR_77(__VA_ARGS__) | |
#define VSTR_79(a,...) #a, VSTR_78(__VA_ARGS__) | |
#define VSTR_80(a,...) #a, VSTR_79(__VA_ARGS__) | |
#define VSTR_81(a,...) #a, VSTR_80(__VA_ARGS__) | |
#define VSTR_82(a,...) #a, VSTR_81(__VA_ARGS__) | |
#define VSTR_83(a,...) #a, VSTR_82(__VA_ARGS__) | |
#define VSTR_84(a,...) #a, VSTR_83(__VA_ARGS__) | |
#define VSTR_85(a,...) #a, VSTR_84(__VA_ARGS__) | |
#define VSTR_86(a,...) #a, VSTR_85(__VA_ARGS__) | |
#define VSTR_87(a,...) #a, VSTR_86(__VA_ARGS__) | |
#define VSTR_88(a,...) #a, VSTR_87(__VA_ARGS__) | |
#define VSTR_89(a,...) #a, VSTR_88(__VA_ARGS__) | |
#define VSTR_90(a,...) #a, VSTR_89(__VA_ARGS__) | |
#define VSTR_91(a,...) #a, VSTR_90(__VA_ARGS__) | |
#define VSTR_92(a,...) #a, VSTR_91(__VA_ARGS__) | |
#define VSTR_93(a,...) #a, VSTR_92(__VA_ARGS__) | |
#define VSTR_94(a,...) #a, VSTR_93(__VA_ARGS__) | |
#define VSTR_95(a,...) #a, VSTR_94(__VA_ARGS__) | |
#define VSTR_96(a,...) #a, VSTR_95(__VA_ARGS__) | |
#define VSTR_97(a,...) #a, VSTR_96(__VA_ARGS__) | |
#define VSTR_98(a,...) #a, VSTR_97(__VA_ARGS__) | |
#define VSTR_99(a,...) #a, VSTR_98(__VA_ARGS__) | |
#define VSTR_100(a,...) #a, VSTR_99(__VA_ARGS__) | |
#define VSTR_101(a,...) #a, VSTR_100(__VA_ARGS__) | |
#define VSTR_102(a,...) #a, VSTR_101(__VA_ARGS__) | |
#define VSTR_103(a,...) #a, VSTR_102(__VA_ARGS__) | |
#define VSTR_104(a,...) #a, VSTR_103(__VA_ARGS__) | |
#define VSTR_105(a,...) #a, VSTR_104(__VA_ARGS__) | |
#define VSTR_106(a,...) #a, VSTR_105(__VA_ARGS__) | |
#define VSTR_107(a,...) #a, VSTR_106(__VA_ARGS__) | |
#define VSTR_108(a,...) #a, VSTR_107(__VA_ARGS__) | |
#define VSTR_109(a,...) #a, VSTR_108(__VA_ARGS__) | |
#define VSTR_110(a,...) #a, VSTR_109(__VA_ARGS__) | |
#define VSTR_111(a,...) #a, VSTR_110(__VA_ARGS__) | |
#define VSTR_112(a,...) #a, VSTR_111(__VA_ARGS__) | |
#define VSTR_113(a,...) #a, VSTR_112(__VA_ARGS__) | |
#define VSTR_114(a,...) #a, VSTR_113(__VA_ARGS__) | |
#define VSTR_115(a,...) #a, VSTR_114(__VA_ARGS__) | |
#define VSTR_116(a,...) #a, VSTR_115(__VA_ARGS__) | |
#define VSTR_117(a,...) #a, VSTR_116(__VA_ARGS__) | |
#define VSTR_118(a,...) #a, VSTR_117(__VA_ARGS__) | |
#define VSTR_119(a,...) #a, VSTR_118(__VA_ARGS__) | |
#define VSTR_120(a,...) #a, VSTR_119(__VA_ARGS__) | |
#define VSTR_121(a,...) #a, VSTR_120(__VA_ARGS__) | |
#define VSTR_122(a,...) #a, VSTR_121(__VA_ARGS__) | |
#define VSTR_123(a,...) #a, VSTR_122(__VA_ARGS__) | |
#define VSTR_124(a,...) #a, VSTR_123(__VA_ARGS__) | |
#define VSTR_125(a,...) #a, VSTR_124(__VA_ARGS__) | |
#define VSTR_126(a,...) #a, VSTR_125(__VA_ARGS__) | |
#define VSTR_127(a,...) #a, VSTR_126(__VA_ARGS__) | |
#define VSTR_128(a,...) #a, VSTR_127(__VA_ARGS__) | |
#define _NUM_ARGS2(X,X128,X127,X126,X125,X124,X123,X122,X121,X120,X119,X118,X117,X116,X115,X114,X113,X112,X111,X110,X109,X108,X107,X106,X105,X104,X103,X102,X101,X100,X99,X98,X97,X96,X95,X94,X93,X92,X91,X90,X89,X88,X87,X86,X85,X84,X83,X82,X81,X80,X79,X78,X77,X76,X75,X74,X73,X72,X71,X70,X69,X68,X67,X66,X65,X64,X63,X62,X61,X60,X59,X58,X57,X56,X55,X54,X53,X52,X51,X50,X49,X48,X47,X46,X45,X44,X43,X42,X41,X40,X39,X38,X37,X36,X35,X34,X33,X32,X31,X30,X29,X28,X27,X26,X25,X24,X23,X22,X21,X20,X19,X18,X17,X16,X15,X14,X13,X12,X11,X10,X9,X8,X7,X6,X5,X4,X3,X2,X1,N,...) N | |
#define NUM_ARGS(...) _NUM_ARGS2(0, __VA_ARGS__ ,128,127,126,125,124,123,122,121,120,119,118,117,116,115,114,113,112,111,110,109,108,107,106,105,104,103,102,101,100,99,98,97,96,95,94,93,92,91,90,89,88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70,69,68,67,66,65,64,63,62,61,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0) | |
#define _VSTR_N3(N, ...) VSTR_ ## N(__VA_ARGS__) | |
#define _VSTR_N2(N, ...) _VSTR_N3(N, __VA_ARGS__) | |
#define VSTR_N(...) _VSTR_N2(NUM_ARGS(__VA_ARGS__), __VA_ARGS__) | |
#define SENUM(st,NAME,...) \ | |
enum NAME { \ | |
__VA_ARGS__, LAST_##NAME \ | |
}; \ | |
st const char *NAME##_names[] = {\ | |
VSTR_N(__VA_ARGS__), \ | |
NULL \ | |
}; \ | |
st bool is_valid_##NAME(enum NAME val); \ | |
st const char *NAME ## _to_string(enum NAME val); \ | |
st enum NAME string_to_ ## NAME(const char *str); | |
#define SENUM_IMPL(st,NAME) \ | |
st bool is_valid_##NAME(enum NAME val) { return (val >= 0) && (val < LAST_##NAME); } \ | |
st const char *NAME ## _to_string(enum NAME val) { \ | |
if (!is_valid_##NAME(val)) { \ | |
return "Unknown value for " #NAME; \ | |
} \ | |
return NAME##_names[val]; \ | |
} \ | |
st enum NAME string_to_ ## NAME(const char *str) { \ | |
int i; \ | |
for (i=0; i<LAST_##NAME; i++) { \ | |
if (strcmp(NAME##_names[i], str) == 0) { \ | |
return i; \ | |
} \ | |
}\ | |
return -1; \ | |
} | |
#endif /* ENUM_H */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uses the approach from http://stackoverflow.com/a/5048661/8388. Invoke like this:
Where "foo" is the name of the enum, and A, B, and C are the values.