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