preproc: add %count() function

Add %count(), giving a count of the number of arguments.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
H. Peter Anvin 2022-11-14 01:48:38 -08:00
parent 16b49d4229
commit 664a79473d
2 changed files with 30 additions and 4 deletions

View File

@ -7013,6 +7013,16 @@ stdmac_cond_sel(const SMacro *s, Token **params, int nparams)
return new_Token(NULL, tok_smac_param(which), "", 0);
}
/* %count() */
static Token *
stdmac_count(const SMacro *s, Token **params, int nparams)
{
(void)s;
(void)params;
return make_tok_num(NULL, nparams);
}
/* Add magic standard macros */
struct magic_macros {
const char *name;
@ -7028,6 +7038,7 @@ static void pp_add_magic_stdmac(void)
{ "__?LINE?__", true, 0, 0, stdmac_line },
{ "__?BITS?__", true, 0, 0, stdmac_bits },
{ "__?PTR?__", true, 0, 0, stdmac_ptr },
{ "%count", false, 1, SPARM_VARADIC, stdmac_count },
{ "%eval", false, 1, SPARM_EVAL|SPARM_VARADIC, stdmac_join },
{ "%str", false, 1, SPARM_GREEDY|SPARM_STR, stdmac_join },
{ "%strcat", false, 1, SPARM_GREEDY, stdmac_strcat },

View File

@ -2867,13 +2867,28 @@ to \c{%sel(2-!(x),y,z)}.
The argument not selected is never expanded.
\S{f_count} \i\c{%count()} Function
The \c{%count()} function expands to the number of argments passed to
the macro. Note that just as for single-line macros, \c{%count()}
treats an empty argument list as a single empty argument.
\c %xdefine empty %count() ; %define empty 1
\c %xdefine one %count(1) ; %define one 1
\c %xdefine two %count(5,q) ; %define two 2
\c %define list a,b,46
\c %xdefine lc1 %count(list) ; %define lc 1 (just one argument)
\c %xdefine lc2 %count(%[list]) ; %define lc 3 (indirection expands)
\S{f_eval} \i\c{%eval()} Function
The \c{%eval()} function evaluates its argument as a numeric
expression in much the same way the \i\c{%assign} directive would, see
\k{assign}. Unlike \c{%assign}, \c{%eval()} supports more than one
argument; if more than one argument is specified, it is expanded to a
comma-separated list of values.
expression and expands to the result as an integer constant in much
the same way the \i\c{%assign} directive would, see \k{assign}. Unlike
\c{%assign}, \c{%eval()} supports more than one argument; if more than
one argument is specified, it is expanded to a comma-separated list of
values.
\c %assign a 2
\c %assign b 3