Add support for defining auxiliary macro functions

Add rpmPushMacroAux() function which allows registering auxiliary macros
implemented in C and some required helper facilities: export the types,
rpmMacroBufAppend*() and rpmMacroBufErr() functions, and finally
add rpmMacroEntryPriv() to let macro retrieve their private data.
And that's all folks.
This commit is contained in:
Panu Matilainen 2023-10-20 15:32:40 +03:00
parent 336c07c2e9
commit e9c997f637
2 changed files with 76 additions and 10 deletions

View File

@ -21,6 +21,10 @@ typedef struct rpmMacroEntry_s * rpmMacroEntry;
typedef struct rpmMacroContext_s * rpmMacroContext;
typedef struct rpmMacroBuf_s *rpmMacroBuf;
typedef void (*macroFunc)(rpmMacroBuf mb, rpmMacroEntry me, ARGV_t argv, size_t *parsed);
extern rpmMacroContext rpmGlobalMacroContext;
extern rpmMacroContext rpmCLIMacroContext;
@ -121,6 +125,52 @@ int rpmPushMacroFlags (rpmMacroContext mc, const char * n,
const char * b, int level,
rpmMacroFlags flags);
/** \ingroup rpmmacro
* Push an auxiliary macro to context.
* @param mc macro context (NULL uses global context).
* @param n macro name
* @param o macro parameters (or NULL)
* @param f macro function
* @param priv private user data (or NULL)
* @param level macro recursion level (0 is entry API)
* @param flags macro flags
* @return 0 on success
*/
int rpmPushMacroAux(rpmMacroContext mc,
const char * n, const char * o,
macroFunc f, void *priv, int nargs,
int level, rpmMacroFlags flags);
/** \ingroup rpmmacro
* Return macro entry user data (in aux macro)
* @param me macro entry
* @return pointer to private data passed on define or NULL
*/
void *rpmMacroEntryPriv(rpmMacroEntry me);
/** \ingroup rpmmacro
* Append a character to macro buffer (in aux macro)
* @param mb macro buffer
* @param c character to append
*/
void rpmMacroBufAppend(rpmMacroBuf mb, char c);
/** \ingroup rpmmacro
* Append a string to macro buffer (in aux macro)
* @param mb macro buffer
* @param str string to append
*/
void rpmMacroBufAppendStr(rpmMacroBuf mb, const char *str);
/** \ingroup rpmmacro
* Raise an error or warning in macro buffer (in aux macro)
* @param mb macro buffer
* @param error 1 if error, 0 if warning
* @param fmt j
*/
RPM_GNUC_PRINTF(3, 4)
void rpmMacroBufErr(rpmMacroBuf mb, int error, const char *fmt, ...);
/** \ingroup rpmmacro
* Pop macro from context.
* @param mc macro context (NULL uses global context).

View File

@ -41,9 +41,6 @@ enum macroFlags_e {
ME_FUNC = (1 << 4),
};
typedef struct rpmMacroBuf_s *rpmMacroBuf;
typedef void (*macroFunc)(rpmMacroBuf mb, rpmMacroEntry me, ARGV_t argv, size_t *parsed);
/*! The structure used to store a macro. */
struct rpmMacroEntry_s {
struct rpmMacroEntry_s *prev;/*!< Macro entry stack. */
@ -51,6 +48,7 @@ struct rpmMacroEntry_s {
const char *opts; /*!< Macro parameters (a la getopt) */
const char *body; /*!< Macro body. */
macroFunc func; /*!< Macro function (builtin macros) */
void *priv; /*!< Private user data (aux macros) */
int nargs; /*!< Number of required args */
int flags; /*!< Macro state bits. */
int level; /*!< Scoping level. */
@ -318,7 +316,7 @@ matchchar(const char * p, char pl, char pr)
return (const char *)NULL;
}
static void rpmMacroBufErr(rpmMacroBuf mb, int error, const char *fmt, ...)
void rpmMacroBufErr(rpmMacroBuf mb, int error, const char *fmt, ...)
{
char *emsg = NULL;
int n;
@ -506,7 +504,7 @@ static void mbFini(rpmMacroBuf mb, rpmMacroEntry me, MacroExpansionData *med)
mb->expand_trace = med->expand_trace;
}
static void rpmMacroBufAppend(rpmMacroBuf mb, char c)
void rpmMacroBufAppend(rpmMacroBuf mb, char c)
{
if (mb->nb < 1) {
mb->buf = xrealloc(mb->buf, mb->tpos + MACROBUFSIZ + 1);
@ -517,7 +515,7 @@ static void rpmMacroBufAppend(rpmMacroBuf mb, char c)
mb->nb--;
}
static void rpmMacroBufAppendStr(rpmMacroBuf mb, const char *str)
void rpmMacroBufAppendStr(rpmMacroBuf mb, const char *str)
{
size_t len = strlen(str);
if (len > mb->nb) {
@ -1740,7 +1738,7 @@ static int doExpandMacros(rpmMacroContext mc, const char *src, int flags,
static void pushMacroAny(rpmMacroContext mc,
const char * n, const char * o, const char * b,
macroFunc f, int nargs, int level, int flags)
macroFunc f, void *priv, int nargs, int level, int flags)
{
/* new entry */
rpmMacroEntry me;
@ -1785,6 +1783,7 @@ static void pushMacroAny(rpmMacroContext mc,
me->opts = o ? "" : NULL;
/* initialize */
me->func = f;
me->priv = priv;
me->nargs = nargs;
me->flags = flags;
me->flags &= ~(ME_USED);
@ -1797,7 +1796,7 @@ static void pushMacroAny(rpmMacroContext mc,
static void pushMacro(rpmMacroContext mc,
const char * n, const char * o, const char * b, int level, int flags)
{
return pushMacroAny(mc, n, o, b, NULL, 0, level, flags);
return pushMacroAny(mc, n, o, b, NULL, NULL, 0, level, flags);
}
static void popMacro(rpmMacroContext mc, const char * n)
@ -1975,6 +1974,18 @@ int rpmPushMacro(rpmMacroContext mc,
return rpmPushMacroFlags(mc, n, o, b, level, RPMMACRO_DEFAULT);
}
int rpmPushMacroAux(rpmMacroContext mc,
const char * n, const char * o,
macroFunc f, void *priv, int nargs,
int level, rpmMacroFlags flags)
{
mc = rpmmctxAcquire(mc);
pushMacroAny(mc, n, nargs ? "" : NULL, "<aux>", f, priv, nargs,
level, flags|ME_FUNC);
rpmmctxRelease(mc);
return 0;
}
int rpmPopMacro(rpmMacroContext mc, const char * n)
{
mc = rpmmctxAcquire(mc);
@ -2016,6 +2027,11 @@ int rpmMacroIsParametric(rpmMacroContext mc, const char *n)
return parametric;
}
void *rpmMacroEntryPriv(rpmMacroEntry me)
{
return (me != NULL) ? me->priv : NULL;
}
void
rpmLoadMacros(rpmMacroContext mc, int level)
{
@ -2053,8 +2069,8 @@ rpmInitMacros(rpmMacroContext mc, const char * macrofiles)
/* Define built-in macros */
for (const struct builtins_s *b = builtinmacros; b->name; b++) {
pushMacroAny(mc, b->name, b->nargs ? "" : NULL, "<builtin>", b->func, b->nargs,
RMIL_BUILTIN, b->flags | ME_FUNC);
pushMacroAny(mc, b->name, b->nargs ? "" : NULL, "<builtin>",
b->func, NULL, b->nargs, RMIL_BUILTIN, b->flags | ME_FUNC);
}
argvSplit(&globs, macrofiles, ":");