00001
00006 #include "system.h"
00007
00008 #include "rpmbuild.h"
00009 #include "debug.h"
00010
00013
00014 static struct ReqComp {
00015 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
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
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
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 break;
00118 default:
00119 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
00129 v = re;
00130 SKIPWHITE(v);
00131 ve = v;
00132 SKIPNONWHITE(ve);
00133
00134 re = v;
00135
00136
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 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
00156 if (!rpmExpandNumeric("%{?_noVersionedDependencies}"))
00157 (void) rpmlibNeedsFeature(h, "VersionedDependencies", "3.0.3-1");
00158 break;
00159 default:
00160 break;
00161 }
00162 flags |= rc->sense;
00163
00164
00165 v = ve;
00166 SKIPWHITE(v);
00167 ve = v;
00168 SKIPNONWHITE(ve);
00169 break;
00170 }
00171 }
00172
00173
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;
00184 } else
00185 version = NULL;
00186
00187
00188 (void) addReqProv(spec, h, flags, req, version, index);
00189
00190 req = _free(req);
00191 version = _free(version);
00192
00193 }
00194
00195
00196 return 0;
00197 }