3 * Handle spec data structure.
13 extern MacroContext rpmGlobalMacroContext;
15 #define SKIPWHITE(_x) {while(*(_x) && (isspace(*_x) || *(_x) == ',')) (_x)++;}
16 #define SKIPNONWHITE(_x){while(*(_x) &&!(isspace(*_x) || *(_x) == ',')) (_x)++;}
20 static inline void freeTriggerFiles(/*@only@*/ struct TriggerFileEntry *p)
22 struct TriggerFileEntry *o, *q = p;
36 static inline void freeCpioList(/*@only@*/ struct cpioFileMapping *cpioList, int cpioCount)
38 struct cpioFileMapping *p = cpioList;
41 rpmMessage(RPMMESS_DEBUG, _("archive = %s, fs = %s\n"),
42 p->archivePath, p->fsPath);
52 static inline void freeSources(/*@only@*/ struct Source *s)
54 struct Source *r, *t = s;
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 headerNVR(spec->packages->header, &pname, NULL, NULL);
81 fullName = n = alloca(strlen(pname) + 1 + strlen(name) + 1);
82 while (*pname) *n++ = *pname++;
85 fullName = n = alloca(strlen(name)+1);
90 /* Locate package with fullName */
91 for (p = spec->packages; p != NULL; p = p->next) {
92 headerNVR(p->header, &pname, NULL, NULL);
93 if (pname && (! strcmp(fullName, pname))) {
100 return ((p == NULL) ? 1 : 0);
103 Package newPackage(Spec spec)
108 p = xmalloc(sizeof(*p));
110 p->header = headerNew();
119 p->triggerScripts = NULL;
122 p->triggerFiles = NULL;
131 p->postInFile = NULL;
133 p->postUnFile = NULL;
134 p->verifyFile = NULL;
136 p->specialDoc = NULL;
138 if (spec->packages == NULL) {
141 /* Always add package to end of list */
142 for (pp = spec->packages; pp->next != NULL; pp = pp->next)
151 void freePackage(/*@only@*/ Package p)
162 headerFree(p->header);
163 freeStringBuf(p->fileList);
165 freeCpioList(p->cpioList, p->cpioCount);
167 freeStringBuf(p->specialDoc);
169 freeSources(p->icon);
171 freeTriggerFiles(p->triggerFiles);
176 void freePackages(Spec spec)
180 while ((p = spec->packages) != NULL) {
181 spec->packages = p->next;
189 static inline /*@owned@*/ struct Source *findSource(Spec spec, int num, int flag)
193 for (p = spec->sources; p != NULL; p = p->next) {
194 if ((num == p->num) && (p->flags & flag)) {
202 int parseNoSource(Spec spec, const char *field, int tag)
208 if (tag == RPMTAG_NOSOURCE) {
209 flag = RPMBUILD_ISSOURCE;
212 flag = RPMBUILD_ISPATCH;
217 for (f = fe; *f; f = fe) {
227 if (parseNum(f, &num)) {
228 rpmError(RPMERR_BADSPEC, _("line %d: Bad number: %s"),
230 return RPMERR_BADSPEC;
233 if (! (p = findSource(spec, num, flag))) {
234 rpmError(RPMERR_BADSPEC, _("line %d: Bad no%s number: %d"),
235 spec->lineNum, name, num);
236 return RPMERR_BADSPEC;
239 p->flags |= RPMBUILD_ISNO;
246 int addSource(Spec spec, Package pkg, const char *field, int tag)
252 const char *fieldp = NULL;
258 flag = RPMBUILD_ISSOURCE;
260 fieldp = spec->line + 6;
263 flag = RPMBUILD_ISPATCH;
265 fieldp = spec->line + 5;
268 flag = RPMBUILD_ISICON;
274 if (tag != RPMTAG_ICON) {
275 /* We already know that a ':' exists, and that there */
276 /* are no spaces before it. */
277 /* This also now allows for spaces and tabs between */
278 /* the number and the ':' */
281 while ((*fieldp != ':') && (*fieldp != ' ') && (*fieldp != '\t')) {
291 if (parseNum(buf, &num)) {
292 rpmError(RPMERR_BADSPEC, _("line %d: Bad %s number: %s\n"),
293 spec->lineNum, name, spec->line);
294 return RPMERR_BADSPEC;
299 /* Create the entry and link it in */
300 p = xmalloc(sizeof(struct Source));
302 p->fullSource = xstrdup(field);
303 p->source = strrchr(p->fullSource, '/');
308 p->source = p->fullSource;
311 if (tag != RPMTAG_ICON) {
312 p->next = spec->sources;
321 if (tag != RPMTAG_ICON) {
322 const char *body = rpmGetPath("%{_sourcedir}/", p->source, NULL);
325 (flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
326 addMacro(spec->macros, buf, NULL, body, RMIL_SPEC);
327 sprintf(buf, "%sURL%d",
328 (flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
329 addMacro(spec->macros, buf, NULL, p->fullSource, RMIL_SPEC);
338 static inline struct speclines * newSl(void)
340 struct speclines *sl = NULL;
342 sl = xmalloc(sizeof(struct speclines));
352 static inline void freeSl(/*@only@*/struct speclines *sl)
357 for (i = 0; i < sl->sl_nlines; i++)
358 FREE(sl->sl_lines[i]);
365 static inline struct spectags * newSt(void)
367 struct spectags *st = NULL;
369 st = xmalloc(sizeof(struct spectags));
379 static inline void freeSt(/*@only@*/struct spectags *st)
384 for (i = 0; i < st->st_ntags; i++) {
385 struct spectag *t = st->st_t + i;
397 spec = (Spec)xmalloc(sizeof *spec);
399 spec->specFile = NULL;
400 spec->sourceRpmName = NULL;
405 spec->fileStack = NULL;
406 spec->lbuf[0] = '\0';
407 spec->line = spec->lbuf;
408 spec->nextline = NULL;
409 spec->nextpeekc = '\0';
411 spec->readStack = xmalloc(sizeof(struct ReadLevelEntry));
412 spec->readStack->next = NULL;
413 spec->readStack->reading = 1;
415 spec->rootURL = NULL;
418 spec->install = NULL;
421 spec->sources = NULL;
422 spec->packages = NULL;
424 spec->numSources = 0;
426 spec->sourceHeader = NULL;
428 spec->sourceCpioCount = 0;
429 spec->sourceCpioList = NULL;
431 spec->gotBuildRootURL = 0;
432 spec->buildRootURL = NULL;
433 spec->buildSubdir = NULL;
435 spec->passPhrase = NULL;
439 spec->buildRestrictions = headerNew();
440 spec->buildArchitectures = NULL;
441 spec->buildArchitectureCount = 0;
442 spec->inBuildArchitectures = 0;
443 spec->buildArchitectureSpecs = NULL;
448 spec->macros = &rpmGlobalMacroContext;
453 void freeSpec(/*@only@*/ Spec spec)
455 struct OpenFileInfo *ofi;
456 struct ReadLevelEntry *rl;
458 freeSl(spec->sl); spec->sl = NULL;
459 freeSt(spec->st); spec->st = NULL;
461 freeStringBuf(spec->prep); spec->prep = NULL;
462 freeStringBuf(spec->build); spec->build = NULL;
463 freeStringBuf(spec->install); spec->install = NULL;
464 freeStringBuf(spec->clean); spec->clean = NULL;
466 FREE(spec->buildRootURL);
467 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';