# 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 }