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

Generated at Thu Sep 6 11:25:40 2001 for rpm by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001