From 03b3df0ce01aa0c59ef72eba8c0b770cc20d93df Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Tue, 13 Apr 2021 16:56:08 +0300 Subject: Add an interactive macro shell mode to rpmspec Handy for debugging and experimenting with macros, in and out of spec context. Placed in rpmspec because we don't want readline dependency on main rpm executable, this is more of a packager tool anyway. --- rpmspec.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'rpmspec.c') diff --git a/rpmspec.c b/rpmspec.c index 80c0cd1d6..d072da166 100644 --- a/rpmspec.c +++ b/rpmspec.c @@ -5,6 +5,11 @@ #include #include +#ifdef HAVE_READLINE +#include +#include +#endif + #include "cliutils.h" #include "debug.h" @@ -13,6 +18,7 @@ enum modes { MODE_UNKNOWN = 0, MODE_QUERY = (1 << 0), MODE_PARSE = (1 << 1), + MODE_SHELL = (1 << 2), }; static int mode = MODE_UNKNOWN; @@ -24,6 +30,10 @@ static struct poptOption specOptsTable[] = { N_("parse spec file(s) to stdout"), NULL }, { "query", 'q', POPT_ARG_VAL, &mode, MODE_QUERY, N_("query spec file(s)"), NULL }, +#if HAVE_READLINE + { "shell", 0, POPT_ARG_VAL, &mode, MODE_SHELL, + N_("interactive macro shell"), NULL }, +#endif { "rpms", 0, POPT_ARG_VAL, &source, RPMQV_SPECRPMS, N_("operate on binary rpms generated by spec (default)"), NULL }, { "builtrpms", 0, POPT_ARG_VAL, &source, RPMQV_SPECBUILTRPMS, @@ -52,6 +62,23 @@ static struct poptOption optionsTable[] = { typedef int (*parsecb)(rpmSpec spec); +#ifdef HAVE_READLINE +static int doShell(rpmSpec spec) +{ + fprintf(stderr, _("RPM version %s macro shell\n"), rpmEVR); + char *line = NULL; + while ((line = readline("> ")) != NULL) { + char *exp = rpmExpand(line, NULL); + if (*exp) + fprintf(stdout, "%s\n", exp); + free(exp); + if (*line) + add_history(line); + } + return 0; +} +#endif + static int dumpSpec(rpmSpec spec) { fprintf(stdout, "%s", rpmSpecGetSection(spec, RPMBUILD_NONE)); @@ -114,6 +141,15 @@ int main(int argc, char *argv[]) break; } +#ifdef HAVE_READLINE + case MODE_SHELL: + if (poptPeekArg(optCon)) + ec = doSpec(optCon, doShell); + else + ec = doShell(NULL); + break; +#endif + case MODE_UNKNOWN: if (poptPeekArg(optCon) != NULL || argc <= 1 || rpmIsVerbose()) { printUsage(optCon, stderr, 0); -- cgit v1.2.1