00001
00004 #include "system.h"
00005
00006 #include <rpmio.h>
00007
00008 #define _RPMEVR_INTERNAL
00009 #include <rpmevr.h>
00010
00011 #include "debug.h"
00012
00013
00014 int _rpmevr_debug = 0;
00015
00016 #if !defined(MAX)
00017 #define MAX(x, y) ( ((x)>(y))?(x):(y) )
00018 #endif
00019
00020
00021 #if defined(RPM_VENDOR_MANDRIVA)
00022
00023 static int _invert_digits_alphas_comparison = 1;
00024 #else
00025
00026 static int _invert_digits_alphas_comparison = -1;
00027 #endif
00028
00029
00030
00031 static const char * _rpmnotalpha = ".:-";
00032
00038 static inline int xisrpmalpha(int c)
00039
00040 {
00041 int rc = xisalpha(c);
00042 if (!rc)
00043 rc = xispunct(c);
00044 if (rc && _rpmnotalpha && *_rpmnotalpha)
00045 rc = (strchr(_rpmnotalpha, c) == NULL);
00046 return rc;
00047 }
00048
00049 int rpmEVRcmp(const char * a, const char * b)
00050
00051 {
00052 const char * ae, * be;
00053 int rc = 0;
00054
00055
00056 for (; *a && *b && rc == 0; a = ae, b = be) {
00057
00058
00059 while (*a && !(xisdigit(*a) || xisrpmalpha(*a))) a++;
00060 while (*b && !(xisdigit(*b) || xisrpmalpha(*b))) b++;
00061
00062
00063 if (xisdigit(*a) || xisdigit(*b)) {
00064
00065 while (a[0] == '0' && xisdigit(a[1])) a++;
00066 while (b[0] == '0' && xisdigit(b[1])) b++;
00067
00068
00069 ae = a; while (xisdigit(*ae)) ae++;
00070 be = b; while (xisdigit(*be)) be++;
00071
00072
00073 if (a == ae || b == be)
00074 rc = (*b - *a) * _invert_digits_alphas_comparison;
00075 else {
00076 rc = (ae - a) - (be - b);
00077 if (!rc)
00078 rc = strncmp(a, b, (ae - a));
00079 }
00080 } else {
00081
00082 ae = a; while (xisrpmalpha(*ae)) ae++;
00083 be = b; while (xisrpmalpha(*be)) be++;
00084
00085
00086 rc = strncmp(a, b, MAX((ae - a), (be - b)));
00087 }
00088 }
00089
00090
00091 if (!rc)
00092 rc = (*a - *b);
00093
00094
00095 rc = (rc > 0 ? 1
00096 : rc < 0 ? -1
00097 : 0);
00098 return rc;
00099 }
00100
00101 int rpmEVRparse(const char * evrstr, EVR_t evr)
00102
00103 {
00104 char *s = xstrdup(evrstr);
00105 char *se;
00106
00107 evr->str = se = s;
00108 while (*se && xisdigit(*se)) se++;
00109
00110 if (*se == ':') {
00111 evr->E = s;
00112 *se++ = '\0';
00113 evr->V = se;
00114
00115 if (*evr->E == '\0') evr->E = "0";
00116
00117 evr->Elong = strtoul(evr->E, NULL, 10);
00118 } else {
00119 evr->E = NULL;
00120 evr->V = s;
00121 evr->Elong = 0;
00122 }
00123 se = strrchr(se, '-');
00124 if (se) {
00125 *se++ = '\0';
00126 evr->R = se;
00127 } else {
00128 evr->R = NULL;
00129 }
00130 return 0;
00131 }
00132
00139 static int compare_values(const char *a, const char *b)
00140
00141 {
00142 return rpmvercmp(a, b);
00143 }
00144
00145 int rpmEVRcompare(const EVR_t a, const EVR_t b)
00146 {
00147 int rc = 0;
00148
00149 if (!rc)
00150 rc = compare_values(a->E, b->E);
00151 if (!rc)
00152 rc = compare_values(a->V, b->V);
00153 if (!rc)
00154 rc = compare_values(a->R, b->R);
00155 return rc;
00156 }
00157
00158 int (*rpmvercmp) (const char *a, const char *b) = rpmEVRcmp;
00159
00162
00163 static struct EVRop_s {
00164
00165 const char * operator;
00166 rpmsenseFlags sense;
00167 } cops[] = {
00168 { "<=", RPMSENSE_LESS ^ RPMSENSE_EQUAL},
00169 { "=<", RPMSENSE_LESS ^ RPMSENSE_EQUAL},
00170
00171 { "==", RPMSENSE_EQUAL},
00172 { "!=", RPMSENSE_NOTEQUAL},
00173
00174 { ">=", RPMSENSE_GREATER ^ RPMSENSE_EQUAL},
00175 { "=>", RPMSENSE_GREATER ^ RPMSENSE_EQUAL},
00176
00177 { "<", RPMSENSE_LESS},
00178 { "=", RPMSENSE_EQUAL},
00179 { ">", RPMSENSE_GREATER},
00180
00181 { NULL, 0 },
00182 };
00183
00184 rpmsenseFlags rpmEVRflags(const char *op, const char **end)
00185 {
00186 rpmsenseFlags Flags = 0;
00187 struct EVRop_s *cop;
00188
00189 if (op == NULL || *op == '\0')
00190 Flags = RPMSENSE_EQUAL;
00191 else
00192 for (cop = cops; cop->operator != NULL; cop++) {
00193 if (strncmp(op, cop->operator, strlen(cop->operator)))
00194 continue;
00195 Flags = cop->sense;
00196 if (end)
00197 *end = op + strlen(cop->operator);
00198 break;
00199 }
00200 return Flags;
00201 }