Add new rpmExpandThisMacro() public method

This expands the maco with the specified name. Argument expandsion
for parametric macros can be turned on with the RPMEXPAND_EXPAND_ARGS
flag.
This commit is contained in:
Michael Schroeder 2020-10-26 12:21:49 +01:00 committed by Panu Matilainen
parent ef4241d727
commit a2e60c0a50
2 changed files with 110 additions and 0 deletions

View File

@ -1603,6 +1603,75 @@ exit:
return mb->error;
}
/**
* Expand a single macro
* @param mb macro expansion state
* @param me macro entry slot
* @param args arguments for parametric macros
* @param flags expandsion flags
* @return 0 on success, 1 on failure
*/
static int
expandThisMacro(MacroBuf mb, rpmMacroEntry me, ARGV_const_t args, int flags)
{
int store_macro_trace;
int store_expand_trace;
size_t tpos;
ARGV_t optargs = NULL;
if (mb->buf == NULL)
mbAllocBuf(mb, 0);
if (++mb->depth > max_macro_depth) {
mbErr(mb, 1,
_("Too many levels of recursion in macro expansion. It is likely caused by recursive macro declaration.\n"));
mb->depth--;
mb->expand_trace = 1;
goto exit;
}
if (mb->macro_trace) {
ARGV_const_t av = args;
fprintf(stderr, "%3d>%*s%%%s", mb->depth, (2 * mb->depth + 1), "", me->name);
for (av = args; av && *av; av++)
fprintf(stderr, " %s", *av);
fprintf(stderr, "\n");
}
tpos = mb->tpos; /* save expansion pointer for printExpand */
store_macro_trace = mb->macro_trace;
store_expand_trace = mb->expand_trace;
/* prepare arguments for parametric macros */
if (me->opts) {
argvAdd(&optargs, me->name);
if ((flags & RPMEXPAND_EXPAND_ARGS) != 0) {
ARGV_const_t av = args;
for (av = args; av && *av; av++) {
char *s = NULL;
expandThis(mb, *av, 0, &s);
argvAdd(&optargs, s);
free(s);
}
} else {
argvAppend(&optargs, args);
}
}
doExpandThisMacro(mb, me, optargs);
if (optargs)
argvFree(optargs);
mb->buf[mb->tpos] = '\0';
mb->depth--;
if (mb->error != 0 || mb->expand_trace)
printExpansion(mb, mb->buf+tpos, mb->buf+mb->tpos);
mb->macro_trace = store_macro_trace;
mb->expand_trace = store_expand_trace;
exit:
return mb->error;
}
/* =============================================================== */
@ -1799,6 +1868,31 @@ int rpmExpandMacros(rpmMacroContext mc, const char * sbuf, char ** obuf, int fla
}
}
int rpmExpandThisMacro(rpmMacroContext mc, const char *n, ARGV_const_t args, char ** obuf, int flags)
{
rpmMacroEntry *mep;
char *target = NULL;
int rc = 1; /* assume failure */
mc = rpmmctxAcquire(mc);
mep = findEntry(mc, n, 0, NULL);
if (mep) {
MacroBuf mb = mbCreate(mc, flags);
rc = expandThisMacro(mb, *mep, args, flags);
mb->buf[mb->tpos] = '\0'; /* XXX just in case */
target = xrealloc(mb->buf, mb->tpos + 1);
_free(mb);
}
rpmmctxRelease(mc);
if (rc) {
free(target);
return -1;
} else {
*obuf = target;
return 1;
}
}
void
rpmDumpMacroTable(rpmMacroContext mc, FILE * fp)
{

View File

@ -52,6 +52,9 @@ extern const char * macrofiles;
/* rpm expression parser flags */
#define RPMEXPR_EXPAND (1 << 0) /*!< expand primary terms */
/* rpm macro expansion flags */
#define RPMEXPAND_EXPAND_ARGS (1 << 0) /*!< expand arguments of parametric macros */
typedef enum rpmMacroFlags_e {
RPMMACRO_DEFAULT = 0,
RPMMACRO_LITERAL = (1 << 0), /*!< do not expand body of macro */
@ -76,6 +79,19 @@ void rpmDumpMacroTable (rpmMacroContext mc,
int rpmExpandMacros (rpmMacroContext mc, const char * sbuf,
char ** obuf, int flags);
/** \ingroup rpmmacro
* Expand a specific macro into buffer.
* @param mc macro context (NULL uses global context).
* @param n macro name
* @param args arguments for parametric macros
* @param obuf macro expansion (malloc'ed)
* @param flags flags (currently unused)
* @return negative on failure
*/
int rpmExpandThisMacro (rpmMacroContext mc, const char *n,
ARGV_const_t args,
char ** obuf, int flags);
/** \ingroup rpmmacro
* Push macro to context.
* @param mc macro context (NULL uses global context).