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: [EMAIL PROTECTED]:~/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
pgpu1zaoDHhBu.pgp
Description: PGP signature
_______________________________________________ gnucash-devel mailing list gnucash-devel@gnucash.org https://lists.gnucash.org/mailman/listinfo/gnucash-devel