enum values to strings.
Neil Williams
linux at codehelp.co.uk
Thu Mar 24 16:32:33 EST 2005
That anti-software patent meeting has had an unexpected side effect. After the
meeting, I got chatting about GnuCash and my development work on QOF (as you
do). One of the results was a discussion about how to turn enum values
(integers) into strings (for text file readability) using #define.
I experimented with the code that had been jotted down on the back of EU
software patent EP 0760140 (!) and also found this example:
http://www.flipcode.com/cgi-bin/fcmsg.cgi?thread_show=24481
That doesn't work for me, so I've got a version here that DOES work as
straight C (I think):
Credit to Jamie Lokier for the original idea and Chad Austin for the flipcode
example in C++. I'm posting it here in case I've missed something obvious.
;-)
#include <stdio.h>
#define ENUM_BODY(name, value) \
name = value,
#define AS_STRING_CASE(name, value) \
case name: return #name;
#define FROM_STRING_CASE(name, value) \
if (strcmp(str, #name) == 0) { \
return name; \
}
#define DEFINE_ENUM(name, list) \
typedef enum { \
list(ENUM_BODY) \
}name; \
const char* asString(name n) { \
switch (n) { \
list(AS_STRING_CASE) \
default: return ""; \
} \
} \
name fromString(const char* str) { \
list(FROM_STRING_CASE) \
return 0; /* assert? throw? */ \
}
#define ENUM_LIST(_) \
_(RED, 0) \
_(GREEN, 1) \
_(BLUE, 87)
DEFINE_ENUM(Color, ENUM_LIST)
int main() {
Color c = GREEN;
printf("%d\n",c);
printf("%s\n", asString(c));
printf("%d\n", fromString("BLUE"));
}
gcc enum.c
Output:
neil at garfield:~/tmp/enum$ ./a.out
1
GREEN
87
I need this functionality to convert potentially any enum already defined in
GnuCash into a form that is usable AS an enum by all existing processes and
which can be converted to a const char* on demand, with only one piece of new
code, no duplication and as efficiently as possible. Only enums that are used
as QOF parameters (presently gint32/gint64) would actually take this new
form. The parameter would then be changed to QOF_TYPE_STRING and a function
defined. That would get the enum from the existing function (as a wrapper)
and then pass that to asString() above.
The parsed version of the defines (using gcc -E) shows the expanded section
as: (line breaks added)
typedef enum { RED = 0, GREEN = 1, BLUE = 87, }Color;
const char* asString(Color n) {
switch (n) {
case RED: return "RED";
case GREEN: return "GREEN";
case BLUE: return "BLUE";
default: return "";
}
}
Color
fromString(const char* str)
{
if (strcmp(str, "RED") == 0) { return RED; }
if (strcmp(str, "GREEN") == 0) { return GREEN; }
if (strcmp(str, "BLUE") == 0) { return BLUE; }
return 0;
}
int main() {
Color c = GREEN;
printf("%d\n",c);
printf("%s\n", asString(c));
printf("%d\n", fromString("BLUE"));
}
Can anyone see problems with this solution? Are the defines correct C?
Do we want to use safe_strcmp?
Should the strings be translatable?
#define AS_STRING_CASE(name, value) \
case name: return _(#name);
instead of return #name?
Comments? Problems?
--
Neil Williams
=============
http://www.dcglug.org.uk/
http://www.nosoftwarepatents.com/
http://sourceforge.net/projects/isbnsearch/
http://www.neil.williamsleesmill.me.uk/
http://www.biglumber.com/x/web?qs=0x8801094A28BCB3E3
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.gnucash.org/pipermail/gnucash-devel/attachments/20050324/7b8f260b/attachment.bin
More information about the gnucash-devel
mailing list