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 /*@-boundsread@*/
00092     for (r = field; *r != '\0'; r = re) {
00093         SKIPWHITE(r);
00094         if (*r == '\0')
00095             break;
00096 
00097         flags = (tagflags & ~RPMSENSE_SENSEMASK);
00098 
00099         /* Tokens must begin with alphanumeric, _, or / */
00100         if (!(xisalnum(r[0]) || r[0] == '_' || r[0] == '/')) {
00101             rpmError(RPMERR_BADSPEC,
00102                      _("line %d: Dependency tokens must begin with alpha-numeric, '_' or '/': %s\n"),
00103                      spec->lineNum, spec->line);
00104             return RPMERR_BADSPEC;
00105         }
00106 
00107         /* Don't permit file names as args for certain tags */
00108         switch (tag) {
00109         case RPMTAG_OBSOLETEFLAGS:
00110         case RPMTAG_CONFLICTFLAGS:
00111         case RPMTAG_BUILDCONFLICTS:
00112             if (r[0] == '/') {
00113                 rpmError(RPMERR_BADSPEC,_("line %d: File name not permitted: %s\n"),
00114                          spec->lineNum, spec->line);
00115                 return RPMERR_BADSPEC;
00116             }
00117             /*@switchbreak@*/ break;
00118         default:
00119             /*@switchbreak@*/ break;
00120         }
00121 
00122         re = r;
00123         SKIPNONWHITE(re);
00124         req = xmalloc((re-r) + 1);
00125         strncpy(req, r, (re-r));
00126         req[re-r] = '\0';
00127 
00128         /* Parse version */
00129         v = re;
00130         SKIPWHITE(v);
00131         ve = v;
00132         SKIPNONWHITE(ve);
00133 
00134         re = v; /* ==> next token (if no version found) starts here */
00135 
00136         /* Check for possible logical operator */
00137         if (ve > v) {
00138           struct ReqComp *rc;
00139           for (rc = ReqComparisons; rc->token != NULL; rc++) {
00140             if ((ve-v) != strlen(rc->token) || strncmp(v, rc->token, (ve-v)))
00141                 /*@innercontinue@*/ continue;
00142 
00143             if (r[0] == '/') {
00144                 rpmError(RPMERR_BADSPEC,
00145                          _("line %d: Versioned file name not permitted: %s\n"),
00146                          spec->lineNum, spec->line);
00147                 return RPMERR_BADSPEC;
00148             }
00149 
00150             switch(tag) {
00151             case RPMTAG_BUILDPREREQ:
00152             case RPMTAG_PREREQ:
00153             case RPMTAG_PROVIDEFLAGS:
00154             case RPMTAG_OBSOLETEFLAGS:
00155                 /* Add prereq on rpmlib that has versioned dependencies. */
00156                 if (!rpmExpandNumeric("%{?_noVersionedDependencies}"))
00157                     (void) rpmlibNeedsFeature(h, "VersionedDependencies", "3.0.3-1");
00158                 /*@switchbreak@*/ break;
00159             default:
00160                 /*@switchbreak@*/ break;
00161             }
00162             flags |= rc->sense;
00163 
00164             /* now parse version */
00165             v = ve;
00166             SKIPWHITE(v);
00167             ve = v;
00168             SKIPNONWHITE(ve);
00169             /*@innerbreak@*/ break;
00170           }
00171         }
00172 
00173         /*@-branchstate@*/
00174         if (flags & RPMSENSE_SENSEMASK) {
00175             if (*v == '\0' || ve == v) {
00176                 rpmError(RPMERR_BADSPEC, _("line %d: Version required: %s\n"),
00177                         spec->lineNum, spec->line);
00178                 return RPMERR_BADSPEC;
00179             }
00180             version = xmalloc((ve-v) + 1);
00181             strncpy(version, v, (ve-v));
00182             version[ve-v] = '\0';
00183             re = ve;    /* ==> next token after version string starts here */
00184         } else
00185             version = NULL;
00186         /*@=branchstate@*/
00187 
00188         (void) addReqProv(spec, h, flags, req, version, index);
00189 
00190         req = _free(req);
00191         version = _free(version);
00192 
00193     }
00194 /*@=boundsread@*/
00195 
00196     return 0;
00197 }

Generated on Sun Oct 26 13:01:57 2003 for rpm by doxygen1.2.18