自分用
common.h
#ifndef __COMMON_H__
#define __COMMON_H__
#define DEFINE_ENUM_WITH_STRINGS(name, LIST) \
typedef enum name \
{ \
LIST(DEFINE_ENUM_ELEMENT) \
} name; \
\
static inline const char *name##_to_string(name value) \
{ \
switch (value) \
{ \
LIST(DEFINE_ENUM_CASE) \
default: \
return "UNKNOWN"; \
} \
}
#define DEFINE_ENUM_ELEMENT(e) e,
#define DEFINE_ENUM_CASE(e) \
case e: \
return #e;
#endif
test.c
#include <stdio.h>
#include "common.h"
#define COLOR_ITEMS(X) \
X(RED) \
X(GREEN) \
X(BLUE)
DEFINE_ENUM_WITH_STRINGS(Color, COLOR_ITEMS)
extern void fruits(void);
int main(void)
{
printf("%s(%d)\n", Color_to_string(1), GREEN);
fruits();
return 0;
}
test2.c
#include <stdio.h>
#include "common.h"
#define FRUITS_ITEMS(X) \
X(APPLE) \
X(GRAPE) \
X(ORANGE)
DEFINE_ENUM_WITH_STRINGS(Fruits, FRUITS_ITEMS)
void fruits(void)
{
printf("%s(%d)\n", Fruits_to_string(2), ORANGE);
}
何かもっと良い方法があった気がするのだけど
見つけきれなかったのでとりあえずこれで
出力サンプル
tyano ~$ gcc test.c test2.c
tyano ~$ ./a.out
GREEN(1)
ORANGE(2)
値指定版
#include <stdio.h>
#define DEFINE_ENUM_WITH_STRINGS(Name, LIST) \
typedef enum Name { \
LIST(EXPAND_ENUM, EXPAND_ENUM_VAL) \
} Name; \
static const char *Name##_to_string(int v) { \
switch (v) { \
LIST(EXPAND_CASE, EXPAND_CASE_VAL) \
default: return "UNKNOWN"; \
} \
}
#define EXPAND_ENUM(name) name,
#define EXPAND_ENUM_VAL(name, val) name = val,
#define EXPAND_CASE(name) case name: return #name;
#define EXPAND_CASE_VAL(name, val) case name: return #name;
#define COLOR_LIST(X, X_VAL) \
X(RED) \
X(GREEN) \
X(BLUE) \
X_VAL(BLACK, 1000) \
X(WHITE)
DEFINE_ENUM_WITH_STRINGS(Color, COLOR_LIST)