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

Generated at Thu Apr 19 15:29:42 2001 for rpm by doxygen1.2.6-20010408 written by Dimitri van Heesch, © 1997-2001