7 extern MacroContext globalMacroContext;
9 #define SKIPWHITE(_x) {while(*(_x) && (isspace(*_x) || *(_x) == ',')) (_x)++;}
10 #define SKIPNONWHITE(_x){while(*(_x) &&!(isspace(*_x) || *(_x) == ',')) (_x)++;}
12 static inline void freeTriggerFiles(/*@only@*/ struct TriggerFileEntry *p)
14 struct TriggerFileEntry *o, *q = p;
26 static inline void freeCpioList(/*@only@*/ struct cpioFileMapping *cpioList, int cpioCount)
28 struct cpioFileMapping *p = cpioList;
31 rpmMessage(RPMMESS_DEBUG, _("archive = %s, fs = %s\n"),
32 p->archivePath, p->fsPath);
40 static inline void freeSources(/*@only@*/ struct Source *s)
42 struct Source *r, *t = s;
52 int lookupPackage(Spec spec, const char *name, int flag, /*@out@*/Package *pkg)
61 *pkg = spec->packages;
65 /* Construct package name */
67 if (flag == PART_SUBNAME) {
68 headerGetEntry(spec->packages->header, RPMTAG_NAME,
69 NULL, (void **) &pname, NULL);
70 fullName = n = alloca(strlen(pname) + 1 + strlen(name) + 1);
71 while (*pname) *n++ = *pname++;
74 fullName = n = alloca(strlen(name)+1);
79 /* Locate package with fullName */
80 for (p = spec->packages; p != NULL; p = p->next) {
81 headerGetEntry(p->header, RPMTAG_NAME, NULL, (void **) &pname, NULL);
82 if (pname && (! strcmp(fullName, pname))) {
89 return ((p == NULL) ? 1 : 0);
92 Package newPackage(Spec spec)
97 p = xmalloc(sizeof(*p));
99 p->header = headerNew();
108 p->triggerScripts = NULL;
111 p->triggerFiles = NULL;
120 p->postInFile = NULL;
122 p->postUnFile = NULL;
123 p->verifyFile = NULL;
125 p->specialDoc = NULL;
127 if (spec->packages == NULL) {
130 /* Always add package to end of list */
131 for (pp = spec->packages; pp->next != NULL; pp = pp->next)
140 void freePackage(/*@only@*/ Package p)
151 headerFree(p->header);
152 freeStringBuf(p->fileList);
154 freeCpioList(p->cpioList, p->cpioCount);
156 freeStringBuf(p->specialDoc);
158 freeSources(p->icon);
160 freeTriggerFiles(p->triggerFiles);
165 void freePackages(Spec spec)
169 while (spec->packages) {
171 spec->packages = spec->packages->next;
177 static inline /*@owned@*/ struct Source *findSource(Spec spec, int num, int flag)
181 for (p = spec->sources; p != NULL; p = p->next) {
182 if ((num == p->num) && (p->flags & flag)) {
191 static char *getSourceAux(Spec spec, int num, int flag, int full)
193 struct Source *p = spec->sources;
195 p = findSource(spec, num, flag);
197 return (p) ? (full ? p->fullSource : p->source) : NULL;
200 static char *getSource(Spec spec, int num, int flag)
202 return getSourceAux(spec, num, flag, 0);
205 static char *getFullSource(Spec spec, int num, int flag)
207 return getSourceAux(spec, num, flag, 1);
211 int parseNoSource(Spec spec, const char *field, int tag)
217 if (tag == RPMTAG_NOSOURCE) {
218 flag = RPMBUILD_ISSOURCE;
221 flag = RPMBUILD_ISPATCH;
226 for (f = fe; *f; f = fe) {
236 if (parseNum(f, &num)) {
237 rpmError(RPMERR_BADSPEC, _("line %d: Bad number: %s"),
239 return RPMERR_BADSPEC;
242 if (! (p = findSource(spec, num, flag))) {
243 rpmError(RPMERR_BADSPEC, _("line %d: Bad no%s number: %d"),
244 spec->lineNum, name, num);
245 return RPMERR_BADSPEC;
248 p->flags |= RPMBUILD_ISNO;
255 int addSource(Spec spec, Package pkg, const char *field, int tag)
261 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;
283 if (tag != RPMTAG_ICON) {
284 /* We already know that a ':' exists, and that there */
285 /* are no spaces before it. */
286 /* This also now allows for spaces and tabs between */
287 /* the number and the ':' */
290 while ((*fieldp != ':') && (*fieldp != ' ') && (*fieldp != '\t')) {
300 if (parseNum(buf, &num)) {
301 rpmError(RPMERR_BADSPEC, _("line %d: Bad %s number: %s\n"),
302 spec->lineNum, name, spec->line);
303 return RPMERR_BADSPEC;
308 /* Create the entry and link it in */
309 p = xmalloc(sizeof(struct Source));
311 p->fullSource = xstrdup(field);
312 p->source = strrchr(p->fullSource, '/');
317 p->source = p->fullSource;
320 if (tag != RPMTAG_ICON) {
321 p->next = spec->sources;
330 if (tag != RPMTAG_ICON) {
331 const char *body = rpmGetPath("%{_sourcedir}/", p->source, NULL);
334 (flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
335 addMacro(spec->macros, buf, NULL, body, RMIL_SPEC);
336 sprintf(buf, "%sURL%d",
337 (flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
338 addMacro(spec->macros, buf, NULL, p->fullSource, RMIL_SPEC);
345 static inline struct speclines * newSl(void)
347 struct speclines *sl;
348 if (specedit == NULL)
350 sl = xmalloc(sizeof(struct speclines));
357 static inline void freeSl(/*@only@*/struct speclines *sl)
362 for (i = 0; i < sl->sl_nlines; i++)
363 FREE(sl->sl_lines[i]);
368 static inline struct spectags * newSt(void)
371 if (specedit == NULL)
373 st = xmalloc(sizeof(struct spectags));
380 static inline void freeSt(/*@only@*/struct spectags *st)
385 for (i = 0; i < st->st_ntags; i++) {
386 struct spectag *t = st->st_t + i;
398 spec = (Spec)xmalloc(sizeof *spec);
400 spec->specFile = NULL;
401 spec->sourceRpmName = NULL;
406 spec->fileStack = NULL;
407 spec->lbuf[0] = '\0';
408 spec->line = spec->lbuf;
409 spec->nextline = NULL;
410 spec->nextpeekc = '\0';
412 spec->readStack = xmalloc(sizeof(struct ReadLevelEntry));
413 spec->readStack->next = NULL;
414 spec->readStack->reading = 1;
416 spec->rootURL = NULL;
419 spec->install = NULL;
422 spec->sources = NULL;
423 spec->packages = NULL;
425 spec->numSources = 0;
427 spec->sourceHeader = NULL;
429 spec->sourceCpioCount = 0;
430 spec->sourceCpioList = NULL;
432 spec->gotBuildRootURL = 0;
433 spec->buildRootURL = NULL;
434 spec->buildSubdir = NULL;
436 spec->passPhrase = NULL;
440 spec->buildRestrictions = headerNew();
441 spec->buildArchitectures = NULL;
442 spec->buildArchitectureCount = 0;
443 spec->inBuildArchitectures = 0;
444 spec->buildArchitectureSpecs = NULL;
449 spec->macros = &globalMacroContext;
454 void freeSpec(/*@only@*/ Spec spec)
456 struct OpenFileInfo *ofi;
457 struct ReadLevelEntry *rl;
459 freeSl(spec->sl); spec->sl = NULL;
460 freeSt(spec->st); spec->st = NULL;
462 freeStringBuf(spec->prep); spec->prep = NULL;
463 freeStringBuf(spec->build); spec->build = NULL;
464 freeStringBuf(spec->install); spec->install = NULL;
465 freeStringBuf(spec->clean); spec->clean = NULL;
467 FREE(spec->buildRootURL);
468 FREE(spec->buildSubdir);
469 FREE(spec->specFile);
470 FREE(spec->sourceRpmName);
472 while (spec->fileStack) {
473 ofi = spec->fileStack;
474 spec->fileStack = spec->fileStack->next;
480 while (spec->readStack) {
481 rl = spec->readStack;
482 spec->readStack = spec->readStack->next;
487 if (spec->sourceHeader != NULL) {
488 headerFree(spec->sourceHeader);
489 spec->sourceHeader = NULL;
492 freeCpioList(spec->sourceCpioList, spec->sourceCpioCount);
493 spec->sourceCpioList = NULL;
495 headerFree(spec->buildRestrictions);
496 spec->buildRestrictions = NULL;
498 if (!spec->inBuildArchitectures) {
499 while (spec->buildArchitectureCount--) {
501 spec->buildArchitectureSpecs[spec->buildArchitectureCount]);
503 FREE(spec->buildArchitectureSpecs);
505 FREE(spec->buildArchitectures);
507 FREE(spec->passPhrase);
510 freeSources(spec->sources); spec->sources = NULL;
517 /*@only@*/ struct OpenFileInfo * newOpenFileInfo(void)
519 struct OpenFileInfo *ofi;
521 ofi = xmalloc(sizeof(struct OpenFileInfo));
523 ofi->fileName = NULL;
525 ofi->readBuf[0] = '\0';