--- /dev/null
+diff -urN rpm-5.4.13/build/parseSpec.c rpm-5.4.13-rpmspec/build/parseSpec.c
+--- rpm-5.4.13/build/parseSpec.c 2013-10-22 20:18:34.483039876 +0200
++++ rpm-5.4.13-rpmspec/build/parseSpec.c 2013-10-22 18:52:02.550664732 +0200
+@@ -474,6 +474,11 @@
+ spec->line[0] = '\0';
+ }
+
++ /* Collect parsed line */
++ if (spec->parsed == NULL)
++ spec->parsed = rpmiobNew(0);
++ spec->parsed = rpmiobAppend(spec->parsed, spec->line, 1);
++
+ /*@-compmempass@*/ /* FIX: spec->readStack->next should be dependent */
+ return 0;
+ /*@=compmempass@*/
+diff -urN rpm-5.4.13/build/rpmspec.h rpm-5.4.13-rpmspec/build/rpmspec.h
+--- rpm-5.4.13/build/rpmspec.h 2013-10-22 20:18:34.449706143 +0200
++++ rpm-5.4.13-rpmspec/build/rpmspec.h 2013-10-22 18:44:37.729692113 +0200
+@@ -193,6 +193,8 @@
+ /*@only@*/
+ rpmiob clean; /*!< %clean scriptlet. */
+
++ rpmiob parsed;
++
+ size_t nfoo;
+ /*@only@*/ /*@relnull@*/
+ tagStore_t foo;
+diff -urN rpm-5.4.13/tools/Makefile.am rpm-5.4.13-rpmspec/tools/Makefile.am
+--- rpm-5.4.13/tools/Makefile.am 2013-10-22 20:18:34.426372530 +0200
++++ rpm-5.4.13-rpmspec/tools/Makefile.am 2013-10-22 20:02:30.365350944 +0200
+@@ -61,7 +61,7 @@
+ pkgbin_PROGRAMS = \
+ @WITH_AUGEAS_AUGTOOL@ chroot cp @WITH_CUDF_CUDFTOOL@ find mtree \
+ @WITH_SEMANAGE_SEMODULE@ wget \
+- rpmcache rpmdigest rpmrepo rpmspecdump \
++ rpmcache rpmdigest rpmrepo rpmspecdump rpmspec \
+ rpmcmp rpmdeps sqlite3 @WITH_KEYUTILS_RPMKEY@ @WITH_LIBELF_DEBUGEDIT@
+ if WITH_DB
+ pkgbin_PROGRAMS += dbconvert
+@@ -195,6 +195,9 @@
+ rpmspecdump_SOURCES = rpmspecdump.c
+ rpmspecdump_LDADD = $(RPMBUILD_LDADD_COMMON)
+
++rpmspec_SOURCES = rpmspec.c
++rpmspec_LDADD = $(RPMBUILD_LDADD_COMMON)
++
+ semodule_SOURCES = semodule.c
+ semodule_LDADD = $(RPMIO_LDADD_COMMON)
+
+diff -urN rpm-5.4.13/tools/rpmspec.c rpm-5.4.13-rpmspec/tools/rpmspec.c
+--- rpm-5.4.13/tools/rpmspec.c 1970-01-01 01:00:00.000000000 +0100
++++ rpm-5.4.13-rpmspec/tools/rpmspec.c 2013-10-22 20:00:06.075242852 +0200
+@@ -0,0 +1,176 @@
++#include "system.h"
++const char *__progname;
++
++#define _AUTOHELP
++
++#if defined(IAM_RPM) || defined(__LCLINT__)
++#define IAM_RPMBT
++#define IAM_RPMDB
++#define IAM_RPMEIU
++#define IAM_RPMQV
++#define IAM_RPMK
++#endif
++
++#include <rpmio.h>
++#include <rpmiotypes.h>
++#include <poptIO.h>
++
++#include <rpmtypes.h>
++#include <rpmtag.h>
++#include "rpmdb.h"
++
++#include "rpmversion.h"
++#include "rpmps.h"
++#include "rpmts.h"
++
++#include <rpmbuild.h>
++
++#ifdef IAM_RPMBT
++#include "build.h"
++#define GETOPT_REBUILD 1003
++#define GETOPT_RECOMPILE 1004
++#endif
++
++#include <rpmcli.h>
++
++#include "debug.h"
++
++enum modes {
++ MODE_UNKNOWN = 0,
++ MODE_QUERY = (1 << 0),
++ MODE_PARSE = (1 << 1),
++};
++
++static int mode = MODE_UNKNOWN;
++static rpmQVSources source = RPMQV_RPM;
++static const char *target = NULL;
++static char *queryformat = NULL;
++
++static struct poptOption specOptsTable[] = {
++ { "parse", 'P', POPT_ARG_VAL, &mode, MODE_PARSE,
++ N_("parse spec file(s) to stdout"), NULL },
++ { "query", 'q', POPT_ARG_VAL, &mode, MODE_QUERY,
++ N_("query spec file(s)"), NULL },
++ { "rpms", 0, POPT_ARG_VAL, &source, RPMQV_RPM,
++ N_("operate on binary rpms generated by spec (default)"), NULL },
++ { "srpm", 0, POPT_ARG_VAL, &source, RPMQV_SPECSRPM,
++ N_("operate on source rpm generated by spec"), NULL },
++ { "target", 0, POPT_ARG_STRING, &target, 0,
++ N_("override target platform"), NULL },
++ { "queryformat", 0, POPT_ARG_STRING, &queryformat, 0,
++ N_("use the following query format"), "QUERYFORMAT" },
++ { "qf", 0, (POPT_ARG_STRING | POPT_ARGFLAG_DOC_HIDDEN), &queryformat, 0,
++ NULL, NULL },
++ POPT_TABLEEND
++};
++
++/* the structure describing the options we take and the defaults */
++static struct poptOption optionsTable[] = {
++ { NULL, '\0', POPT_ARG_INCLUDE_TABLE, specOptsTable, 0,
++ N_("Spec options:"), NULL },
++
++ { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
++ N_("Common options for all rpm modes and executables:"), NULL },
++
++ POPT_AUTOALIAS
++ POPT_AUTOHELP
++ POPT_TABLEEND
++};
++
++/*@exits@*/ static void argerror(const char * desc)
++ /*@globals __assert_program_name, fileSystem @*/
++ /*@modifies fileSystem @*/
++{
++ fprintf(stderr, _("%s: %s\n"), __progname, desc);
++ exit(EXIT_FAILURE);
++}
++
++#ifdef DYING /* XXX rpmIsVerbose alone stops usage spewage with every --eval */
++static void printVersion(FILE * fp)
++ /*@globals rpmEVR, fileSystem @*/
++ /*@modifies *fp, fileSystem @*/
++{
++ fprintf(fp, "%s (" RPM_NAME ") %s\n", __progname, rpmEVR);
++ if (rpmIsVerbose())
++ fprintf(fp, "rpmlib 0x%08x,0x%08x,0x%08x\n",
++ rpmlibVersion(), rpmlibTimestamp(), rpmlibVendor());
++}
++
++static void printUsage(poptContext con, FILE * fp, int flags)
++ /*@globals rpmEVR, fileSystem, internalState @*/
++ /*@modifies *fp, fileSystem, internalState @*/
++{
++ printVersion(fp);
++ fprintf(fp, "\n");
++
++ if (rpmIsVerbose())
++ poptPrintHelp(con, fp, flags);
++ else
++ poptPrintUsage(con, fp, flags);
++}
++#endif
++
++int main(int argc, char *argv[])
++{
++ rpmts ts = NULL;
++ QVA_t qva = &rpmQVKArgs;
++
++ poptContext optCon;
++ int ec = 0;
++
++ optCon = rpmcliInit(argc, argv, optionsTable);
++
++ if (target) {
++ rpmFreeMacros(NULL);
++ rpmFreeRpmrc();
++ rpmcliConfigured();
++ }
++
++ ts = rpmtsCreate();
++ switch (mode) {
++
++ case MODE_QUERY:
++ if (!poptPeekArg(optCon))
++ argerror(_("no arguments given for query"));
++
++ qva->qva_queryFormat = queryformat;
++ qva->qva_source = source;
++ qva->qva_specQuery = rpmspecQuery;
++ ec = rpmcliQuery(ts, qva, (const char **) poptGetArgs(optCon));
++ break;
++
++ case MODE_PARSE: {
++ const char * spath;
++ if (!poptPeekArg(optCon))
++ argerror(_("no arguments given for parse"));
++
++ while ((spath = poptGetArg(optCon)) != NULL) {
++ int ret = parseSpec(ts, spath, "/", 0, NULL, NULL, 1, 1, 0);
++ if (ret != 0) {
++ ec++;
++ continue;
++ }
++ Spec spec = rpmtsSpec(ts);
++ fprintf(stdout, "%s", rpmiobStr(spec->parsed));
++ }
++ break;
++ }
++
++ case MODE_UNKNOWN:
++#ifdef DYING /* XXX rpmIsVerbose alone stops usage spewage with every --eval */
++ if (poptPeekArg(optCon) != NULL || argc <= 1 || rpmIsVerbose()) {
++ printUsage(optCon, stderr, 0);
++ ec = argc;
++ }
++#endif
++ break;
++ }
++
++ rpmtsFree(ts);
++
++ free(qva->qva_queryFormat);
++
++ rpmcliFini(optCon);
++
++ return ec;
++}