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 = xstrdup("yes");
00113     p->autoReq = xstrdup("yes");
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->autoProv = _free(pkg->autoProv);
00154     pkg->autoReq = _free(pkg->autoReq);
00155 
00156     pkg->preInFile = _free(pkg->preInFile);
00157     pkg->postInFile = _free(pkg->postInFile);
00158     pkg->preUnFile = _free(pkg->preUnFile);
00159     pkg->postUnFile = _free(pkg->postUnFile);
00160     pkg->verifyFile = _free(pkg->verifyFile);
00161 
00162     pkg->header = headerFree(pkg->header);
00163     pkg->fileList = freeStringBuf(pkg->fileList);
00164     pkg->fileFile = _free(pkg->fileFile);
00165     if (pkg->cpioList) {
00166         TFI_t fi = pkg->cpioList;
00167         pkg->cpioList = NULL;
00168         freeFi(fi);
00169         fi = _free(fi);
00170     }
00171 
00172     pkg->specialDoc = freeStringBuf(pkg->specialDoc);
00173     pkg->icon = freeSources(pkg->icon);
00174     pkg->triggerFiles = freeTriggerFiles(pkg->triggerFiles);
00175 
00176     pkg = _free(pkg);
00177     return NULL;
00178 }
00179 
00180 Package freePackages(Package packages)
00181 {
00182     Package p;
00183 
00184     while ((p = packages) != NULL) {
00185         packages = p->next;
00186         p->next = NULL;
00187         p = freePackage(p);
00188     }
00189     return NULL;
00190 }
00191 
00194 static inline /*@owned@*/ struct Source *findSource(Spec spec, int num, int flag)
00195         /*@*/
00196 {
00197     struct Source *p;
00198 
00199     for (p = spec->sources; p != NULL; p = p->next)
00200         if ((num == p->num) && (p->flags & flag)) return p;
00201 
00202     return NULL;
00203 }
00204 
00205 int parseNoSource(Spec spec, const char * field, int tag)
00206 {
00207     const char *f, *fe;
00208     const char *name;
00209     int num, flag;
00210 
00211     if (tag == RPMTAG_NOSOURCE) {
00212         flag = RPMBUILD_ISSOURCE;
00213         name = "source";
00214     } else {
00215         flag = RPMBUILD_ISPATCH;
00216         name = "patch";
00217     }
00218     
00219     fe = field;
00220     for (f = fe; *f != '\0'; f = fe) {
00221         struct Source *p;
00222 
00223         SKIPWHITE(f);
00224         if (*f == '\0')
00225             break;
00226         fe = f;
00227         SKIPNONWHITE(fe);
00228         {
00229         char buf[fe - f + 1];
00230         memcpy( buf, f, fe - f );
00231         buf[fe - f] = '\0';
00232         if (*fe != '\0') fe++;
00233 
00234         if (parseNum(buf, &num)) {
00235             rpmError(RPMERR_BADSPEC, _("line %d: Bad number: %s\n"),
00236                      spec->lineNum, buf);
00237             return RPMERR_BADSPEC;
00238         }
00239         }
00240 
00241         if (! (p = findSource(spec, num, flag))) {
00242             rpmError(RPMERR_BADSPEC, _("line %d: Bad no%s number: %d\n"),
00243                      spec->lineNum, name, num);
00244             return RPMERR_BADSPEC;
00245         }
00246 
00247         p->flags |= RPMBUILD_ISNO;
00248 
00249     }
00250 
00251     return 0;
00252 }
00253 
00254 int addSource(Spec spec, Package pkg, const char *field, int tag)
00255 {
00256     struct Source *p;
00257     int flag = 0;
00258     char *name = NULL;
00259     char *nump;
00260     const char *fieldp = NULL;
00261     char buf[BUFSIZ];
00262     int num = 0;
00263 
00264     buf[0] = '\0';
00265     /*@-branchstate@*/
00266     switch (tag) {
00267       case RPMTAG_SOURCE:
00268         flag = RPMBUILD_ISSOURCE;
00269         name = _("source");
00270         fieldp = spec->line + 6;
00271         break;
00272       case RPMTAG_PATCH:
00273         flag = RPMBUILD_ISPATCH;
00274         name = _("patch");
00275         fieldp = spec->line + 5;
00276         break;
00277       case RPMTAG_ICON:
00278         flag = RPMBUILD_ISICON;
00279         name = _("icon");
00280         fieldp = NULL;
00281         break;
00282     }
00283     /*@=branchstate@*/
00284 
00285     /* Get the number */
00286     if (tag != RPMTAG_ICON) {
00287         /* We already know that a ':' exists, and that there */
00288         /* are no spaces before it.                          */
00289         /* This also now allows for spaces and tabs between  */
00290         /* the number and the ':'                            */
00291 
00292         nump = buf;
00293         while ((*fieldp != ':') && (*fieldp != ' ') && (*fieldp != '\t')) {
00294             *nump++ = *fieldp++;
00295         }
00296         *nump = '\0';
00297 
00298         nump = buf;
00299         SKIPSPACE(nump);
00300         if (nump == NULL || *nump == '\0') {
00301             num = 0;
00302         } else {
00303             if (parseNum(buf, &num)) {
00304                 rpmError(RPMERR_BADSPEC, _("line %d: Bad %s number: %s\n"),
00305                          spec->lineNum, name, spec->line);
00306                 return RPMERR_BADSPEC;
00307             }
00308         }
00309     }
00310 
00311     /* Create the entry and link it in */
00312     p = xmalloc(sizeof(*p));
00313     p->num = num;
00314     p->fullSource = xstrdup(field);
00315     p->flags = flag;
00316     p->source = strrchr(p->fullSource, '/');
00317     if (p->source) {
00318         p->source++;
00319     } else {
00320         p->source = p->fullSource;
00321     }
00322 
00323     if ( !*p->source )
00324     {
00325         rpmError( RPMERR_BADSPEC, _("line %d: Bad %s name: %s\n"),
00326             spec->lineNum, name, p->fullSource );
00327         return RPMERR_BADSPEC;
00328     }
00329 
00330     if (tag != RPMTAG_ICON) {
00331         p->next = spec->sources;
00332         spec->sources = p;
00333     } else {
00334         p->next = pkg->icon;
00335         pkg->icon = p;
00336     }
00337 
00338     spec->numSources++;
00339 
00340     if (tag != RPMTAG_ICON) {
00341         /*@-nullpass@*/         /* LCL: varargs needs null annotate. */
00342         const char *body = rpmGetPath("%{_sourcedir}/", p->source, NULL);
00343         /*@=nullpass@*/
00344 
00345         sprintf(buf, "%s%d",
00346                 (flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
00347         addMacro(spec->macros, buf, NULL, body, RMIL_SPEC);
00348         sprintf(buf, "%sURL%d",
00349                 (flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
00350         addMacro(spec->macros, buf, NULL, p->fullSource, RMIL_SPEC);
00351         body = _free(body);
00352     }
00353     
00354     return 0;
00355 }
00356 
00359 static inline /*@only@*/ /*@null@*/ speclines newSl(void)
00360         /*@*/
00361 {
00362     speclines sl = NULL;
00363     /*@-branchstate@*/
00364     if (specedit) {
00365         sl = xmalloc(sizeof(*sl));
00366         sl->sl_lines = NULL;
00367         sl->sl_nalloc = 0;
00368         sl->sl_nlines = 0;
00369     }
00370     /*@=branchstate@*/
00371     return sl;
00372 }
00373 
00376 static inline /*@null@*/ speclines freeSl(/*@only@*/ /*@null@*/ speclines sl)
00377         /*@modifies sl @*/
00378 {
00379     int i;
00380     if (sl == NULL) return NULL;
00381     for (i = 0; i < sl->sl_nlines; i++)
00382         /*@-unqualifiedtrans@*/
00383         sl->sl_lines[i] = _free(sl->sl_lines[i]);
00384         /*@=unqualifiedtrans@*/
00385     sl->sl_lines = _free(sl->sl_lines);
00386     return _free(sl);
00387 }
00388 
00391 static inline /*@only@*/ /*@null@*/ spectags newSt(void)
00392         /*@*/
00393 {
00394     spectags st = NULL;
00395     /*@-branchstate@*/
00396     if (specedit) {
00397         st = xmalloc(sizeof(*st));
00398         st->st_t = NULL;
00399         st->st_nalloc = 0;
00400         st->st_ntags = 0;
00401     }
00402     /*@=branchstate@*/
00403     return st;
00404 }
00405 
00408 static inline /*@null@*/ spectags freeSt(/*@only@*/ /*@null@*/ spectags st)
00409         /*@modifies st @*/
00410 {
00411     int i;
00412     if (st == NULL) return NULL;
00413     for (i = 0; i < st->st_ntags; i++) {
00414         spectag t = st->st_t + i;
00415         t->t_lang = _free(t->t_lang);
00416         t->t_msgid = _free(t->t_msgid);
00417     }
00418     st->st_t = _free(st->st_t);
00419     return _free(st);
00420 }
00421 
00422 Spec newSpec(void)
00423 {
00424     Spec spec = xcalloc(1, sizeof(*spec));
00425     
00426     spec->specFile = NULL;
00427     spec->sourceRpmName = NULL;
00428 
00429     spec->sl = newSl();
00430     spec->st = newSt();
00431 
00432     spec->fileStack = NULL;
00433     spec->lbuf[0] = '\0';
00434     spec->line = spec->lbuf;
00435     spec->nextline = NULL;
00436     spec->nextpeekc = '\0';
00437     spec->lineNum = 0;
00438     spec->readStack = xcalloc(1, sizeof(*spec->readStack));
00439     spec->readStack->next = NULL;
00440     spec->readStack->reading = 1;
00441 
00442     spec->rootURL = NULL;
00443     spec->prep = NULL;
00444     spec->build = NULL;
00445     spec->install = NULL;
00446     spec->clean = NULL;
00447 
00448     spec->sources = NULL;
00449     spec->packages = NULL;
00450     spec->noSource = 0;
00451     spec->numSources = 0;
00452 
00453     spec->sourceHeader = NULL;
00454 
00455     spec->sourceCpioList = NULL;
00456     
00457     spec->gotBuildRootURL = 0;
00458     spec->buildRootURL = NULL;
00459     spec->buildSubdir = NULL;
00460 
00461     spec->passPhrase = NULL;
00462     spec->timeCheck = 0;
00463     spec->cookie = NULL;
00464 
00465     spec->buildRestrictions = headerNew();
00466     spec->BANames = NULL;
00467     spec->BACount = 0;
00468     spec->recursing = 0;
00469     spec->BASpecs = NULL;
00470 
00471     spec->force = 0;
00472     spec->anyarch = 0;
00473 
00474 /*@i@*/ spec->macros = rpmGlobalMacroContext;
00475     
00476     return spec;
00477 }
00478 
00479 Spec freeSpec(Spec spec)
00480 {
00481     struct ReadLevelEntry *rl;
00482 
00483     if (spec == NULL) return NULL;
00484 
00485     spec->sl = freeSl(spec->sl);
00486     spec->st = freeSt(spec->st);
00487 
00488     spec->prep = freeStringBuf(spec->prep);
00489     spec->build = freeStringBuf(spec->build);
00490     spec->install = freeStringBuf(spec->install);
00491     spec->clean = freeStringBuf(spec->clean);
00492 
00493     spec->buildRootURL = _free(spec->buildRootURL);
00494     spec->buildSubdir = _free(spec->buildSubdir);
00495     spec->rootURL = _free(spec->rootURL);
00496     spec->specFile = _free(spec->specFile);
00497     spec->sourceRpmName = _free(spec->sourceRpmName);
00498 
00499 #ifdef  DEAD
00500   { struct OpenFileInfo *ofi;
00501     while (spec->fileStack) {
00502         ofi = spec->fileStack;
00503         spec->fileStack = ofi->next;
00504         ofi->next = NULL;
00505         ofi->fileName = _free(ofi->fileName);
00506         ofi = _free(ofi);
00507     }
00508   }
00509 #else
00510     closeSpec(spec);
00511 #endif
00512 
00513     while (spec->readStack) {
00514         rl = spec->readStack;
00515         /*@-dependenttrans@*/
00516         spec->readStack = rl->next;
00517         /*@=dependenttrans@*/
00518         rl->next = NULL;
00519         rl = _free(rl);
00520     }
00521     
00522     spec->sourceHeader = headerFree(spec->sourceHeader);
00523 
00524     if (spec->sourceCpioList) {
00525         TFI_t fi = spec->sourceCpioList;
00526         spec->sourceCpioList = NULL;
00527         freeFi(fi);
00528         fi = _free(fi);
00529     }
00530     
00531     spec->buildRestrictions = headerFree(spec->buildRestrictions);
00532 
00533     if (!spec->recursing) {
00534         if (spec->BASpecs != NULL)
00535         while (spec->BACount--) {
00536             /*@-unqualifiedtrans@*/
00537             spec->BASpecs[spec->BACount] =
00538                         freeSpec(spec->BASpecs[spec->BACount]);
00539             /*@=unqualifiedtrans@*/
00540         }
00541         /*@-compdef@*/
00542         spec->BASpecs = _free(spec->BASpecs);
00543         /*@=compdef@*/
00544     }
00545     spec->BANames = _free(spec->BANames);
00546 
00547     spec->passPhrase = _free(spec->passPhrase);
00548     spec->cookie = _free(spec->cookie);
00549 
00550     spec->sources = freeSources(spec->sources);
00551     spec->packages = freePackages(spec->packages);
00552     
00553     spec = _free(spec);
00554 
00555     return spec;
00556 }
00557 
00558 /*@only@*/ struct OpenFileInfo * newOpenFileInfo(void)
00559 {
00560     struct OpenFileInfo *ofi;
00561 
00562     ofi = xmalloc(sizeof(*ofi));
00563     ofi->fd = NULL;
00564     ofi->fileName = NULL;
00565     ofi->lineNum = 0;
00566     ofi->readBuf[0] = '\0';
00567     ofi->readPtr = NULL;
00568     ofi->next = NULL;
00569 
00570     return ofi;
00571 }

Generated on Sun Feb 2 23:31:59 2003 for rpm by doxygen1.2.18