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