3 * Handle spec data structure.
17 #define SKIPWHITE(_x) {while(*(_x) && (xisspace(*_x) || *(_x) == ',')) (_x)++;}
18 #define SKIPNONWHITE(_x){while(*(_x) &&!(xisspace(*_x) || *(_x) == ',')) (_x)++;}
20 /*@access Header @*/ /* compared with NULL */
21 /*@access rpmfi @*/ /* compared with NULL */
24 * @param p trigger entry chain
28 /*@null@*/ struct TriggerFileEntry * freeTriggerFiles(/*@only@*/ /*@null@*/ struct TriggerFileEntry * p)
31 struct TriggerFileEntry *o, *q = p;
36 o->fileName = _free(o->fileName);
37 o->script = _free(o->script);
38 o->prog = _free(o->prog);
45 * Destroy source component chain.
46 * @param s source component chain
50 /*@null@*/ struct Source * freeSources(/*@only@*/ /*@null@*/ struct Source * s)
53 struct Source *r, *t = s;
58 r->fullSource = _free(r->fullSource);
64 int lookupPackage(Spec spec, const char *name, int flag, /*@out@*/Package *pkg)
73 *pkg = spec->packages;
77 /* Construct package name */
79 if (flag == PART_SUBNAME) {
80 (void) headerNVR(spec->packages->header, &pname, NULL, NULL);
81 fullName = n = alloca(strlen(pname) + 1 + strlen(name) + 1);
82 while (*pname != '\0') *n++ = *pname++;
85 fullName = n = alloca(strlen(name)+1);
92 /* Locate package with fullName */
93 for (p = spec->packages; p != NULL; p = p->next) {
94 (void) headerNVR(p->header, &pname, NULL, NULL);
95 if (pname && (! strcmp(fullName, pname))) {
101 /*@-dependenttrans@*/ *pkg = p; /*@=dependenttrans@*/
102 return ((p == NULL) ? 1 : 0);
105 Package newPackage(Spec spec)
110 p = xcalloc(1, sizeof(*p));
112 p->header = headerNew();
121 p->triggerScripts = NULL;
124 p->triggerFiles = NULL;
132 p->postInFile = NULL;
134 p->postUnFile = NULL;
135 p->verifyFile = NULL;
137 p->specialDoc = NULL;
139 if (spec->packages == NULL) {
142 /* Always add package to end of list */
143 for (pp = spec->packages; pp->next != NULL; pp = pp->next)
152 Package freePackage(Package pkg)
154 if (pkg == NULL) return NULL;
156 pkg->preInFile = _free(pkg->preInFile);
157 pkg->postInFile = _free(pkg->postInFile);
158 pkg->preUnFile = _free(pkg->preUnFile);
159 pkg->postUnFile = _free(pkg->postUnFile);
160 pkg->verifyFile = _free(pkg->verifyFile);
162 pkg->header = headerFree(pkg->header, "pkg->header");
163 pkg->fileList = freeStringBuf(pkg->fileList);
164 pkg->fileFile = _free(pkg->fileFile);
166 rpmfi fi = pkg->cpioList;
167 pkg->cpioList = NULL;
168 fi = rpmfiFree(fi, 1);
170 /*@-refcounttrans@*/ /* FIX: fi needs to be only */
176 pkg->specialDoc = freeStringBuf(pkg->specialDoc);
177 pkg->icon = freeSources(pkg->icon);
178 pkg->triggerFiles = freeTriggerFiles(pkg->triggerFiles);
184 Package freePackages(Package packages)
188 while ((p = packages) != NULL) {
198 static inline /*@owned@*/ struct Source *findSource(Spec spec, int num, int flag)
203 for (p = spec->sources; p != NULL; p = p->next)
204 if ((num == p->num) && (p->flags & flag)) return p;
209 int parseNoSource(Spec spec, const char * field, int tag)
215 if (tag == RPMTAG_NOSOURCE) {
216 flag = RPMBUILD_ISSOURCE;
219 flag = RPMBUILD_ISPATCH;
224 for (f = fe; *f != '\0'; f = fe) {
232 if (*fe != '\0') fe++;
234 if (parseNum(f, &num)) {
235 rpmError(RPMERR_BADSPEC, _("line %d: Bad number: %s\n"),
237 return RPMERR_BADSPEC;
240 if (! (p = findSource(spec, num, flag))) {
241 rpmError(RPMERR_BADSPEC, _("line %d: Bad no%s number: %d\n"),
242 spec->lineNum, name, num);
243 return RPMERR_BADSPEC;
246 p->flags |= RPMBUILD_ISNO;
253 int addSource(Spec spec, Package pkg, const char *field, int tag)
259 const char *fieldp = NULL;
267 flag = RPMBUILD_ISSOURCE;
269 fieldp = spec->line + 6;
272 flag = RPMBUILD_ISPATCH;
274 fieldp = spec->line + 5;
277 flag = RPMBUILD_ISICON;
284 if (tag != RPMTAG_ICON) {
285 /* We already know that a ':' exists, and that there */
286 /* are no spaces before it. */
287 /* This also now allows for spaces and tabs between */
288 /* the number and the ':' */
291 while ((*fieldp != ':') && (*fieldp != ' ') && (*fieldp != '\t')) {
298 if (nump == NULL || *nump == '\0') {
301 if (parseNum(buf, &num)) {
302 rpmError(RPMERR_BADSPEC, _("line %d: Bad %s number: %s\n"),
303 spec->lineNum, name, spec->line);
304 return RPMERR_BADSPEC;
309 /* Create the entry and link it in */
310 p = xmalloc(sizeof(*p));
312 p->fullSource = xstrdup(field);
314 p->source = strrchr(p->fullSource, '/');
318 p->source = p->fullSource;
321 if (tag != RPMTAG_ICON) {
322 p->next = spec->sources;
331 if (tag != RPMTAG_ICON) {
332 /*@-nullpass@*/ /* LCL: varargs needs null annotate. */
333 const char *body = rpmGetPath("%{_sourcedir}/", p->source, NULL);
337 (flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
338 addMacro(spec->macros, buf, NULL, body, RMIL_SPEC);
339 sprintf(buf, "%sURL%d",
340 (flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
341 addMacro(spec->macros, buf, NULL, p->fullSource, RMIL_SPEC);
350 static inline /*@only@*/ /*@null@*/ speclines newSl(void)
356 sl = xmalloc(sizeof(*sl));
367 static inline /*@null@*/ speclines freeSl(/*@only@*/ /*@null@*/ speclines sl)
371 if (sl == NULL) return NULL;
372 for (i = 0; i < sl->sl_nlines; i++)
373 /*@-unqualifiedtrans@*/
374 sl->sl_lines[i] = _free(sl->sl_lines[i]);
375 /*@=unqualifiedtrans@*/
376 sl->sl_lines = _free(sl->sl_lines);
382 static inline /*@only@*/ /*@null@*/ spectags newSt(void)
388 st = xmalloc(sizeof(*st));
399 static inline /*@null@*/ spectags freeSt(/*@only@*/ /*@null@*/ spectags st)
403 if (st == NULL) return NULL;
404 for (i = 0; i < st->st_ntags; i++) {
405 spectag t = st->st_t + i;
406 t->t_lang = _free(t->t_lang);
407 t->t_msgid = _free(t->t_msgid);
409 st->st_t = _free(st->st_t);
415 Spec spec = xcalloc(1, sizeof(*spec));
417 spec->specFile = NULL;
418 spec->sourceRpmName = NULL;
423 spec->fileStack = NULL;
424 spec->lbuf[0] = '\0';
425 spec->line = spec->lbuf;
426 spec->nextline = NULL;
427 spec->nextpeekc = '\0';
429 spec->readStack = xcalloc(1, sizeof(*spec->readStack));
430 spec->readStack->next = NULL;
431 spec->readStack->reading = 1;
433 spec->rootURL = NULL;
436 spec->install = NULL;
439 spec->sources = NULL;
440 spec->packages = NULL;
442 spec->numSources = 0;
444 spec->sourceHeader = NULL;
446 spec->sourceCpioList = NULL;
448 spec->gotBuildRootURL = 0;
449 spec->buildRootURL = NULL;
450 spec->buildSubdir = NULL;
452 spec->passPhrase = NULL;
456 spec->buildRestrictions = headerNew();
457 spec->BANames = NULL;
460 spec->BASpecs = NULL;
465 /*@i@*/ spec->macros = rpmGlobalMacroContext;
470 Spec freeSpec(Spec spec)
472 struct ReadLevelEntry *rl;
474 if (spec == NULL) return NULL;
476 spec->sl = freeSl(spec->sl);
477 spec->st = freeSt(spec->st);
479 spec->prep = freeStringBuf(spec->prep);
480 spec->build = freeStringBuf(spec->build);
481 spec->install = freeStringBuf(spec->install);
482 spec->clean = freeStringBuf(spec->clean);
484 spec->buildRootURL = _free(spec->buildRootURL);
485 spec->buildSubdir = _free(spec->buildSubdir);
486 spec->rootURL = _free(spec->rootURL);
487 spec->specFile = _free(spec->specFile);
488 spec->sourceRpmName = _free(spec->sourceRpmName);
491 { struct OpenFileInfo *ofi;
492 while (spec->fileStack) {
493 ofi = spec->fileStack;
494 spec->fileStack = ofi->next;
496 ofi->fileName = _free(ofi->fileName);
504 while (spec->readStack) {
505 rl = spec->readStack;
506 /*@-dependenttrans@*/
507 spec->readStack = rl->next;
508 /*@=dependenttrans@*/
513 spec->sourceHeader = headerFree(spec->sourceHeader, "spec->sourceHeader");
515 if (spec->sourceCpioList) {
516 rpmfi fi = spec->sourceCpioList;
517 spec->sourceCpioList = NULL;
518 fi = rpmfiFree(fi, 1);
520 /*@-refcounttrans@*/ /* FIX: fi needs to be only */
526 spec->buildRestrictions = headerFree(spec->buildRestrictions, "spec->>buildRestrictions");
528 if (!spec->recursing) {
529 if (spec->BASpecs != NULL)
530 while (spec->BACount--) {
531 /*@-unqualifiedtrans@*/
532 spec->BASpecs[spec->BACount] =
533 freeSpec(spec->BASpecs[spec->BACount]);
534 /*@=unqualifiedtrans@*/
537 spec->BASpecs = _free(spec->BASpecs);
540 spec->BANames = _free(spec->BANames);
542 spec->passPhrase = _free(spec->passPhrase);
543 spec->cookie = _free(spec->cookie);
545 spec->sources = freeSources(spec->sources);
546 spec->packages = freePackages(spec->packages);
553 /*@only@*/ struct OpenFileInfo * newOpenFileInfo(void)
555 struct OpenFileInfo *ofi;
557 ofi = xmalloc(sizeof(*ofi));
559 ofi->fileName = NULL;
561 ofi->readBuf[0] = '\0';