3 * Handle spec data structure.
8 #include <rpm/header.h>
10 #include <rpm/rpmfi.h>
11 #include <rpm/rpmts.h>
12 #include <rpm/rpmlog.h>
13 #include <rpm/rpmfileutil.h>
15 #include "rpmio/rpmlua.h"
16 #include "build/rpmbuild_internal.h"
20 #define SKIPSPACE(s) { while (*(s) && risspace(*(s))) (s)++; }
23 * @param p trigger entry chain
27 struct TriggerFileEntry * freeTriggerFiles(struct TriggerFileEntry * p)
29 struct TriggerFileEntry *o, *q = p;
34 o->fileName = _free(o->fileName);
35 o->script = _free(o->script);
36 o->prog = _free(o->prog);
43 * Destroy source component chain.
44 * @param s source component chain
48 struct Source * freeSources(struct Source * s)
50 struct Source *r, *t = s;
55 r->fullSource = _free(r->fullSource);
61 rpmRC lookupPackage(rpmSpec spec, const char *name, int flag,Package *pkg)
64 char *fullName = NULL;
70 *pkg = spec->packages;
74 /* Construct package name */
75 if (flag == PART_SUBNAME) {
76 pname = headerGetString(spec->packages->header, RPMTAG_NAME);
77 rasprintf(&fullName, "%s-%s", pname, name);
79 fullName = xstrdup(name);
82 /* Locate package with fullName */
83 for (p = spec->packages; p != NULL; p = p->next) {
84 pname = headerGetString(p->header, RPMTAG_NAME);
85 if (pname && (rstreq(fullName, pname))) {
93 return ((p == NULL) ? RPMRC_FAIL : RPMRC_OK);
96 Package newPackage(rpmSpec spec)
98 Package p = xcalloc(1, sizeof(*p));
99 p->header = headerNew();
104 p->policyList = NULL;
106 if (spec->packages == NULL) {
110 /* Always add package to end of list */
111 for (pp = spec->packages; pp->next != NULL; pp = pp->next)
120 static Package freePackage(Package pkg)
122 if (pkg == NULL) return NULL;
124 pkg->preInFile = _free(pkg->preInFile);
125 pkg->postInFile = _free(pkg->postInFile);
126 pkg->preUnFile = _free(pkg->preUnFile);
127 pkg->postUnFile = _free(pkg->postUnFile);
128 pkg->verifyFile = _free(pkg->verifyFile);
130 pkg->header = headerFree(pkg->header);
131 pkg->ds = rpmdsFree(pkg->ds);
132 pkg->fileList = argvFree(pkg->fileList);
133 pkg->fileFile = argvFree(pkg->fileFile);
134 pkg->policyList = argvFree(pkg->policyList);
135 pkg->cpioList = rpmfiFree(pkg->cpioList);
137 pkg->icon = freeSources(pkg->icon);
138 pkg->triggerFiles = freeTriggerFiles(pkg->triggerFiles);
144 static Package freePackages(Package packages)
148 while ((p = packages) != NULL) {
156 rpmSpec newSpec(void)
158 rpmSpec spec = xcalloc(1, sizeof(*spec));
160 spec->specFile = NULL;
162 spec->fileStack = NULL;
163 spec->lbufSize = BUFSIZ * 10;
164 spec->lbuf = xmalloc(spec->lbufSize);
165 spec->lbuf[0] = '\0';
166 spec->line = spec->lbuf;
167 spec->nextline = NULL;
168 spec->nextpeekc = '\0';
170 spec->readStack = xcalloc(1, sizeof(*spec->readStack));
171 spec->readStack->next = NULL;
172 spec->readStack->reading = 1;
174 spec->rootDir = NULL;
177 spec->install = NULL;
182 spec->sources = NULL;
183 spec->packages = NULL;
185 spec->numSources = 0;
187 spec->sourceRpmName = NULL;
188 spec->sourcePkgId = NULL;
189 spec->sourceHeader = NULL;
190 spec->sourceCpioList = NULL;
192 spec->buildRoot = NULL;
193 spec->buildSubdir = NULL;
195 spec->buildRestrictions = headerNew();
196 spec->BANames = NULL;
199 spec->BASpecs = NULL;
201 spec->flags = RPMSPEC_NONE;
203 spec->macros = rpmGlobalMacroContext;
207 /* make sure patches and sources tables always exist */
208 rpmlua lua = NULL; /* global state */
209 rpmluaPushTable(lua, "patches");
210 rpmluaPushTable(lua, "sources");
218 rpmSpec rpmSpecFree(rpmSpec spec)
221 if (spec == NULL) return NULL;
223 spec->prep = freeStringBuf(spec->prep);
224 spec->build = freeStringBuf(spec->build);
225 spec->install = freeStringBuf(spec->install);
226 spec->check = freeStringBuf(spec->check);
227 spec->clean = freeStringBuf(spec->clean);
228 spec->parsed = freeStringBuf(spec->parsed);
230 spec->buildRoot = _free(spec->buildRoot);
231 spec->buildSubdir = _free(spec->buildSubdir);
232 spec->specFile = _free(spec->specFile);
236 while (spec->readStack) {
237 struct ReadLevelEntry *rl = spec->readStack;
238 spec->readStack = rl->next;
242 spec->lbuf = _free(spec->lbuf);
244 spec->sourceRpmName = _free(spec->sourceRpmName);
245 spec->sourcePkgId = _free(spec->sourcePkgId);
246 spec->sourceHeader = headerFree(spec->sourceHeader);
247 spec->sourceCpioList = rpmfiFree(spec->sourceCpioList);
249 spec->buildRestrictions = headerFree(spec->buildRestrictions);
251 if (!spec->recursing) {
252 if (spec->BASpecs != NULL)
253 while (spec->BACount--) {
254 spec->BASpecs[spec->BACount] =
255 rpmSpecFree(spec->BASpecs[spec->BACount]);
257 spec->BASpecs = _free(spec->BASpecs);
259 spec->BANames = _free(spec->BANames);
262 rpmlua lua = NULL; /* global state */
263 rpmluaDelVar(lua, "patches");
264 rpmluaDelVar(lua, "sources");
267 spec->sources = freeSources(spec->sources);
268 spec->packages = freePackages(spec->packages);
275 Header rpmSpecSourceHeader(rpmSpec spec)
277 return spec->sourceHeader;
280 rpmds rpmSpecDS(rpmSpec spec, rpmTagVal tag)
282 return (spec != NULL) ? rpmdsNew(spec->buildRestrictions, tag, 0) : NULL;
285 rpmps rpmSpecCheckDeps(rpmts ts, rpmSpec spec)
291 rpmtsAddInstallElement(ts, rpmSpecSourceHeader(spec), NULL, 0, NULL);
293 probs = rpmtsProblems(ts);
299 struct rpmSpecIter_s {
303 #define SPEC_LISTITER_INIT(_itertype, _iteritem) \
304 _itertype iter = NULL; \
306 iter = xcalloc(1, sizeof(*iter)); \
307 iter->next = spec->_iteritem; \
311 #define SPEC_LISTITER_NEXT(_valuetype) \
312 _valuetype item = NULL; \
315 iter->next = (item) ? item->next : NULL; \
319 #define SPEC_LISTITER_FREE() \
324 rpmSpecPkgIter rpmSpecPkgIterInit(rpmSpec spec)
326 SPEC_LISTITER_INIT(rpmSpecPkgIter, packages);
329 rpmSpecPkgIter rpmSpecPkgIterFree(rpmSpecPkgIter iter)
331 SPEC_LISTITER_FREE();
334 rpmSpecPkg rpmSpecPkgIterNext(rpmSpecPkgIter iter)
336 SPEC_LISTITER_NEXT(rpmSpecPkg);
339 Header rpmSpecPkgHeader(rpmSpecPkg pkg)
341 return (pkg != NULL) ? pkg->header : NULL;
344 rpmSpecSrcIter rpmSpecSrcIterInit(rpmSpec spec)
346 SPEC_LISTITER_INIT(rpmSpecSrcIter, sources);
349 rpmSpecSrcIter rpmSpecSrcIterFree(rpmSpecSrcIter iter)
351 SPEC_LISTITER_FREE();
354 rpmSpecSrc rpmSpecSrcIterNext(rpmSpecSrcIter iter)
356 SPEC_LISTITER_NEXT(rpmSpecSrc);
359 rpmSourceFlags rpmSpecSrcFlags(rpmSpecSrc src)
361 return (src != NULL) ? src->flags : 0;
364 int rpmSpecSrcNum(rpmSpecSrc src)
366 return (src != NULL) ? src->num : -1;
369 const char * rpmSpecSrcFilename(rpmSpecSrc src, int full)
371 const char *source = NULL;
373 source = full ? src->fullSource : src->source;
378 const char * rpmSpecGetSection(rpmSpec spec, int section)
382 case RPMBUILD_NONE: return getStringBuf(spec->parsed);
383 case RPMBUILD_PREP: return getStringBuf(spec->prep);
384 case RPMBUILD_BUILD: return getStringBuf(spec->build);
385 case RPMBUILD_INSTALL: return getStringBuf(spec->install);
386 case RPMBUILD_CHECK: return getStringBuf(spec->check);
387 case RPMBUILD_CLEAN: return getStringBuf(spec->clean);
393 int rpmspecQuery(rpmts ts, QVA_t qva, const char * arg)
398 if (qva->qva_showPackage == NULL)
401 spec = rpmSpecParse(arg, (RPMSPEC_ANYARCH|RPMSPEC_FORCE), NULL);
404 _("query of specfile %s failed, can't parse\n"), arg);
408 if (qva->qva_source == RPMQV_SPECRPMS) {
410 for (Package pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
413 * XXX FIXME: whether to show all or just the packages that
414 * would be built needs to be made caller specifiable, for now
415 * revert to "traditional" behavior as existing tools rely on this.
417 if (pkg->fileList == NULL) continue;
419 res += qva->qva_showPackage(qva, ts, pkg->header);
422 res = qva->qva_showPackage(qva, ts, spec->sourceHeader);