Main Page   Modules   Compound List   File List   Compound Members   File Members   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 
00020 static inline void freeTriggerFiles(/*@only@*/ struct TriggerFileEntry *p)
00021 {
00022     struct TriggerFileEntry *o, *q = p;
00023     
00024     while (q != NULL) {
00025         o = q;
00026         q = q->next;
00027         FREE(o->fileName);
00028         FREE(o->script);
00029         FREE(o->prog);
00030         free(o);
00031     }
00032 }
00033 
00036 static inline void freeCpioList(/*@only@*/ struct cpioFileMapping *cpioList, int cpioCount)
00037 {
00038     struct cpioFileMapping *p = cpioList;
00039 
00040     while (cpioCount--) {
00041         rpmMessage(RPMMESS_DEBUG, _("archive = %s, fs = %s\n"),
00042                    p->archivePath, p->fsPath);
00043         FREE(p->archivePath);
00044         FREE(p->fsPath);
00045         p++;
00046     }
00047     FREE(cpioList);
00048 }
00049 
00052 static inline void freeSources(/*@only@*/ struct Source *s)
00053 {
00054     struct Source *r, *t = s;
00055 
00056     while (t != NULL) {
00057         r = t;
00058         t = t->next;
00059         FREE(r->fullSource);
00060         free(r);
00061     }
00062 }
00063 
00064 int lookupPackage(Spec spec, const char *name, int flag, /*@out@*/Package *pkg)
00065 {
00066     const char *pname;
00067     const char *fullName;
00068     Package p;
00069     
00070     /* "main" package */
00071     if (name == NULL) {
00072         if (pkg)
00073             *pkg = spec->packages;
00074         return 0;
00075     }
00076 
00077     /* Construct package name */
00078   { char *n;
00079     if (flag == PART_SUBNAME) {
00080         headerNVR(spec->packages->header, &pname, NULL, NULL);
00081         fullName = n = alloca(strlen(pname) + 1 + strlen(name) + 1);
00082         while (*pname) *n++ = *pname++;
00083         *n++ = '-';
00084     } else {
00085         fullName = n = alloca(strlen(name)+1);
00086     }
00087     strcpy(n, name);
00088   }
00089 
00090     /* Locate package with fullName */
00091     for (p = spec->packages; p != NULL; p = p->next) {
00092         headerNVR(p->header, &pname, NULL, NULL);
00093         if (pname && (! strcmp(fullName, pname))) {
00094             break;
00095         }
00096     }
00097 
00098     if (pkg)
00099         *pkg = p;
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     p->cpioCount = 0;
00129 
00130     p->preInFile = NULL;
00131     p->postInFile = NULL;
00132     p->preUnFile = NULL;
00133     p->postUnFile = NULL;
00134     p->verifyFile = NULL;
00135 
00136     p->specialDoc = NULL;
00137 
00138     if (spec->packages == NULL) {
00139         spec->packages = p;
00140     } else {
00141         /* Always add package to end of list */
00142         for (pp = spec->packages; pp->next != NULL; pp = pp->next)
00143             ;
00144         pp->next = p;
00145     }
00146     p->next = NULL;
00147 
00148     return p;
00149 }
00150 
00151 void freePackage(/*@only@*/ Package p)
00152 {
00153     if (p == NULL)
00154         return;
00155     
00156     FREE(p->preInFile);
00157     FREE(p->postInFile);
00158     FREE(p->preUnFile);
00159     FREE(p->postUnFile);
00160     FREE(p->verifyFile);
00161 
00162     headerFree(p->header);
00163     freeStringBuf(p->fileList);
00164     FREE(p->fileFile);
00165     freeCpioList(p->cpioList, p->cpioCount);
00166 
00167     freeStringBuf(p->specialDoc);
00168 
00169     freeSources(p->icon);
00170 
00171     freeTriggerFiles(p->triggerFiles);
00172 
00173     free(p);
00174 }
00175 
00176 void freePackages(Spec spec)
00177 {
00178     Package p;
00179 
00180     while ((p = spec->packages) != NULL) {
00181         spec->packages = p->next;
00182         p->next = NULL;
00183         freePackage(p);
00184     }
00185 }
00186 
00189 static inline /*@owned@*/ struct Source *findSource(Spec spec, int num, int flag)
00190 {
00191     struct Source *p;
00192 
00193     for (p = spec->sources; p != NULL; p = p->next) {
00194         if ((num == p->num) && (p->flags & flag)) {
00195             return p;
00196         }
00197     }
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; 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) 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     switch (tag) {
00257       case RPMTAG_SOURCE:
00258         flag = RPMBUILD_ISSOURCE;
00259         name = "source";
00260         fieldp = spec->line + 6;
00261         break;
00262       case RPMTAG_PATCH:
00263         flag = RPMBUILD_ISPATCH;
00264         name = "patch";
00265         fieldp = spec->line + 5;
00266         break;
00267       case RPMTAG_ICON:
00268         flag = RPMBUILD_ISICON;
00269         fieldp = NULL;
00270         break;
00271     }
00272 
00273     /* Get the number */
00274     if (tag != RPMTAG_ICON) {
00275         /* We already know that a ':' exists, and that there */
00276         /* are no spaces before it.                          */
00277         /* This also now allows for spaces and tabs between  */
00278         /* the number and the ':'                            */
00279 
00280         nump = buf;
00281         while ((*fieldp != ':') && (*fieldp != ' ') && (*fieldp != '\t')) {
00282             *nump++ = *fieldp++;
00283         }
00284         *nump = '\0';
00285 
00286         nump = buf;
00287         SKIPSPACE(nump);
00288         if (! *nump) {
00289             num = 0;
00290         } else {
00291             if (parseNum(buf, &num)) {
00292                 rpmError(RPMERR_BADSPEC, _("line %d: Bad %s number: %s\n"),
00293                          spec->lineNum, name, spec->line);
00294                 return RPMERR_BADSPEC;
00295             }
00296         }
00297     }
00298 
00299     /* Create the entry and link it in */
00300     p = xmalloc(sizeof(struct Source));
00301     p->num = num;
00302     p->fullSource = xstrdup(field);
00303     p->source = strrchr(p->fullSource, '/');
00304     p->flags = flag;
00305     if (p->source) {
00306         p->source++;
00307     } else {
00308         p->source = p->fullSource;
00309     }
00310 
00311     if (tag != RPMTAG_ICON) {
00312         p->next = spec->sources;
00313         spec->sources = p;
00314     } else {
00315         p->next = pkg->icon;
00316         pkg->icon = p;
00317     }
00318 
00319     spec->numSources++;
00320 
00321     if (tag != RPMTAG_ICON) {
00322         const char *body = rpmGetPath("%{_sourcedir}/", p->source, NULL);
00323 
00324         sprintf(buf, "%s%d",
00325                 (flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
00326         addMacro(spec->macros, buf, NULL, body, RMIL_SPEC);
00327         sprintf(buf, "%sURL%d",
00328                 (flag & RPMBUILD_ISPATCH) ? "PATCH" : "SOURCE", num);
00329         addMacro(spec->macros, buf, NULL, p->fullSource, RMIL_SPEC);
00330         free((void *)body);
00331     }
00332     
00333     return 0;
00334 }
00335 
00338 static inline struct speclines * newSl(void)
00339 {
00340     struct speclines *sl = NULL;
00341     if (specedit) {
00342         sl = xmalloc(sizeof(struct speclines));
00343         sl->sl_lines = NULL;
00344         sl->sl_nalloc = 0;
00345         sl->sl_nlines = 0;
00346     }
00347     return sl;
00348 }
00349 
00352 static inline void freeSl(/*@only@*/struct speclines *sl)
00353 {
00354     int i;
00355     if (sl == NULL)
00356         return;
00357     for (i = 0; i < sl->sl_nlines; i++)
00358         FREE(sl->sl_lines[i]);
00359     FREE(sl->sl_lines);
00360     free(sl);
00361 }
00362 
00365 static inline struct spectags * newSt(void)
00366 {
00367     struct spectags *st = NULL;
00368     if (specedit) {
00369         st = xmalloc(sizeof(struct spectags));
00370         st->st_t = NULL;
00371         st->st_nalloc = 0;
00372         st->st_ntags = 0;
00373     }
00374     return st;
00375 }
00376 
00379 static inline void freeSt(/*@only@*/struct spectags *st)
00380 {
00381     int i;
00382     if (st == NULL)
00383         return;
00384     for (i = 0; i < st->st_ntags; i++) {
00385         struct spectag *t = st->st_t + i;
00386         FREE(t->t_lang);
00387         FREE(t->t_msgid);
00388     }
00389     FREE(st->st_t);
00390     free(st);
00391 }
00392 
00393 Spec newSpec(void)
00394 {
00395     Spec spec;
00396 
00397     spec = (Spec)xmalloc(sizeof *spec);
00398     
00399     spec->specFile = NULL;
00400     spec->sourceRpmName = NULL;
00401 
00402     spec->sl = newSl();
00403     spec->st = newSt();
00404 
00405     spec->fileStack = NULL;
00406     spec->lbuf[0] = '\0';
00407     spec->line = spec->lbuf;
00408     spec->nextline = NULL;
00409     spec->nextpeekc = '\0';
00410     spec->lineNum = 0;
00411     spec->readStack = xmalloc(sizeof(struct ReadLevelEntry));
00412     spec->readStack->next = NULL;
00413     spec->readStack->reading = 1;
00414 
00415     spec->rootURL = NULL;
00416     spec->prep = NULL;
00417     spec->build = NULL;
00418     spec->install = NULL;
00419     spec->clean = NULL;
00420 
00421     spec->sources = NULL;
00422     spec->packages = NULL;
00423     spec->noSource = 0;
00424     spec->numSources = 0;
00425 
00426     spec->sourceHeader = NULL;
00427 
00428     spec->sourceCpioCount = 0;
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->buildArchitectures = NULL;
00441     spec->buildArchitectureCount = 0;
00442     spec->inBuildArchitectures = 0;
00443     spec->buildArchitectureSpecs = NULL;
00444 
00445     spec->force = 0;
00446     spec->anyarch = 0;
00447 
00448     spec->macros = &rpmGlobalMacroContext;
00449     
00450     return spec;
00451 }
00452 
00453 void freeSpec(/*@only@*/ Spec spec)
00454 {
00455     struct OpenFileInfo *ofi;
00456     struct ReadLevelEntry *rl;
00457 
00458     freeSl(spec->sl);   spec->sl = NULL;
00459     freeSt(spec->st);   spec->st = NULL;
00460 
00461     freeStringBuf(spec->prep);  spec->prep = NULL;
00462     freeStringBuf(spec->build); spec->build = NULL;
00463     freeStringBuf(spec->install); spec->install = NULL;
00464     freeStringBuf(spec->clean); spec->clean = NULL;
00465 
00466     FREE(spec->buildRootURL);
00467     FREE(spec->buildSubdir);
00468     FREE(spec->rootURL);
00469     FREE(spec->specFile);
00470     FREE(spec->sourceRpmName);
00471 
00472     while (spec->fileStack) {
00473         ofi = spec->fileStack;
00474         spec->fileStack = spec->fileStack->next;
00475         ofi->next = NULL;
00476         FREE(ofi->fileName);
00477         free(ofi);
00478     }
00479 
00480     while (spec->readStack) {
00481         rl = spec->readStack;
00482         spec->readStack = spec->readStack->next;
00483         rl->next = NULL;
00484         free(rl);
00485     }
00486     
00487     if (spec->sourceHeader != NULL) {
00488         headerFree(spec->sourceHeader);
00489         spec->sourceHeader = NULL;
00490     }
00491 
00492     freeCpioList(spec->sourceCpioList, spec->sourceCpioCount);
00493     spec->sourceCpioList = NULL;
00494     
00495     headerFree(spec->buildRestrictions);
00496     spec->buildRestrictions = NULL;
00497 
00498     if (!spec->inBuildArchitectures) {
00499         while (spec->buildArchitectureCount--) {
00500             freeSpec(
00501                 spec->buildArchitectureSpecs[spec->buildArchitectureCount]);
00502         }
00503         FREE(spec->buildArchitectureSpecs);
00504     }
00505     FREE(spec->buildArchitectures);
00506 
00507     FREE(spec->passPhrase);
00508     FREE(spec->cookie);
00509 
00510     freeSources(spec->sources); spec->sources = NULL;
00511     freePackages(spec);
00512     closeSpec(spec);
00513     
00514     free(spec);
00515 }
00516 
00517 /*@only@*/ struct OpenFileInfo * newOpenFileInfo(void)
00518 {
00519     struct OpenFileInfo *ofi;
00520 
00521     ofi = xmalloc(sizeof(struct OpenFileInfo));
00522     ofi->fd = NULL;
00523     ofi->fileName = NULL;
00524     ofi->lineNum = 0;
00525     ofi->readBuf[0] = '\0';
00526     ofi->readPtr = NULL;
00527     ofi->next = NULL;
00528 
00529     return ofi;
00530 }

Generated at Sun Apr 8 18:42:59 2001 for rpm by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000