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 }

Generated on Wed Sep 4 12:49:50 2002 for rpm by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002