Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

build/parseReqs.c

Go to the documentation of this file.
00001 
00006 #include "system.h"
00007 
00008 #include "rpmbuild.h"
00009 #include "debug.h"
00010 
00013 static struct ReqComp {
00014 /*@observer@*/ /*@null@*/ const char * token;
00015     rpmsenseFlags sense;
00016 } ReqComparisons[] = {
00017     { "<=", RPMSENSE_LESS | RPMSENSE_EQUAL},
00018     { "=<", RPMSENSE_LESS | RPMSENSE_EQUAL},
00019     { "<", RPMSENSE_LESS},
00020 
00021     { "==", RPMSENSE_EQUAL},
00022     { "=", RPMSENSE_EQUAL},
00023     
00024     { ">=", RPMSENSE_GREATER | RPMSENSE_EQUAL},
00025     { "=>", RPMSENSE_GREATER | RPMSENSE_EQUAL},
00026     { ">", RPMSENSE_GREATER},
00027 
00028     { NULL, 0 },
00029 };
00030 
00031 #define SKIPWHITE(_x)   {while(*(_x) && (xisspace(*_x) || *(_x) == ',')) (_x)++;}
00032 #define SKIPNONWHITE(_x){while(*(_x) &&!(xisspace(*_x) || *(_x) == ',')) (_x)++;}
00033 
00034 int parseRCPOT(Spec spec, Package pkg, const char *field, int tag,
00035                int index, rpmsenseFlags tagflags)
00036 {
00037     const char *r, *re, *v, *ve;
00038     char * req, * version;
00039     Header h;
00040     rpmsenseFlags flags;
00041 
00042     switch (tag) {
00043     case RPMTAG_PROVIDEFLAGS:
00044         tagflags |= RPMSENSE_PROVIDES;
00045         h = pkg->header;
00046         break;
00047     case RPMTAG_OBSOLETEFLAGS:
00048         tagflags |= RPMSENSE_OBSOLETES;
00049         h = pkg->header;
00050         break;
00051     case RPMTAG_CONFLICTFLAGS:
00052         tagflags |= RPMSENSE_CONFLICTS;
00053         h = pkg->header;
00054         break;
00055     case RPMTAG_BUILDCONFLICTS:
00056         tagflags |= RPMSENSE_CONFLICTS;
00057         h = spec->buildRestrictions;
00058         break;
00059     case RPMTAG_PREREQ:
00060         tagflags |= RPMSENSE_PREREQ;
00061         h = pkg->header;
00062         break;
00063     case RPMTAG_BUILDPREREQ:
00064         tagflags |= RPMSENSE_PREREQ;
00065         h = spec->buildRestrictions;
00066         break;
00067     case RPMTAG_TRIGGERIN:
00068         tagflags |= RPMSENSE_TRIGGERIN;
00069         h = pkg->header;
00070         break;
00071     case RPMTAG_TRIGGERPOSTUN:
00072         tagflags |= RPMSENSE_TRIGGERPOSTUN;
00073         h = pkg->header;
00074         break;
00075     case RPMTAG_TRIGGERUN:
00076         tagflags |= RPMSENSE_TRIGGERUN;
00077         h = pkg->header;
00078         break;
00079     case RPMTAG_BUILDREQUIRES:
00080         tagflags |= RPMSENSE_ANY;
00081         h = spec->buildRestrictions;
00082         break;
00083     default:
00084     case RPMTAG_REQUIREFLAGS:
00085         tagflags |= RPMSENSE_ANY;
00086         h = pkg->header;
00087         break;
00088     }
00089 
00090     for (r = field; *r != '\0'; r = re) {
00091         SKIPWHITE(r);
00092         if (*r == '\0')
00093             break;
00094 
00095         flags = (tagflags & ~RPMSENSE_SENSEMASK);
00096 
00097         /* Tokens must begin with alphanumeric, _, or / */
00098         if (!(xisalnum(r[0]) || r[0] == '_' || r[0] == '/')) {
00099             rpmError(RPMERR_BADSPEC,
00100                      _("line %d: Dependency tokens must begin with alpha-numeric, '_' or '/': %s\n"),
00101                      spec->lineNum, spec->line);
00102             return RPMERR_BADSPEC;
00103         }
00104 
00105         /* Don't permit file names as args for certain tags */
00106         switch (tag) {
00107         case RPMTAG_OBSOLETEFLAGS:
00108         case RPMTAG_CONFLICTFLAGS:
00109         case RPMTAG_BUILDCONFLICTS:
00110             if (r[0] == '/') {
00111                 rpmError(RPMERR_BADSPEC,_("line %d: File name not permitted: %s\n"),
00112                          spec->lineNum, spec->line);
00113                 return RPMERR_BADSPEC;
00114             }
00115             break;
00116         default:
00117             break;
00118         }
00119 
00120         re = r;
00121         SKIPNONWHITE(re);
00122         req = xmalloc((re-r) + 1);
00123         strncpy(req, r, (re-r));
00124         req[re-r] = '\0';
00125 
00126         /* Parse version */
00127         v = re;
00128         SKIPWHITE(v);
00129         ve = v;
00130         SKIPNONWHITE(ve);
00131 
00132         re = v; /* ==> next token (if no version found) starts here */
00133 
00134         /* Check for possible logical operator */
00135         if (ve > v) {
00136           struct ReqComp *rc;
00137           for (rc = ReqComparisons; rc->token != NULL; rc++) {
00138             if ((ve-v) != strlen(rc->token) || strncmp(v, rc->token, (ve-v)))
00139                 continue;
00140 
00141             if (r[0] == '/') {
00142                 rpmError(RPMERR_BADSPEC,
00143                          _("line %d: Versioned file name not permitted: %s\n"),
00144                          spec->lineNum, spec->line);
00145                 return RPMERR_BADSPEC;
00146             }
00147 
00148             switch(tag) {
00149             case RPMTAG_BUILDPREREQ:
00150             case RPMTAG_PREREQ:
00151             case RPMTAG_PROVIDEFLAGS:
00152             case RPMTAG_OBSOLETEFLAGS:
00153                 /* Add prereq on rpmlib that has versioned dependencies. */
00154                 if (!rpmExpandNumeric("%{_noVersionedDependencies}"))
00155                     (void) rpmlibNeedsFeature(h, "VersionedDependencies", "3.0.3-1");
00156                 break;
00157             default:
00158                 break;
00159             }
00160             flags |= rc->sense;
00161 
00162             /* now parse version */
00163             v = ve;
00164             SKIPWHITE(v);
00165             ve = v;
00166             SKIPNONWHITE(ve);
00167             /*@innerbreak@*/ break;
00168           }
00169         }
00170 
00171         if (flags & RPMSENSE_SENSEMASK) {
00172             if (*v == '\0' || ve == v) {
00173                 rpmError(RPMERR_BADSPEC, _("line %d: Version required: %s\n"),
00174                         spec->lineNum, spec->line);
00175                 return RPMERR_BADSPEC;
00176             }
00177             version = xmalloc((ve-v) + 1);
00178             strncpy(version, v, (ve-v));
00179             version[ve-v] = '\0';
00180             re = ve;    /* ==> next token after version string starts here */
00181         } else
00182             version = NULL;
00183 
00184         (void) addReqProv(spec, h, flags, req, version, index);
00185 
00186         req = _free(req);
00187         version = _free(version);
00188 
00189     }
00190 
00191     return 0;
00192 }

Generated at Wed Mar 27 03:56:48 2002 for rpm by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001