On Sun, 30 Aug 2020, Hal Murray via devel wrote:
Is there any way to do something like
#define FOO $FOO+1
I want to keep track of the number of times a macro has been called. That
seems like something that would happen often enough that there would be a
standard recipe but I haven't seen it. (Or didn't recognize it.)
----------
The context is the code in ntp_control that is responding to ntpq requests to
read a variable. It needs to translate a string (name of variable to read) to
a subroutine to print that variable. Current code looks like:
#define CS_REFID 6
{ CS_REFID, RO|DEF, "refid" },
#define CS_REFTIME 7
{ CS_REFTIME, RO|DEF, "reftime" },
#define CS_POLL 8
{ CS_POLL, RO|DEF, "tc" },
#define CS_PEERID 9
{ CS_PEERID, RO|DEF, "peer" },
That sets up the table to search. The table is big (~100 slots) so it's a
real pain to insert a new slot.
Later on, there is a giant select that uses those CS_xxx tags:
case CS_ROOTDELAY:
ctl_putdbl(sys_var[CS_ROOTDELAY].text,
sys_vars.sys_rootdelay * MS_PER_S);
break;
case CS_ROOTDISPERSION:
ctl_putdbl(sys_var[CS_ROOTDISPERSION].text,
sys_vars.sys_rootdisp * MS_PER_S);
break;
---------
The usual way to do this sort of thing with the lame macro processor known
as cpp is as follows:
First define a "master macro" whose body is a series of invocations of an
entry macro, with all the necessary properties being provided as
arguments. Then, for each table or other use:
1) Define the entry macro to generate the appropriate content from the
appropriate arguments.
2) Invoke the master macro.
3) Undefine the entry macro (so it's ready for next time).
I can't make a precise example since you chose different entries for the
two parts of your example above, but for the first part one could have
something like this:
#define CS_ENTRIES \
CS_ENTRY(REFID, RO|DEF, "refid") \
CS_ENTRY(POLL, RO|DEF, "tc") \
CS_ENTRY(PEERID, RO|DEF, "peer") \
Then, to define the numeric codes:
#define CS_ENTRY(sym, flags, name) CS_##sym,
enum cs_index {
CS_ENTRIES
CS_MAXVAL // Maximum value +1
};
#undef CS_ENTRY
For a table of names:
#define CS_ENTRY(sym, flags, name) name,
static const char * const cs_names[] = {
CS_ENTRIES
};
#undef CS_ENTRY
One approach would be to have an external program do the equivalent of the cpp
processing that we would like to do. That would take some waf hacking, but
shouldn't be a big deal.
An unnecessary complication.
Fred Wright
_______________________________________________
devel mailing list
devel@ntpsec.org
http://lists.ntpsec.org/mailman/listinfo/devel