00001
00006 #include "system.h"
00007
00008 #include "rpmbuild.h"
00009 #include "debug.h"
00010
00013 static struct ReqComp {
00014 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
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
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
00127 v = re;
00128 SKIPWHITE(v);
00129 ve = v;
00130 SKIPNONWHITE(ve);
00131
00132 re = v;
00133
00134
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
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
00163 v = ve;
00164 SKIPWHITE(v);
00165 ve = v;
00166 SKIPNONWHITE(ve);
00167 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;
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 }