enum as string macro - updated

Neil Williams linux at codehelp.co.uk
Sat Apr 23 15:20:21 EDT 2005


OK, the clever little macro that I found and improved has now been improved 
some more. It is now quite happy in a header file AND it produces Doxygen 
output!
https://lists.gnucash.org/pipermail/gnucash-devel/2005-March/012849.html

The Doxygen output is a simple config change in doxygen.cfg.in together with 
the < operator to link the docs against a specific expanded line.

i.e. Doxygen expands the macro and then appends the comment before reading the 
comment itself. It's quite crafty!

Example from FreqSpec.h:
(The _() syntax is not preserved once the gcc preprocessor has been through 
the file so there's no risk of translating the strings, it's purely for the 
macro.)

#define ENUM_LIST_UI(_) \
        _(UIFREQ_NONE,) /**< no frequency */ \
        _(UIFREQ_ONCE,) /**< Just occurs once */ \
        _(UIFREQ_DAILY,) /**< Repeat every day. */ \
        _(UIFREQ_DAILY_MF,) /**< Repeat Monday to Friday, skip weekend. */ \
        _(UIFREQ_WEEKLY,) /**< Repeat once each week. */ \
        _(UIFREQ_BI_WEEKLY,) /**< Repeat twice a week. */ \
        _(UIFREQ_SEMI_MONTHLY,) /**< Repeat twice a month. */ \
        _(UIFREQ_MONTHLY,) /**< Repeat once a month. */ \
        _(UIFREQ_QUARTERLY,) /**< Repeat every quarter. */ \
        _(UIFREQ_TRI_ANUALLY,) /**< Repeat three times a year. */ \
        _(UIFREQ_SEMI_YEARLY,) /**< Repeat twice a year. */ \
        _(UIFREQ_YEARLY,) /**< Repeat once a year. */ \
        _(UIFREQ_NUM_UI_FREQSPECS,) 

DEFINE_ENUM( UIFreqType, ENUM_LIST_UI) /**< \enum UIFreqType

 * The user's conception of the frequency.  It is expected that this
 * list will grow, while the former ::FreqType will not. */

AS_STRING_DEC(UIFreqType, ENUM_LIST_UI) /**< Convert UIFreqType values to 
strings. */
FROM_STRING_DEC(UIFreqType, ENUM_LIST_UI) /**< Convert strings to UIFreqType 
values. */

That puts the enum, the typedef and the prototypes of the two functions into 
the header. The prototypes could be in a different file if necessary. Note 
that the list is specific to this enum. Different enums would simply use 
their own name for the list macro and call DEFINE_ENUM with that macro and 
the name of the enum to be declared a typedef.

Then in the C code, you put the definitions of the two functions as two more 
macros:

FROM_STRING_FUNC(UIFreqType, ENUM_LIST_UI)
AS_STRING_FUNC(UIFreqType, ENUM_LIST_UI)

No duplication, no worries about updating the values and not updating the text 
version.

To call the funcs, simply use:
char*
qofFreqSpecGetUIType(FreqSpec *fs)
{
	char *type_string;

	g_return_val_if_fail(fs, NULL);
	type_string = g_strdup(UIFreqTypeasString(fs->uift));
	return type_string;
}


void
qofFreqSpecSetUIType (FreqSpec *fs, const char *type_string)
{
	UIFreqType type;

	g_return_if_fail(fs != NULL);
	type = UIFreqTypefromString(type_string);
}

Note that the asString and fromString functions are named for this particular 
enum as well - allowing the same macros to be used for different enums in the 
same source file.

The complete macro will go into gnc-engine-util.h ready for anyone to use as 
above.

It can also be used by external programs linked against QOF - although you 
will need to adjust Doxygen further so that Doxygen can find the original 
macro to expand.

I'll put some example Doxygen output up tomorrow when the files themselves are 
ready to commit.

There's no support for a different string version to the enum name but that's 
the point - using this we can be sure that the string in the input is the 
enum value in code.

As in the original code, starter values are supported:
#define ENUM_LIST(_)                             \
    _(RED,   0)                                  \
    _(GREEN, 1)                                  \
    _(BLUE,  87)

With the header file and doxygen problems solved, I'd like to use the macro 
for all future enums. 

-- 

Neil Williams
=============
http://www.dcglug.org.uk/
http://www.nosoftwarepatents.com/
http://www.linux.codehelp.co.uk/

-------------- 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/20050423/dcc12e91/attachment.bin


More information about the gnucash-devel mailing list