From: Mark Huang Date: Wed, 8 Mar 2006 21:19:16 +0000 (+0000) Subject: - parse RPM spec files for real using C library. Can't use Python X-Git-Tag: planetlab-3_3-branch-point~22 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=b4cd26785fca00250c33964e12be40d358b48482;p=build.git - parse RPM spec files for real using C library. Can't use Python bindings since they do not export tags. --- diff --git a/parseSpec.c b/parseSpec.c new file mode 100644 index 00000000..c1e0a348 --- /dev/null +++ b/parseSpec.c @@ -0,0 +1,100 @@ +/* + * Parses RPM spec file into Makefile fragment. See + * + * http://fedora.redhat.com/docs/drafts/rpm-guide-en/ch-programming-c.html + * + * Mark Huang + * Copyright (C) 2006 The Trustees of Princeton University + * + * $Id: rollout.py,v 1.3 2005/06/21 19:12:44 mlhuang Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* the structure describing the options we take and the defaults */ +static struct poptOption optionsTable[] = { + { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0, + "Common options for all rpm modes and executables:", + NULL }, + + POPT_AUTOALIAS + POPT_AUTOHELP + POPT_TABLEEND +}; + +/* Stolen from rpm/build/spec.c:rpmspecQuery() */ +Spec +rpmspecGet(rpmts ts, const char * arg) +{ + char * buildRoot = NULL; + int recursing = 0; + char * passPhrase = ""; + char *cookie = NULL; + int anyarch = 1; + int force = 1; + + if (parseSpec(ts, arg, "/", buildRoot, recursing, passPhrase, + cookie, anyarch, force)) { + fprintf(stderr, "query of specfile %s failed, can't parse\n", arg); + return NULL; + } + + return rpmtsSpec(ts); +} + +int +main(int argc, char *const argv[]) +{ + poptContext context; + rpmts ts = NULL; + QVA_t qva = &rpmQVKArgs; + int ec = 0; + Spec spec; + struct Source *source; + + /* Parse common options for all rpm modes and executables */ + context = rpmcliInit(argc, argv, optionsTable); + + /* Create transaction state */ + ts = rpmtsCreate(); + + /* Parse spec file. The rpmcli functions don't allow you to + * access the Spec structure directly, so we call our own + * version of parseSpec() directly. */ + spec = rpmspecGet(ts, argv[1]); + if (spec && spec->sources) { + for (source = spec->sources; source; source = source->next) { + char fullSource[PATH_MAX]; + strncpy(fullSource, source->fullSource, sizeof(fullSource)); + printf("SOURCES += SOURCES/%s\n", basename(fullSource)); + } + } + + /* This is what would popt would do if --specfile were + * specified. */ + qva->qva_source |= RPMQV_SPECFILE; + qva->qva_sourceCount++; + qva->qva_mode = 'q'; + qva->qva_specQuery = rpmspecQuery; + + /* Get SRPM name from name of first package */ + qva->qva_queryFormat = "SRPM := SRPMS/%{name}-%{version}-%{release}.src.rpm\n"; + if (spec && spec->packages) + showQueryPackage(qva, ts, spec->packages->header); + + /* Print all packages */ + qva->qva_queryFormat = "RPMS += RPMS/%{ARCH}/%{name}-%{version}-%{release}.%{ARCH}.rpm\n"; + ec = rpmcliQuery(ts, qva, (const char **) &argv[1]); + + ts = rpmtsFree(ts); + context = rpmcliFini(context); + return ec; +}