Main Page Modules Data Structures File List Data Fields Globals Related Pages

# build/spec.c

Go to the documentation of this file.

    00001
    00006 #include "system.h"
    00007
    00008 #include "buildio.h"
    00009 #include "debug.h"
    00010
    00011 /*@-redecl@*/
    00012 extern int specedit;
    00013 /*@=redecl@*/
    00014
    00015 #define SKIPWHITE(_x)   {while(*(_x) && (xisspace(*_x) || *(_x) == ',')) (_x)++;}
    00016 #define SKIPNONWHITE(_x){while(*(_x) &&!(xisspace(*_x) || *(_x) == ',')) (_x)++;}
    00017
    00018 /*@access Header @*/    /* compared with NULL */
    00019
    00024 static inline
    00025 /*@null@*/ struct TriggerFileEntry * freeTriggerFiles(/*@only@*/ /*@null@*/ struct TriggerFileEntry * p)
    00026         /*@modifies p @*/
    00027 {
    00028     struct TriggerFileEntry *o, *q = p;
    00029
    00030     while (q != NULL) {
    00031         o = q;
    00032         q = q->next;
    00033         o->fileName = _free(o->fileName);
    00034         o->script = _free(o->script);
    00035         o->prog = _free(o->prog);
    00036         o = _free(o);
    00037     }
    00038     return NULL;
    00039 }
    00040
    00046 static inline
    00047 /*@null@*/ struct Source * freeSources(/*@only@*/ /*@null@*/ struct Source * s)
    00048         /*@modifies s @*/
    00049 {
    00050     struct Source *r, *t = s;
    00051
    00052     while (t != NULL) {
    00053         r = t;
    00054         t = t->next;
    00055         r->fullSource = _free(r->fullSource);
    00056         r = _free(r);
    00057     }
    00058     return NULL;
    00059 }
    00060
    00061 int lookupPackage(Spec spec, const char *name, int flag, /*@out@*/Package *pkg)
    00062 {
    00063     const char *pname;
    00064     const char *fullName;
    00065     Package p;
    00066
    00067     /* "main" package */
    00068     if (name == NULL) {
    00069         if (pkg)
    00070             *pkg = spec->packages;
    00071         return 0;
    00072     }
    00073
    00074     /* Construct package name */
    00075   { char *n;
    00076     if (flag == PART_SUBNAME) {
    00077         (void) headerNVR(spec->packages->header, &pname, NULL, NULL);
    00078         fullName = n = alloca(strlen(pname) + 1 + strlen(name) + 1);
    00079         while (*pname != '\0') *n++ = *pname++;
    00080         *n++ = '-';
    00081     } else {
    00082         fullName = n = alloca(strlen(name)+1);
    00083     }
    00084     /*@-mayaliasunique@*/
    00085     strcpy(n, name);
    00086     /*@=mayaliasunique@*/
    00087   }
    00088
    00089     /* Locate package with fullName */
    00090     for (p = spec->packages; p != NULL; p = p->next) {
    00091         (void) headerNVR(p->header, &pname, NULL, NULL);
    00092         if (pname && (! strcmp(fullName, pname))) {
    00093             break;
    00094         }
    00095     }
    00096
    00097     if (pkg)
    00098         /*@-dependenttrans@*/ *pkg = p; /*@=dependenttrans@*/
    00099     return ((p == NULL) ? 1 : 0);
    00100 }
    00101
    00102 Package newPackage(Spec spec)
    00103 {
    00104     Package p;
    00105     Package pp;
    00106
    00107     p = xcalloc(1, sizeof(*p));
    00108
    00109     p->header = headerNew();
    00110     p->icon = NULL;
    00111
    00112     p->autoProv = 1;
    00113     p->autoReq = 1;
    00114
    00115 #if 0
    00116     p->reqProv = NULL;
    00117     p->triggers = NULL;
    00118     p->triggerScripts = NULL;
    00119 #endif
    00120
    00121     p->triggerFiles = NULL;
    00122
    00123     p->fileFile = NULL;
    00124     p->fileList = NULL;
    00125
    00126     p->cpioList = NULL;
    00127
    00128     p->preInFile = NULL;
    00129     p->postInFile = NULL;
    00130     p->preUnFile = NULL;
    00131     p->postUnFile = NULL;
    00132     p->verifyFile = NULL;
    00133
    00134     p->specialDoc = NULL;
    00135
    00136     if (spec->packages == NULL) {
    00137         spec->packages = p;
    00138     } else {
    00139         /* Always add package to end of list */
    00140         for (pp = spec->packages; pp->next != NULL; pp = pp->next)
    00141             {};
    00142         pp->next = p;
    00143     }
    00144     p->next = NULL;
    00145
    00146     return p;
    00147 }
    00148
    00149 Package freePackage(Package pkg)
    00150 {
    00151     if (pkg == NULL) return NULL;
    00152
    00153     pkg->preInFile = _free(pkg->preInFile);
    00154     pkg->postInFile = _free(pkg->postInFile);
    00155     pkg->preUnFile = _free(pkg->preUnFile);
    00156     pkg->postUnFile = _free(pkg->postUnFile);
    00157     pkg->verifyFile = _free(pkg->verifyFile);
    00158
    00159     pkg->header = headerFree(pkg->header);
    00160     pkg->fileList = freeStringBuf(pkg->fileList);
    00161     pkg->fileFile = _free(pkg->fileFile);
    00162     if (pkg->cpioList) {
    00163         TFI_t fi = pkg->cpioList;
    00164         pkg->cpioList = NULL;
    00165         freeFi(fi);
    00166         fi = _free(fi);
    00167     }
    00168
    00169     pkg->specialDoc = freeStringBuf(pkg->specialDoc);
    00170     pkg->icon = freeSources(pkg->icon);
    00171     pkg->triggerFiles = freeTriggerFiles(pkg->triggerFiles);
    00172
    00173     pkg = _free(pkg);
    00174     return NULL;
    00175 }
    00176
    00177 Package freePackages(Package packages)
    00178 {
    00179     Package p;
    00180
    00181     while ((p = packages) != NULL) {
    00182         packages = p->next;
    00183         p->next = NULL;
    00184         p = freePackage(p);
    00185     }
    00186     return NULL;
    00187 }
    00188
    00191 static inline /*@owned@*/ struct Source *findSource(Spec spec, int num, int flag)
    00192         /*@*/
    00193 {
    00194     struct Source *p;
    00195
    00196     for (p = spec->sources; p != NULL; p = p->next)
    00197         if ((num == p->num) && (p->flags & flag)) return p;
    00198
    00199     return NULL;
    00200 }
    00201
    00202 int parseNoSource(Spec spec, const char * field, int tag)
    00203 {
    00204     const char *f, *fe;
    00205     const char *name;
    00206     int num, flag;
    00207
    00208     if (tag == RPMTAG_NOSOURCE) {
    00209         flag = RPMBUILD_ISSOURCE;
    00210         name = "source";
    00211     } else {
    00212         flag = RPMBUILD_ISPATCH;
    00213         name = "patch";
    00214     }
    00215
    00216     fe = field;
    00217     for (f = fe; *f != '\0'; f = fe) {
    00218         struct Source *p;
    00219
    00220         SKIPWHITE(f);
    00221         if (*f == '\0')
    00222             break;
    00223         fe = f;
    00224         SKIPNONWHITE(fe);
    00225         if (*fe != '\0') fe++;
    00226
    00227         if (parseNum(f, &num)) {
    00228             rpmError(RPMERR_BADSPEC, _("line %d: Bad number: %s\n"),
    00229                      spec->lineNum, f);
    00230             return RPMERR_BADSPEC;
    00231         }
    00232
    00233         if (! (p = findSource(spec, num, flag))) {
    00234             rpmError(RPMERR_BADSPEC, _("line %d: Bad no%s number: %d\n"),
    00235                      spec->lineNum, name, num);
    00236             return RPMERR_BADSPEC;
    00237         }
    00238
    00239         p->flags |= RPMBUILD_ISNO;
    00240
    00241     }
    00242
    00243     return 0;
    00244 }
    00245
    00246 int addSource(Spec spec, Package pkg, const char *field, int tag)
    00247 {
    00248     struct Source *p;
    00249     int flag = 0;
    00250     char *name = NULL;
    00251     char *nump;
    00252     const char *fieldp = NULL;
    00253     char buf[BUFSIZ];
    00254     int num = 0;
    00255
    00256     buf[0] = '\0';
    00257     /*@-branchstate@*/
    00258     switch (tag) {
    00259       case RPMTAG_SOURCE:
    00260         flag = RPMBUILD_ISSOURCE;
    00261         name = "source";
    00262         fieldp = spec->line + 6;
    00263         break;
    00264       case RPMTAG_PATCH:
    00265         flag = RPMBUILD_ISPATCH;
    00266         name = "patch";
    00267         fieldp = spec->line + 5;
    00268         break;
    00269       case RPMTAG_ICON:
    00270         flag = RPMBUILD_ISICON;
    00271         fieldp = NULL;
    00272         break;
    00273     }
    00274     /*@=branchstate@*/
    00275
    00276     /* Get the number */
    00277     if (tag != RPMTAG_ICON) {
    00278         /* We already know that a ':' exists, and that there */
    00279         /* are no spaces before it.                          */
    00280         /* This also now allows for spaces and tabs between  */
    00281         /* the number and the ':'                            */
    00282
    00283         nump = buf;
    00284         while ((*fieldp != ':') && (*fieldp != ' ') && (*fieldp != '\t')) {
    00285             *nump++ = *fieldp++;
    00286         }
    00287         *nump = '\0';
    00288
    00289         nump = buf;
    00290         SKIPSPACE(nump);
    00291         if (nump == NULL || *nump == '\0') {
    00292             num = 0;
    00293         } else {
    00294             if (parseNum(buf, &num)) {
    00295                 rpmError(RPMERR_BADSPEC, _("line %d: Bad %s number: %s\n"),
    00296                          spec->lineNum, name, spec->line);
    00297                 return RPMERR_BADSPEC;
    00298             }
    00299         }
    00300     }
    00301
    00302     /* Create the entry and link it in */
    00303     p = xmalloc(sizeof(*p));
    00304     p->num = num;
    00305     p->fullSource = xstrdup(field);
    00306     p->flags = flag;
    00307     p->source = strrchr(p->fullSource, '/');
    00308     if (p->source) {
    00309         p->source++;
    00310     } else {
    00311         p->source = p->fullSource;
    00312     }
    00313
    00314     if (tag != RPMTAG_ICON) {
    00315         p->next = spec->sources;
    00316         spec->sources = p;
    00317     } else {
    00318         p->next = pkg->icon;
    00319         pkg->icon = p;
    00320     }
    00321
    00322     spec->numSources++;
    00323
    00324     if (tag != RPMTAG_ICON) {
    00325         /*@-nullpass@*/         /* LCL: varargs needs null annotate. */
    00326         const char *body = rpmGetPath("%{_sourcedir}/", p->source, NULL);
    00327         /*@=nullpass@*/
    00328
    00329         sprintf(buf, "%s%d",
    00330                 (flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
    00331         addMacro(spec->macros, buf, NULL, body, RMIL_SPEC);
    00332         sprintf(buf, "%sURL%d",
    00333                 (flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
    00334         addMacro(spec->macros, buf, NULL, p->fullSource, RMIL_SPEC);
    00335         body = _free(body);
    00336     }
    00337
    00338     return 0;
    00339 }
    00340
    00343 static inline /*@only@*/ /*@null@*/ speclines newSl(void)
    00344         /*@*/
    00345 {
    00346     speclines sl = NULL;
    00347     /*@-branchstate@*/
    00348     if (specedit) {
    00349         sl = xmalloc(sizeof(*sl));
    00350         sl->sl_lines = NULL;
    00351         sl->sl_nalloc = 0;
    00352         sl->sl_nlines = 0;
    00353     }
    00354     /*@=branchstate@*/
    00355     return sl;
    00356 }
    00357
    00360 static inline /*@null@*/ speclines freeSl(/*@only@*/ /*@null@*/ speclines sl)
    00361         /*@modifies sl @*/
    00362 {
    00363     int i;
    00364     if (sl == NULL) return NULL;
    00365     for (i = 0; i < sl->sl_nlines; i++)
    00366         /*@-unqualifiedtrans@*/
    00367         sl->sl_lines[i] = _free(sl->sl_lines[i]);
    00368         /*@=unqualifiedtrans@*/
    00369     sl->sl_lines = _free(sl->sl_lines);
    00370     return _free(sl);
    00371 }
    00372
    00375 static inline /*@only@*/ /*@null@*/ spectags newSt(void)
    00376         /*@*/
    00377 {
    00378     spectags st = NULL;
    00379     /*@-branchstate@*/
    00380     if (specedit) {
    00381         st = xmalloc(sizeof(*st));
    00382         st->st_t = NULL;
    00383         st->st_nalloc = 0;
    00384         st->st_ntags = 0;
    00385     }
    00386     /*@=branchstate@*/
    00387     return st;
    00388 }
    00389
    00392 static inline /*@null@*/ spectags freeSt(/*@only@*/ /*@null@*/ spectags st)
    00393         /*@modifies st @*/
    00394 {
    00395     int i;
    00396     if (st == NULL) return NULL;
    00397     for (i = 0; i < st->st_ntags; i++) {
    00398         spectag t = st->st_t + i;
    00399         t->t_lang = _free(t->t_lang);
    00400         t->t_msgid = _free(t->t_msgid);
    00401     }
    00402     st->st_t = _free(st->st_t);
    00403     return _free(st);
    00404 }
    00405
    00406 Spec newSpec(void)
    00407 {
    00408     Spec spec = xcalloc(1, sizeof(*spec));
    00409
    00410     spec->specFile = NULL;
    00411     spec->sourceRpmName = NULL;
    00412
    00413     spec->sl = newSl();
    00414     spec->st = newSt();
    00415
    00416     spec->fileStack = NULL;
    00417     spec->lbuf[0] = '\0';
    00418     spec->line = spec->lbuf;
    00419     spec->nextline = NULL;
    00420     spec->nextpeekc = '\0';
    00421     spec->lineNum = 0;
    00422     spec->readStack = xcalloc(1, sizeof(*spec->readStack));
    00423     spec->readStack->next = NULL;
    00424     spec->readStack->reading = 1;
    00425
    00426     spec->rootURL = NULL;
    00427     spec->prep = NULL;
    00428     spec->build = NULL;
    00429     spec->install = NULL;
    00430     spec->clean = NULL;
    00431
    00432     spec->sources = NULL;
    00433     spec->packages = NULL;
    00434     spec->noSource = 0;
    00435     spec->numSources = 0;
    00436
    00437     spec->sourceHeader = NULL;
    00438
    00439     spec->sourceCpioList = NULL;
    00440
    00441     spec->gotBuildRootURL = 0;
    00442     spec->buildRootURL = NULL;
    00443     spec->buildSubdir = NULL;
    00444
    00445     spec->passPhrase = NULL;
    00446     spec->timeCheck = 0;
    00447     spec->cookie = NULL;
    00448
    00449     spec->buildRestrictions = headerNew();
    00450     spec->BANames = NULL;
    00451     spec->BACount = 0;
    00452     spec->recursing = 0;
    00453     spec->BASpecs = NULL;
    00454
    00455     spec->force = 0;
    00456     spec->anyarch = 0;
    00457
    00458 /*@i@*/ spec->macros = rpmGlobalMacroContext;
    00459
    00460     return spec;
    00461 }
    00462
    00463 Spec freeSpec(Spec spec)
    00464 {
    00465     struct ReadLevelEntry *rl;
    00466
    00467     if (spec == NULL) return NULL;
    00468
    00469     spec->sl = freeSl(spec->sl);
    00470     spec->st = freeSt(spec->st);
    00471
    00472     spec->prep = freeStringBuf(spec->prep);
    00473     spec->build = freeStringBuf(spec->build);
    00474     spec->install = freeStringBuf(spec->install);
    00475     spec->clean = freeStringBuf(spec->clean);
    00476
    00477     spec->buildRootURL = _free(spec->buildRootURL);
    00478     spec->buildSubdir = _free(spec->buildSubdir);
    00479     spec->rootURL = _free(spec->rootURL);
    00480     spec->specFile = _free(spec->specFile);
    00481     spec->sourceRpmName = _free(spec->sourceRpmName);
    00482
    00483 #ifdef  DEAD
    00484   { struct OpenFileInfo *ofi;
    00485     while (spec->fileStack) {
    00486         ofi = spec->fileStack;
    00487         spec->fileStack = ofi->next;
    00488         ofi->next = NULL;
    00489         ofi->fileName = _free(ofi->fileName);
    00490         ofi = _free(ofi);
    00491     }
    00492   }
    00493 #else
    00494     closeSpec(spec);
    00495 #endif
    00496
    00497     while (spec->readStack) {
    00498         rl = spec->readStack;
    00499         /*@-dependenttrans@*/
    00500         spec->readStack = rl->next;
    00501         /*@=dependenttrans@*/
    00502         rl->next = NULL;
    00503         rl = _free(rl);
    00504     }
    00505
    00506     spec->sourceHeader = headerFree(spec->sourceHeader);
    00507
    00508     if (spec->sourceCpioList) {
    00509         TFI_t fi = spec->sourceCpioList;
    00510         spec->sourceCpioList = NULL;
    00511         freeFi(fi);
    00512         fi = _free(fi);
    00513     }
    00514
    00515     spec->buildRestrictions = headerFree(spec->buildRestrictions);
    00516
    00517     if (!spec->recursing) {
    00518         if (spec->BASpecs != NULL)
    00519         while (spec->BACount--) {
    00520             /*@-unqualifiedtrans@*/
    00521             spec->BASpecs[spec->BACount] =
    00522                         freeSpec(spec->BASpecs[spec->BACount]);
    00523             /*@=unqualifiedtrans@*/
    00524         }
    00525         /*@-compdef@*/
    00526         spec->BASpecs = _free(spec->BASpecs);
    00527         /*@=compdef@*/
    00528     }
    00529     spec->BANames = _free(spec->BANames);
    00530
    00531     spec->passPhrase = _free(spec->passPhrase);
    00532     spec->cookie = _free(spec->cookie);
    00533
    00534     spec->sources = freeSources(spec->sources);
    00535     spec->packages = freePackages(spec->packages);
    00536
    00537     spec = _free(spec);
    00538
    00539     return spec;
    00540 }
    00541
    00542 /*@only@*/ struct OpenFileInfo * newOpenFileInfo(void)
    00543 {
    00544     struct OpenFileInfo *ofi;
    00545
    00546     ofi = xmalloc(sizeof(*ofi));
    00547     ofi->fd = NULL;
    00548     ofi->fileName = NULL;
    00549     ofi->lineNum = 0;
    00550     ofi->readBuf[0] = '\0';
    00551     ofi->readPtr = NULL;
    00552     ofi->next = NULL;
    00553
    00554     return ofi;
    00555 }