Specify number of expected arguments for builtins in numbers

No functional changes here, but going forward this gives us more
flexibility than the ME_HAVEARG. We could also extend this to support
mandatory arguments to user defined macros too.
This commit is contained in:
Panu Matilainen 2020-11-13 11:48:21 +02:00
parent cfaf1c6292
commit 78bb7369a3
1 changed files with 37 additions and 37 deletions

View File

@ -39,12 +39,9 @@ enum macroFlags_e {
ME_LITERAL = (1 << 2), ME_LITERAL = (1 << 2),
ME_PARSE = (1 << 3), ME_PARSE = (1 << 3),
ME_FUNC = (1 << 4), ME_FUNC = (1 << 4),
ME_HAVEARG = (1 << 5),
}; };
#define ME_BUILTIN (ME_PARSE|ME_FUNC) #define ME_BUILTIN (ME_PARSE|ME_FUNC)
#define ME_ARGFUNC (ME_FUNC|ME_HAVEARG)
#define ME_ARGPARSE (ME_PARSE|ME_HAVEARG)
typedef struct MacroBuf_s *MacroBuf; typedef struct MacroBuf_s *MacroBuf;
typedef size_t (*macroFunc)(MacroBuf mb, rpmMacroEntry me, ARGV_t argv); typedef size_t (*macroFunc)(MacroBuf mb, rpmMacroEntry me, ARGV_t argv);
@ -56,6 +53,7 @@ struct rpmMacroEntry_s {
const char *opts; /*!< Macro parameters (a la getopt) */ const char *opts; /*!< Macro parameters (a la getopt) */
const char *body; /*!< Macro body. */ const char *body; /*!< Macro body. */
macroFunc func; /*!< Macro function (builtin macros) */ macroFunc func; /*!< Macro function (builtin macros) */
int nargs; /*!< Number of required args */
int flags; /*!< Macro state bits. */ int flags; /*!< Macro state bits. */
int level; /*!< Scoping level. */ int level; /*!< Scoping level. */
char arena[]; /*!< String arena. */ char arena[]; /*!< String arena. */
@ -1256,39 +1254,40 @@ static size_t doTrace(MacroBuf mb, rpmMacroEntry me, ARGV_t argv)
static struct builtins_s { static struct builtins_s {
const char * name; const char * name;
macroFunc func; macroFunc func;
int nargs;
int flags; int flags;
} const builtinmacros[] = { } const builtinmacros[] = {
{ "P", doSP, ME_ARGFUNC }, { "P", doSP, 1, ME_FUNC },
{ "S", doSP, ME_ARGFUNC }, { "S", doSP, 1, ME_FUNC },
{ "basename", doFoo, ME_ARGFUNC }, { "basename", doFoo, 1, ME_FUNC },
{ "define", doDef, ME_ARGPARSE }, { "define", doDef, -1, ME_PARSE },
{ "dirname", doFoo, ME_ARGFUNC }, { "dirname", doFoo, 1, ME_FUNC },
{ "dnl", doDnl, ME_ARGPARSE }, { "dnl", doDnl, -1, ME_PARSE },
{ "dump", doDump, ME_PARSE }, { "dump", doDump, 0, ME_PARSE },
{ "echo", doOutput, ME_ARGFUNC }, { "echo", doOutput, 1, ME_FUNC },
{ "error", doOutput, ME_ARGFUNC }, { "error", doOutput, 1, ME_FUNC },
{ "exists", doFoo, ME_ARGFUNC }, { "exists", doFoo, 1, ME_FUNC },
{ "expand", doExpand, ME_ARGFUNC }, { "expand", doExpand, 1, ME_FUNC },
{ "expr", doFoo, ME_ARGFUNC }, { "expr", doFoo, 1, ME_FUNC },
{ "getconfdir", doFoo, ME_FUNC }, { "getconfdir", doFoo, 0, ME_FUNC },
{ "getenv", doFoo, ME_ARGFUNC }, { "getenv", doFoo, 1, ME_FUNC },
{ "getncpus", doFoo, ME_FUNC }, { "getncpus", doFoo, 0, ME_FUNC },
{ "global", doGlobal, ME_ARGPARSE }, { "global", doGlobal, -1, ME_PARSE },
{ "load", doLoad, ME_ARGFUNC }, { "load", doLoad, 1, ME_FUNC },
#ifdef WITH_LUA #ifdef WITH_LUA
{ "lua", doLua, ME_ARGFUNC }, { "lua", doLua, 1, ME_FUNC },
#endif #endif
{ "macrobody", doBody, ME_ARGFUNC }, { "macrobody", doBody, 1, ME_FUNC },
{ "quote", doFoo, ME_ARGFUNC }, { "quote", doFoo, 1, ME_FUNC },
{ "shrink", doFoo, ME_ARGFUNC }, { "shrink", doFoo, 1, ME_FUNC },
{ "suffix", doFoo, ME_ARGFUNC }, { "suffix", doFoo, 1, ME_FUNC },
{ "trace", doTrace, ME_FUNC }, { "trace", doTrace, 0, ME_FUNC },
{ "u2p", doFoo, ME_ARGFUNC }, { "u2p", doFoo, 1, ME_FUNC },
{ "uncompress", doUncompress, ME_ARGFUNC }, { "uncompress", doUncompress, 1, ME_FUNC },
{ "undefine", doUndefine, ME_ARGPARSE }, { "undefine", doUndefine, 1, ME_PARSE },
{ "url2path", doFoo, ME_ARGFUNC }, { "url2path", doFoo, 1, ME_FUNC },
{ "verbose", doVerbose, ME_FUNC }, { "verbose", doVerbose, 0, ME_FUNC },
{ "warn", doOutput, ME_ARGFUNC }, { "warn", doOutput, 1, ME_FUNC },
{ NULL, NULL, 0 } { NULL, NULL, 0 }
}; };
@ -1350,7 +1349,7 @@ doExpandThisMacro(MacroBuf mb, rpmMacroEntry me, ARGV_t args, size_t *parsed)
/* Recursively expand body of macro */ /* Recursively expand body of macro */
if (me->flags & ME_BUILTIN) { if (me->flags & ME_BUILTIN) {
int nargs = argvCount(args) - 1; int nargs = argvCount(args) - 1;
int needarg = (me->flags & ME_HAVEARG) ? 1 : 0; int needarg = (me->nargs != 0);
int havearg = (nargs > 0); int havearg = (nargs > 0);
if (needarg != havearg) { if (needarg != havearg) {
mbErr(mb, 1, "%%%s: %s\n", me->name, needarg ? mbErr(mb, 1, "%%%s: %s\n", me->name, needarg ?
@ -1633,8 +1632,8 @@ static int doExpandMacros(rpmMacroContext mc, const char *src, int flags,
} }
static void pushMacroAny(rpmMacroContext mc, static void pushMacroAny(rpmMacroContext mc,
const char * n, const char * o, const char * b, macroFunc f, const char * n, const char * o, const char * b,
int level, int flags) macroFunc f, int nargs, int level, int flags)
{ {
/* new entry */ /* new entry */
rpmMacroEntry me; rpmMacroEntry me;
@ -1693,6 +1692,7 @@ static void pushMacroAny(rpmMacroContext mc,
me->opts = o ? "" : NULL; me->opts = o ? "" : NULL;
/* initialize */ /* initialize */
me->func = f; me->func = f;
me->nargs = nargs;
me->flags = flags; me->flags = flags;
me->flags &= ~(ME_USED); me->flags &= ~(ME_USED);
me->level = level; me->level = level;
@ -1704,7 +1704,7 @@ static void pushMacroAny(rpmMacroContext mc,
static void pushMacro(rpmMacroContext mc, static void pushMacro(rpmMacroContext mc,
const char * n, const char * o, const char * b, int level, int flags) const char * n, const char * o, const char * b, int level, int flags)
{ {
return pushMacroAny(mc, n, o, b, NULL, level, flags); return pushMacroAny(mc, n, o, b, NULL, 0, level, flags);
} }
static void popMacro(rpmMacroContext mc, const char * n) static void popMacro(rpmMacroContext mc, const char * n)
@ -1959,7 +1959,7 @@ rpmInitMacros(rpmMacroContext mc, const char * macrofiles)
/* Define built-in macros */ /* Define built-in macros */
for (const struct builtins_s *b = builtinmacros; b->name; b++) { for (const struct builtins_s *b = builtinmacros; b->name; b++) {
pushMacroAny(mc, b->name, "", "<builtin>", b->func, pushMacroAny(mc, b->name, "", "<builtin>", b->func, b->nargs,
RMIL_BUILTIN, b->flags); RMIL_BUILTIN, b->flags);
} }