3 * Handle spec data structure.
15 #define SKIPWHITE(_x) {while(*(_x) && (xisspace(*_x) || *(_x) == ',')) (_x)++;}
16 #define SKIPNONWHITE(_x){while(*(_x) &&!(xisspace(*_x) || *(_x) == ',')) (_x)++;}
18 /*@access Header @*/ /* compared with NULL */
19 /*@access TFI_t @*/ /* compared with NULL */
22 * @param p trigger entry chain
26 /*@null@*/ struct TriggerFileEntry * freeTriggerFiles(/*@only@*/ /*@null@*/ 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 /*@null@*/ struct Source * freeSources(/*@only@*/ /*@null@*/ struct Source * s)
51 struct Source *r, *t = s;
56 r->fullSource = _free(r->fullSource);
62 int lookupPackage(Spec spec, const char *name, int flag, /*@out@*/Package *pkg)
71 *pkg = spec->packages;
75 /* Construct package name */
77 if (flag == PART_SUBNAME) {
78 (void) headerNVR(spec->packages->header, &pname, NULL, NULL);
79 fullName = n = alloca(strlen(pname) + 1 + strlen(name) + 1);
80 while (*pname != '\0') *n++ = *pname++;
83 fullName = n = alloca(strlen(name)+1);
90 /* Locate package with fullName */
91 for (p = spec->packages; p != NULL; p = p->next) {
92 (void) headerNVR(p->header, &pname, NULL, NULL);
93 if (pname && (! strcmp(fullName, pname))) {
99 /*@-dependenttrans@*/ *pkg = p; /*@=dependenttrans@*/
100 return ((p == NULL) ? 1 : 0);
103 Package newPackage(Spec spec)
108 p = xcalloc(1, sizeof(*p));
110 p->header = headerNew();
119 p->triggerScripts = NULL;
122 p->triggerFiles = NULL;
130 p->postInFile = NULL;
132 p->postUnFile = NULL;
133 p->verifyFile = NULL;
135 p->specialDoc = NULL;
137 if (spec->packages == NULL) {
140 /* Always add package to end of list */
141 for (pp = spec->packages; pp->next != NULL; pp = pp->next)
150 Package freePackage(Package pkg)
152 if (pkg == NULL) return NULL;
154 pkg->preInFile = _free(pkg->preInFile);
155 pkg->postInFile = _free(pkg->postInFile);
156 pkg->preUnFile = _free(pkg->preUnFile);
157 pkg->postUnFile = _free(pkg->postUnFile);
158 pkg->verifyFile = _free(pkg->verifyFile);
160 pkg->header = headerFree(pkg->header, "pkg->header");
161 pkg->fileList = freeStringBuf(pkg->fileList);
162 pkg->fileFile = _free(pkg->fileFile);
164 TFI_t fi = pkg->cpioList;
165 pkg->cpioList = NULL;
168 /*@-refcounttrans@*/ /* FIX: fi needs to be only */
174 pkg->specialDoc = freeStringBuf(pkg->specialDoc);
175 pkg->icon = freeSources(pkg->icon);
176 pkg->triggerFiles = freeTriggerFiles(pkg->triggerFiles);
182 Package freePackages(Package packages)
186 while ((p = packages) != NULL) {
196 static inline /*@owned@*/ struct Source *findSource(Spec spec, int num, int flag)
201 for (p = spec->sources; p != NULL; p = p->next)
202 if ((num == p->num) && (p->flags & flag)) return p;
207 int parseNoSource(Spec spec, const char * field, int tag)
213 if (tag == RPMTAG_NOSOURCE) {
214 flag = RPMBUILD_ISSOURCE;
217 flag = RPMBUILD_ISPATCH;
222 for (f = fe; *f != '\0'; f = fe) {
230 if (*fe != '\0') fe++;
232 if (parseNum(f, &num)) {
233 rpmError(RPMERR_BADSPEC, _("line %d: Bad number: %s\n"),
235 return RPMERR_BADSPEC;
238 if (! (p = findSource(spec, num, flag))) {
239 rpmError(RPMERR_BADSPEC, _("line %d: Bad no%s number: %d\n"),
240 spec->lineNum, name, num);
241 return RPMERR_BADSPEC;
244 p->flags |= RPMBUILD_ISNO;
251 int addSource(Spec spec, Package pkg, const char *field, int tag)
257 const char *fieldp = NULL;
265 flag = RPMBUILD_ISSOURCE;
267 fieldp = spec->line + 6;
270 flag = RPMBUILD_ISPATCH;
272 fieldp = spec->line + 5;
275 flag = RPMBUILD_ISICON;
282 if (tag != RPMTAG_ICON) {
283 /* We already know that a ':' exists, and that there */
284 /* are no spaces before it. */
285 /* This also now allows for spaces and tabs between */
286 /* the number and the ':' */
289 while ((*fieldp != ':') && (*fieldp != ' ') && (*fieldp != '\t')) {
296 if (nump == NULL || *nump == '\0') {
299 if (parseNum(buf, &num)) {
300 rpmError(RPMERR_BADSPEC, _("line %d: Bad %s number: %s\n"),
301 spec->lineNum, name, spec->line);
302 return RPMERR_BADSPEC;
307 /* Create the entry and link it in */
308 p = xmalloc(sizeof(*p));
310 p->fullSource = xstrdup(field);
312 p->source = strrchr(p->fullSource, '/');
316 p->source = p->fullSource;
319 if (tag != RPMTAG_ICON) {
320 p->next = spec->sources;
329 if (tag != RPMTAG_ICON) {
330 /*@-nullpass@*/ /* LCL: varargs needs null annotate. */
331 const char *body = rpmGetPath("%{_sourcedir}/", p->source, NULL);
335 (flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
336 addMacro(spec->macros, buf, NULL, body, RMIL_SPEC);
337 sprintf(buf, "%sURL%d",
338 (flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
339 addMacro(spec->macros, buf, NULL, p->fullSource, RMIL_SPEC);
348 static inline /*@only@*/ /*@null@*/ speclines newSl(void)
354 sl = xmalloc(sizeof(*sl));
365 static inline /*@null@*/ speclines freeSl(/*@only@*/ /*@null@*/ speclines sl)
369 if (sl == NULL) return NULL;
370 for (i = 0; i < sl->sl_nlines; i++)
371 /*@-unqualifiedtrans@*/
372 sl->sl_lines[i] = _free(sl->sl_lines[i]);
373 /*@=unqualifiedtrans@*/
374 sl->sl_lines = _free(sl->sl_lines);
380 static inline /*@only@*/ /*@null@*/ spectags newSt(void)
386 st = xmalloc(sizeof(*st));
397 static inline /*@null@*/ spectags freeSt(/*@only@*/ /*@null@*/ spectags st)
401 if (st == NULL) return NULL;
402 for (i = 0; i < st->st_ntags; i++) {
403 spectag t = st->st_t + i;
404 t->t_lang = _free(t->t_lang);
405 t->t_msgid = _free(t->t_msgid);
407 st->st_t = _free(st->st_t);
413 Spec spec = xcalloc(1, sizeof(*spec));
415 spec->specFile = NULL;
416 spec->sourceRpmName = NULL;
421 spec->fileStack = NULL;
422 spec->lbuf[0] = '\0';
423 spec->line = spec->lbuf;
424 spec->nextline = NULL;
425 spec->nextpeekc = '\0';
427 spec->readStack = xcalloc(1, sizeof(*spec->readStack));
428 spec->readStack->next = NULL;
429 spec->readStack->reading = 1;
431 spec->rootURL = NULL;
434 spec->install = NULL;
437 spec->sources = NULL;
438 spec->packages = NULL;
440 spec->numSources = 0;
442 spec->sourceHeader = NULL;
444 spec->sourceCpioList = NULL;
446 spec->gotBuildRootURL = 0;
447 spec->buildRootURL = NULL;
448 spec->buildSubdir = NULL;
450 spec->passPhrase = NULL;
454 spec->buildRestrictions = headerNew();
455 spec->BANames = NULL;
458 spec->BASpecs = NULL;
463 /*@i@*/ spec->macros = rpmGlobalMacroContext;
468 Spec freeSpec(Spec spec)
470 struct ReadLevelEntry *rl;
472 if (spec == NULL) return NULL;
474 spec->sl = freeSl(spec->sl);
475 spec->st = freeSt(spec->st);
477 spec->prep = freeStringBuf(spec->prep);
478 spec->build = freeStringBuf(spec->build);
479 spec->install = freeStringBuf(spec->install);
480 spec->clean = freeStringBuf(spec->clean);
482 spec->buildRootURL = _free(spec->buildRootURL);
483 spec->buildSubdir = _free(spec->buildSubdir);
484 spec->rootURL = _free(spec->rootURL);
485 spec->specFile = _free(spec->specFile);
486 spec->sourceRpmName = _free(spec->sourceRpmName);
489 { struct OpenFileInfo *ofi;
490 while (spec->fileStack) {
491 ofi = spec->fileStack;
492 spec->fileStack = ofi->next;
494 ofi->fileName = _free(ofi->fileName);
502 while (spec->readStack) {
503 rl = spec->readStack;
504 /*@-dependenttrans@*/
505 spec->readStack = rl->next;
506 /*@=dependenttrans@*/
511 spec->sourceHeader = headerFree(spec->sourceHeader, "spec->sourceHeader");
513 if (spec->sourceCpioList) {
514 TFI_t fi = spec->sourceCpioList;
515 spec->sourceCpioList = NULL;
518 /*@-refcounttrans@*/ /* FIX: fi needs to be only */
524 spec->buildRestrictions = headerFree(spec->buildRestrictions, "spec->>buildRestrictions");
526 if (!spec->recursing) {
527 if (spec->BASpecs != NULL)
528 while (spec->BACount--) {
529 /*@-unqualifiedtrans@*/
530 spec->BASpecs[spec->BACount] =
531 freeSpec(spec->BASpecs[spec->BACount]);
532 /*@=unqualifiedtrans@*/
535 spec->BASpecs = _free(spec->BASpecs);
538 spec->BANames = _free(spec->BANames);
540 spec->passPhrase = _free(spec->passPhrase);
541 spec->cookie = _free(spec->cookie);
543 spec->sources = freeSources(spec->sources);
544 spec->packages = freePackages(spec->packages);
551 /*@only@*/ struct OpenFileInfo * newOpenFileInfo(void)
553 struct OpenFileInfo *ofi;
555 ofi = xmalloc(sizeof(*ofi));
557 ofi->fileName = NULL;
559 ofi->readBuf[0] = '\0';