I am building an application with a lot of integer values which need to be mapped to strings for user CLI and logging.
Using array LUT does not provide boundary checks so I want to generate conversion functions to make sure invalid values will be handled properly.
The idea is to use a function like this:
void *enumStr(void *e, bool isToStr)
{
if (isToStr && e == NUM_ZERO) return "zero"; if (!isToStr && strcmp(e, "zero") == 0) return 0;
if (isToStr && e == NUM_ONE) return "one"; if (!isToStr && strcmp(e, "one") == 0) return 1;
if (isToStr && e == NUM_TWO) return "two"; if (!isToStr && strcmp(e, "two") == 0) return 2;
if (isToStr) return "ENUM_N/A"; else return UINT_MAX;
}
which converts between a number and a string and to add two helper functions which hide the boolean argument.
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <limits.h>
#define ENUMSTR_START(enumName) \
void * _ ## enumName ## _(void *e, bool isToStr) {
#define ENUMSTR_ITEM(enumItem, enumStr) \
if (isToStr && e == enumItem) return enumStr; if (!isToStr && strcmp(e, enumStr) == 0) return enumItem
#define ENUMSTR_END(enumName) \
if (isToStr) return "STR_N/A"; else return UINT_MAX; } \
const char * enumName ## _toStr(uint32_t enumItem) { return (const char * ) _ ## enumName ## _ (enumItem, true); } \
uint32_t enumName ## _fromStr(const char *enumStr) { return _ ## enumName ## _ (enumStr, false); }
typedef enum
{
NUM_ZERO,
NUM_ONE,
NUM_TWO
} NUM;
ENUMSTR_START(NUM)
ENUMSTR_ITEM(NUM_ZERO, "zero");
ENUMSTR_ITEM(NUM_ONE, "one");
ENUMSTR_ITEM(NUM_TWO, "two");
ENUMSTR_END(NUM)
int main(void) {
printf("test 0 %s\n", NUM_toStr(NUM_ZERO));
printf("test 1 %s\n", NUM_toStr(NUM_ONE));
printf("test 2 %s\n", NUM_toStr(NUM_TWO));
printf("test 32 %s\n", NUM_toStr(32));
printf("test zero %u\n", NUM_fromStr("zero"));
printf("test one %u\n", NUM_fromStr("one"));
printf("test two %u\n", NUM_fromStr("two"));
printf("test three %u\n", NUM_fromStr("three"));
return 0;
}
Output:
test 0 zero
test 1 one
test 2 two
test 32 STR_N/A
test zero 0
test one 1
test two 2
test three 4294967295
1from the functionvoid *enumStr(void *e, bool isToStr)is not valid C as arbitrary integer values cannot certainly convert to avoid *. You need a new approach. Please explain more about your needs and usage limitations. \$\endgroup\$