enum values to strings.
Derek Atkins
warlord at MIT.EDU
Thu Mar 24 16:41:21 EST 2005
Note that in many cases this conversion is already done. The Gnucash XML does
this in most cases. Take a look at, e.g. src/engine/Account.c for an example.
It's not _quite_ as clever as your code, but it does the job.
And yes, we should definitely be using strings instead of ints for enums.
Remember when I asked why you needed QOF_TYPE_INT32? ;)
I dont think we ever use an INT64 enum.
-derek
Quoting Neil Williams <linux at codehelp.co.uk>:
> 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
>
>
--
Derek Atkins, SB '93 MIT EE, SM '95 MIT Media Laboratory
Member, MIT Student Information Processing Board (SIPB)
URL: http://web.mit.edu/warlord/ PP-ASEL-IA N1NWH
warlord at MIT.EDU PGP key available
More information about the gnucash-devel
mailing list