summaryrefslogtreecommitdiff
path: root/build/spec.c
diff options
context:
space:
mode:
Diffstat (limited to 'build/spec.c')
-rw-r--r--build/spec.c428
1 files changed, 428 insertions, 0 deletions
diff --git a/build/spec.c b/build/spec.c
new file mode 100644
index 0000000..a4a321f
--- /dev/null
+++ b/build/spec.c
@@ -0,0 +1,428 @@
+/** \ingroup rpmbuild
+ * \file build/spec.c
+ * Handle spec data structure.
+ */
+
+#include "system.h"
+
+#include <rpm/header.h>
+#include <rpm/rpmds.h>
+#include <rpm/rpmfi.h>
+#include <rpm/rpmts.h>
+#include <rpm/rpmlog.h>
+#include <rpm/rpmfileutil.h>
+
+#include "rpmio/rpmlua.h"
+#include "build/rpmbuild_internal.h"
+
+#include "debug.h"
+
+#define SKIPSPACE(s) { while (*(s) && risspace(*(s))) (s)++; }
+
+/**
+ * @param p trigger entry chain
+ * @return NULL always
+ */
+static inline
+struct TriggerFileEntry * freeTriggerFiles(struct TriggerFileEntry * p)
+{
+ struct TriggerFileEntry *o, *q = p;
+
+ while (q != NULL) {
+ o = q;
+ q = q->next;
+ o->fileName = _free(o->fileName);
+ o->script = _free(o->script);
+ o->prog = _free(o->prog);
+ o = _free(o);
+ }
+ return NULL;
+}
+
+/**
+ * Destroy source component chain.
+ * @param s source component chain
+ * @return NULL always
+ */
+static inline
+struct Source * freeSources(struct Source * s)
+{
+ struct Source *r, *t = s;
+
+ while (t != NULL) {
+ r = t;
+ t = t->next;
+ r->fullSource = _free(r->fullSource);
+ r = _free(r);
+ }
+ return NULL;
+}
+
+rpmRC lookupPackage(rpmSpec spec, const char *name, int flag,Package *pkg)
+{
+ const char *pname;
+ char *fullName = NULL;
+ Package p;
+
+ /* "main" package */
+ if (name == NULL) {
+ if (pkg)
+ *pkg = spec->packages;
+ return RPMRC_OK;
+ }
+
+ /* Construct package name */
+ if (flag == PART_SUBNAME) {
+ pname = headerGetString(spec->packages->header, RPMTAG_NAME);
+ rasprintf(&fullName, "%s-%s", pname, name);
+ } else {
+ fullName = xstrdup(name);
+ }
+
+ /* Locate package with fullName */
+ for (p = spec->packages; p != NULL; p = p->next) {
+ pname = headerGetString(p->header, RPMTAG_NAME);
+ if (pname && (rstreq(fullName, pname))) {
+ break;
+ }
+ }
+ free(fullName);
+
+ if (pkg)
+ *pkg = p;
+ return ((p == NULL) ? RPMRC_FAIL : RPMRC_OK);
+}
+
+Package newPackage(rpmSpec spec)
+{
+ Package p = xcalloc(1, sizeof(*p));
+ p->header = headerNew();
+ p->autoProv = 1;
+ p->autoReq = 1;
+ p->fileList = NULL;
+ p->fileFile = NULL;
+ p->policyList = NULL;
+
+ if (spec->packages == NULL) {
+ spec->packages = p;
+ } else {
+ Package pp;
+ /* Always add package to end of list */
+ for (pp = spec->packages; pp->next != NULL; pp = pp->next)
+ {};
+ pp->next = p;
+ }
+ p->next = NULL;
+
+ return p;
+}
+
+static Package freePackage(Package pkg)
+{
+ if (pkg == NULL) return NULL;
+
+ pkg->preInFile = _free(pkg->preInFile);
+ pkg->postInFile = _free(pkg->postInFile);
+ pkg->preUnFile = _free(pkg->preUnFile);
+ pkg->postUnFile = _free(pkg->postUnFile);
+ pkg->verifyFile = _free(pkg->verifyFile);
+
+ pkg->header = headerFree(pkg->header);
+ pkg->ds = rpmdsFree(pkg->ds);
+ pkg->fileList = argvFree(pkg->fileList);
+ pkg->fileFile = argvFree(pkg->fileFile);
+ pkg->policyList = argvFree(pkg->policyList);
+ if (pkg->cpioList) {
+ rpmfi fi = pkg->cpioList;
+ pkg->cpioList = NULL;
+ fi = rpmfiFree(fi);
+ }
+
+ pkg->specialDoc = freeStringBuf(pkg->specialDoc);
+ pkg->specialDocDir = _free(pkg->specialDocDir);
+ pkg->icon = freeSources(pkg->icon);
+ pkg->triggerFiles = freeTriggerFiles(pkg->triggerFiles);
+
+ pkg = _free(pkg);
+ return NULL;
+}
+
+static Package freePackages(Package packages)
+{
+ Package p;
+
+ while ((p = packages) != NULL) {
+ packages = p->next;
+ p->next = NULL;
+ p = freePackage(p);
+ }
+ return NULL;
+}
+
+rpmSpec newSpec(void)
+{
+ rpmSpec spec = xcalloc(1, sizeof(*spec));
+
+ spec->specFile = NULL;
+
+ spec->fileStack = NULL;
+ spec->lbuf[0] = '\0';
+ spec->line = spec->lbuf;
+ spec->nextline = NULL;
+ spec->nextpeekc = '\0';
+ spec->lineNum = 0;
+ spec->readStack = xcalloc(1, sizeof(*spec->readStack));
+ spec->readStack->next = NULL;
+ spec->readStack->reading = 1;
+
+ spec->rootDir = NULL;
+ spec->prep = NULL;
+ spec->build = NULL;
+ spec->install = NULL;
+ spec->check = NULL;
+ spec->clean = NULL;
+ spec->parsed = NULL;
+
+ spec->sources = NULL;
+ spec->packages = NULL;
+ spec->noSource = 0;
+ spec->numSources = 0;
+
+ spec->sourceRpmName = NULL;
+ spec->sourcePkgId = NULL;
+ spec->sourceHeader = NULL;
+ spec->sourceCpioList = NULL;
+
+ spec->buildRoot = NULL;
+ spec->buildSubdir = NULL;
+
+ spec->buildRestrictions = headerNew();
+ spec->BANames = NULL;
+ spec->BACount = 0;
+ spec->recursing = 0;
+ spec->BASpecs = NULL;
+
+ spec->flags = RPMSPEC_NONE;
+
+ spec->macros = rpmGlobalMacroContext;
+
+#ifdef WITH_LUA
+ {
+ /* make sure patches and sources tables always exist */
+ rpmlua lua = NULL; /* global state */
+ rpmluaPushTable(lua, "patches");
+ rpmluaPushTable(lua, "sources");
+ rpmluaPop(lua);
+ rpmluaPop(lua);
+ }
+#endif
+ return spec;
+}
+
+rpmSpec rpmSpecFree(rpmSpec spec)
+{
+
+ if (spec == NULL) return NULL;
+
+ spec->prep = freeStringBuf(spec->prep);
+ spec->build = freeStringBuf(spec->build);
+ spec->install = freeStringBuf(spec->install);
+ spec->check = freeStringBuf(spec->check);
+ spec->clean = freeStringBuf(spec->clean);
+ spec->parsed = freeStringBuf(spec->parsed);
+
+ spec->buildRoot = _free(spec->buildRoot);
+ spec->buildSubdir = _free(spec->buildSubdir);
+ spec->specFile = _free(spec->specFile);
+
+ closeSpec(spec);
+
+ while (spec->readStack) {
+ struct ReadLevelEntry *rl = spec->readStack;
+ spec->readStack = rl->next;
+ rl->next = NULL;
+ free(rl);
+ }
+
+ spec->sourceRpmName = _free(spec->sourceRpmName);
+ spec->sourcePkgId = _free(spec->sourcePkgId);
+ spec->sourceHeader = headerFree(spec->sourceHeader);
+
+ if (spec->sourceCpioList) {
+ rpmfi fi = spec->sourceCpioList;
+ spec->sourceCpioList = NULL;
+ fi = rpmfiFree(fi);
+ }
+
+ spec->buildRestrictions = headerFree(spec->buildRestrictions);
+
+ if (!spec->recursing) {
+ if (spec->BASpecs != NULL)
+ while (spec->BACount--) {
+ spec->BASpecs[spec->BACount] =
+ rpmSpecFree(spec->BASpecs[spec->BACount]);
+ }
+ spec->BASpecs = _free(spec->BASpecs);
+ }
+ spec->BANames = _free(spec->BANames);
+
+#ifdef WITH_LUA
+ rpmlua lua = NULL; /* global state */
+ rpmluaDelVar(lua, "patches");
+ rpmluaDelVar(lua, "sources");
+#endif
+
+ spec->sources = freeSources(spec->sources);
+ spec->packages = freePackages(spec->packages);
+
+ spec = _free(spec);
+
+ return spec;
+}
+
+Header rpmSpecSourceHeader(rpmSpec spec)
+{
+ return spec->sourceHeader;
+}
+
+rpmds rpmSpecDS(rpmSpec spec, rpmTagVal tag)
+{
+ return (spec != NULL) ? rpmdsNew(spec->buildRestrictions, tag, 0) : NULL;
+}
+
+rpmps rpmSpecCheckDeps(rpmts ts, rpmSpec spec)
+{
+ rpmps probs = NULL;
+
+ rpmtsEmpty(ts);
+
+ rpmtsAddInstallElement(ts, rpmSpecSourceHeader(spec), NULL, 0, NULL);
+ rpmtsCheck(ts);
+ probs = rpmtsProblems(ts);
+
+ rpmtsEmpty(ts);
+ return probs;
+}
+
+struct rpmSpecIter_s {
+ void *next;
+};
+
+#define SPEC_LISTITER_INIT(_itertype, _iteritem) \
+ _itertype iter = NULL; \
+ if (spec) { \
+ iter = xcalloc(1, sizeof(*iter)); \
+ iter->next = spec->_iteritem; \
+ } \
+ return iter
+
+#define SPEC_LISTITER_NEXT(_valuetype) \
+ _valuetype item = NULL; \
+ if (iter) { \
+ item = iter->next; \
+ iter->next = (item) ? item->next : NULL; \
+ } \
+ return item
+
+#define SPEC_LISTITER_FREE() \
+ free(iter); \
+ return NULL
+
+
+rpmSpecPkgIter rpmSpecPkgIterInit(rpmSpec spec)
+{
+ SPEC_LISTITER_INIT(rpmSpecPkgIter, packages);
+}
+
+rpmSpecPkgIter rpmSpecPkgIterFree(rpmSpecPkgIter iter)
+{
+ SPEC_LISTITER_FREE();
+}
+
+rpmSpecPkg rpmSpecPkgIterNext(rpmSpecPkgIter iter)
+{
+ SPEC_LISTITER_NEXT(rpmSpecPkg);
+}
+
+Header rpmSpecPkgHeader(rpmSpecPkg pkg)
+{
+ return (pkg != NULL) ? pkg->header : NULL;
+}
+
+rpmSpecSrcIter rpmSpecSrcIterInit(rpmSpec spec)
+{
+ SPEC_LISTITER_INIT(rpmSpecSrcIter, sources);
+}
+
+rpmSpecSrcIter rpmSpecSrcIterFree(rpmSpecSrcIter iter)
+{
+ SPEC_LISTITER_FREE();
+}
+
+rpmSpecSrc rpmSpecSrcIterNext(rpmSpecSrcIter iter)
+{
+ SPEC_LISTITER_NEXT(rpmSpecSrc);
+}
+
+rpmSourceFlags rpmSpecSrcFlags(rpmSpecSrc src)
+{
+ return (src != NULL) ? src->flags : 0;
+}
+
+int rpmSpecSrcNum(rpmSpecSrc src)
+{
+ return (src != NULL) ? src->num : -1;
+}
+
+const char * rpmSpecSrcFilename(rpmSpecSrc src, int full)
+{
+ const char *source = NULL;
+ if (src) {
+ source = full ? src->fullSource : src->source;
+ }
+ return source;
+}
+
+const char * rpmSpecGetSection(rpmSpec spec, int section)
+{
+ if (spec) {
+ switch (section) {
+ case RPMBUILD_NONE: return getStringBuf(spec->parsed);
+ case RPMBUILD_PREP: return getStringBuf(spec->prep);
+ case RPMBUILD_BUILD: return getStringBuf(spec->build);
+ case RPMBUILD_INSTALL: return getStringBuf(spec->install);
+ case RPMBUILD_CHECK: return getStringBuf(spec->check);
+ case RPMBUILD_CLEAN: return getStringBuf(spec->clean);
+ }
+ }
+ return NULL;
+}
+
+int rpmspecQuery(rpmts ts, QVA_t qva, const char * arg)
+{
+ rpmSpec spec = NULL;
+ int res = 1;
+ int xx;
+
+ if (qva->qva_showPackage == NULL)
+ goto exit;
+
+ spec = rpmSpecParse(arg, (RPMSPEC_ANYARCH|RPMSPEC_FORCE), NULL);
+ if (spec == NULL) {
+ rpmlog(RPMLOG_ERR,
+ _("query of specfile %s failed, can't parse\n"), arg);
+ goto exit;
+ }
+
+ res = 0;
+ if (qva->qva_source == RPMQV_SPECRPMS) {
+ for (Package pkg = spec->packages; pkg != NULL; pkg = pkg->next)
+ xx = qva->qva_showPackage(qva, ts, pkg->header);
+ } else {
+ xx = qva->qva_showPackage(qva, ts, spec->sourceHeader);
+ }
+
+exit:
+ spec = rpmSpecFree(spec);
+ return res;
+}