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

Generated on Thu Apr 29 08:02:18 2004 for rpm by doxygen 1.3.6