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 */
24 /*@null@*/ struct TriggerFileEntry * freeTriggerFiles(/*@only@*/ /*@null@*/ struct TriggerFileEntry * p)
27 struct TriggerFileEntry *o, *q = p;
32 o->fileName = _free(o->fileName);
33 o->script = _free(o->script);
34 o->prog = _free(o->prog);
41 * Destroy source component chain.
42 * @param source component chain
46 /*@null@*/ struct Source * freeSources(/*@only@*/ /*@null@*/ struct Source * s)
49 struct Source *r, *t = s;
54 r->fullSource = _free(r->fullSource);
60 int lookupPackage(Spec spec, const char *name, int flag, /*@out@*/Package *pkg)
69 *pkg = spec->packages;
73 /* Construct package name */
75 if (flag == PART_SUBNAME) {
76 (void) headerNVR(spec->packages->header, &pname, NULL, NULL);
77 fullName = n = alloca(strlen(pname) + 1 + strlen(name) + 1);
78 while (*pname != '\0') *n++ = *pname++;
81 fullName = n = alloca(strlen(name)+1);
88 /* Locate package with fullName */
89 for (p = spec->packages; p != NULL; p = p->next) {
90 (void) headerNVR(p->header, &pname, NULL, NULL);
91 if (pname && (! strcmp(fullName, pname))) {
97 /*@-dependenttrans@*/ *pkg = p; /*@=dependenttrans@*/
98 return ((p == NULL) ? 1 : 0);
101 Package newPackage(Spec spec)
106 p = xcalloc(1, sizeof(*p));
108 p->header = headerNew();
117 p->triggerScripts = NULL;
120 p->triggerFiles = NULL;
128 p->postInFile = NULL;
130 p->postUnFile = NULL;
131 p->verifyFile = NULL;
133 p->specialDoc = NULL;
135 if (spec->packages == NULL) {
138 /* Always add package to end of list */
139 for (pp = spec->packages; pp->next != NULL; pp = pp->next)
148 Package freePackage(Package pkg)
150 if (pkg == NULL) return NULL;
152 pkg->preInFile = _free(pkg->preInFile);
153 pkg->postInFile = _free(pkg->postInFile);
154 pkg->preUnFile = _free(pkg->preUnFile);
155 pkg->postUnFile = _free(pkg->postUnFile);
156 pkg->verifyFile = _free(pkg->verifyFile);
158 pkg->header = headerFree(pkg->header);
159 pkg->fileList = freeStringBuf(pkg->fileList);
160 pkg->fileFile = _free(pkg->fileFile);
162 TFI_t fi = pkg->cpioList;
163 pkg->cpioList = NULL;
168 pkg->specialDoc = freeStringBuf(pkg->specialDoc);
169 pkg->icon = freeSources(pkg->icon);
170 pkg->triggerFiles = freeTriggerFiles(pkg->triggerFiles);
176 Package freePackages(Package packages)
180 while ((p = packages) != NULL) {
190 static inline /*@owned@*/ struct Source *findSource(Spec spec, int num, int flag)
195 for (p = spec->sources; p != NULL; p = p->next)
196 if ((num == p->num) && (p->flags & flag)) return p;
201 int parseNoSource(Spec spec, const char * field, int tag)
207 if (tag == RPMTAG_NOSOURCE) {
208 flag = RPMBUILD_ISSOURCE;
211 flag = RPMBUILD_ISPATCH;
216 for (f = fe; *f != '\0'; f = fe) {
224 if (*fe != '\0') fe++;
226 if (parseNum(f, &num)) {
227 rpmError(RPMERR_BADSPEC, _("line %d: Bad number: %s\n"),
229 return RPMERR_BADSPEC;
232 if (! (p = findSource(spec, num, flag))) {
233 rpmError(RPMERR_BADSPEC, _("line %d: Bad no%s number: %d\n"),
234 spec->lineNum, name, num);
235 return RPMERR_BADSPEC;
238 p->flags |= RPMBUILD_ISNO;
245 int addSource(Spec spec, Package pkg, const char *field, int tag)
251 const char *fieldp = NULL;
259 flag = RPMBUILD_ISSOURCE;
261 fieldp = spec->line + 6;
264 flag = RPMBUILD_ISPATCH;
266 fieldp = spec->line + 5;
269 flag = RPMBUILD_ISICON;
276 if (tag != RPMTAG_ICON) {
277 /* We already know that a ':' exists, and that there */
278 /* are no spaces before it. */
279 /* This also now allows for spaces and tabs between */
280 /* the number and the ':' */
283 while ((*fieldp != ':') && (*fieldp != ' ') && (*fieldp != '\t')) {
290 if (nump == NULL || *nump == '\0') {
293 if (parseNum(buf, &num)) {
294 rpmError(RPMERR_BADSPEC, _("line %d: Bad %s number: %s\n"),
295 spec->lineNum, name, spec->line);
296 return RPMERR_BADSPEC;
301 /* Create the entry and link it in */
302 p = xmalloc(sizeof(struct Source));
304 p->fullSource = xstrdup(field);
306 p->source = strrchr(p->fullSource, '/');
310 p->source = p->fullSource;
313 if (tag != RPMTAG_ICON) {
314 p->next = spec->sources;
323 if (tag != RPMTAG_ICON) {
324 /*@-nullpass@*/ /* LCL: varargs needs null annotate. */
325 const char *body = rpmGetPath("%{_sourcedir}/", p->source, NULL);
329 (flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
330 addMacro(spec->macros, buf, NULL, body, RMIL_SPEC);
331 sprintf(buf, "%sURL%d",
332 (flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
333 addMacro(spec->macros, buf, NULL, p->fullSource, RMIL_SPEC);
342 static inline /*@only@*/ /*@null@*/ speclines newSl(void)
348 sl = xmalloc(sizeof(*sl));
359 static inline /*@null@*/ speclines freeSl(/*@only@*/ /*@null@*/ speclines sl)
363 if (sl == NULL) return NULL;
364 for (i = 0; i < sl->sl_nlines; i++)
365 /*@-unqualifiedtrans@*/
366 sl->sl_lines[i] = _free(sl->sl_lines[i]);
367 /*@=unqualifiedtrans@*/
368 sl->sl_lines = _free(sl->sl_lines);
374 static inline /*@only@*/ /*@null@*/ spectags newSt(void)
380 st = xmalloc(sizeof(*st));
391 static inline /*@null@*/ spectags freeSt(/*@only@*/ /*@null@*/ spectags st)
395 if (st == NULL) return NULL;
396 for (i = 0; i < st->st_ntags; i++) {
397 spectag t = st->st_t + i;
398 t->t_lang = _free(t->t_lang);
399 t->t_msgid = _free(t->t_msgid);
401 st->st_t = _free(st->st_t);
407 Spec spec = xcalloc(1, sizeof(*spec));
409 spec->specFile = NULL;
410 spec->sourceRpmName = NULL;
415 spec->fileStack = NULL;
416 spec->lbuf[0] = '\0';
417 spec->line = spec->lbuf;
418 spec->nextline = NULL;
419 spec->nextpeekc = '\0';
421 spec->readStack = xcalloc(1, sizeof(*spec->readStack));
422 spec->readStack->next = NULL;
423 spec->readStack->reading = 1;
425 spec->rootURL = NULL;
428 spec->install = NULL;
431 spec->sources = NULL;
432 spec->packages = NULL;
434 spec->numSources = 0;
436 spec->sourceHeader = NULL;
438 spec->sourceCpioList = NULL;
440 spec->gotBuildRootURL = 0;
441 spec->buildRootURL = NULL;
442 spec->buildSubdir = NULL;
444 spec->passPhrase = NULL;
448 spec->buildRestrictions = headerNew();
449 spec->BANames = NULL;
452 spec->BASpecs = NULL;
457 spec->macros = rpmGlobalMacroContext;
462 Spec freeSpec(Spec spec)
464 struct ReadLevelEntry *rl;
466 if (spec == NULL) return NULL;
468 spec->sl = freeSl(spec->sl);
469 spec->st = freeSt(spec->st);
471 spec->prep = freeStringBuf(spec->prep);
472 spec->build = freeStringBuf(spec->build);
473 spec->install = freeStringBuf(spec->install);
474 spec->clean = freeStringBuf(spec->clean);
476 spec->buildRootURL = _free(spec->buildRootURL);
477 spec->buildSubdir = _free(spec->buildSubdir);
478 spec->rootURL = _free(spec->rootURL);
479 spec->specFile = _free(spec->specFile);
480 spec->sourceRpmName = _free(spec->sourceRpmName);
483 { struct OpenFileInfo *ofi;
484 while (spec->fileStack) {
485 ofi = spec->fileStack;
486 spec->fileStack = ofi->next;
488 ofi->fileName = _free(ofi->fileName);
496 while (spec->readStack) {
497 rl = spec->readStack;
498 /*@-dependenttrans@*/
499 spec->readStack = rl->next;
500 /*@=dependenttrans@*/
505 spec->sourceHeader = headerFree(spec->sourceHeader);
507 if (spec->sourceCpioList) {
508 TFI_t fi = spec->sourceCpioList;
509 spec->sourceCpioList = NULL;
514 spec->buildRestrictions = headerFree(spec->buildRestrictions);
516 if (!spec->recursing) {
517 if (spec->BASpecs != NULL)
518 while (spec->BACount--) {
519 /*@-unqualifiedtrans@*/
520 spec->BASpecs[spec->BACount] =
521 freeSpec(spec->BASpecs[spec->BACount]);
522 /*@=unqualifiedtrans@*/
525 spec->BASpecs = _free(spec->BASpecs);
528 spec->BANames = _free(spec->BANames);
530 spec->passPhrase = _free(spec->passPhrase);
531 spec->cookie = _free(spec->cookie);
533 spec->sources = freeSources(spec->sources);
534 spec->packages = freePackages(spec->packages);
541 /*@only@*/ struct OpenFileInfo * newOpenFileInfo(void)
543 struct OpenFileInfo *ofi;
545 ofi = xmalloc(sizeof(struct OpenFileInfo));
547 ofi->fileName = NULL;
549 ofi->readBuf[0] = '\0';