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

Generated on Fri Apr 4 14:39:38 2003 for rpm by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002