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
00022 static int _invert_digits_alphas_comparison = -1;
00023
00024
00025
00026 static const char * _rpmnotalpha = ".:-";
00027
00033 static inline int xisrpmalpha(int c)
00034
00035 {
00036 int rc = xisalpha(c);
00037 if (!rc)
00038 rc = xispunct(c);
00039 if (rc && _rpmnotalpha && *_rpmnotalpha)
00040 rc = (strchr(_rpmnotalpha, c) == NULL);
00041 return rc;
00042 }
00043
00044 int rpmEVRcmp(const char * a, const char * b)
00045
00046 {
00047 const char * ae, * be;
00048 int rc = 0;
00049
00050
00051 for (; *a && *b && rc == 0; a = ae, b = be) {
00052
00053
00054 while (*a && !(xisdigit(*a) || xisrpmalpha(*a))) a++;
00055 while (*b && !(xisdigit(*b) || xisrpmalpha(*b))) b++;
00056
00057
00058 if (xisdigit(*a) || xisdigit(*b)) {
00059
00060 while (a[0] == '0' && xisdigit(a[1])) a++;
00061 while (b[0] == '0' && xisdigit(b[1])) b++;
00062
00063
00064 ae = a; while (xisdigit(*ae)) ae++;
00065 be = b; while (xisdigit(*be)) be++;
00066
00067
00068 if (a == ae || b == be)
00069 rc = (*b - *a) * _invert_digits_alphas_comparison;
00070 else {
00071 rc = (ae - a) - (be - b);
00072 if (!rc)
00073 rc = strncmp(a, b, (ae - a));
00074 }
00075 } else {
00076
00077 ae = a; while (xisrpmalpha(*ae)) ae++;
00078 be = b; while (xisrpmalpha(*be)) be++;
00079
00080
00081 rc = strncmp(a, b, MAX((ae - a), (be - b)));
00082 }
00083 }
00084
00085
00086 if (!rc)
00087 rc = (*a - *b);
00088
00089
00090 rc = (rc > 0 ? 1
00091 : rc < 0 ? -1
00092 : 0);
00093 return rc;
00094 }
00095
00096 int rpmEVRparse(const char * evrstr, EVR_t evr)
00097
00098 {
00099 char *s = xstrdup(evrstr);
00100 char *se;
00101
00102 evr->str = se = s;
00103 while (*se && xisdigit(*se)) se++;
00104
00105 if (*se == ':') {
00106 evr->E = s;
00107 *se++ = '\0';
00108 evr->V = se;
00109 if (*evr->E == '\0') evr->E = "0";
00110 evr->Elong = strtoul(evr->E, NULL, 10);
00111 } else {
00112 evr->E = NULL;
00113 evr->V = s;
00114 evr->Elong = 0;
00115 }
00116 se = strrchr(se, '-');
00117 if (se) {
00118 *se++ = '\0';
00119 evr->R = se;
00120 } else {
00121 evr->R = NULL;
00122 }
00123 return 0;
00124 }
00125
00132 static int compare_values(const char *a, const char *b)
00133
00134 {
00135 return rpmvercmp(a, b);
00136 }
00137
00138 int rpmEVRcompare(const EVR_t a, const EVR_t b)
00139 {
00140 int rc = 0;
00141
00142 if (!rc)
00143 rc = compare_values(a->E, b->E);
00144 if (!rc)
00145 rc = compare_values(a->V, b->V);
00146 if (!rc)
00147 rc = compare_values(a->R, b->R);
00148 return rc;
00149 }
00150
00151 int (*rpmvercmp) (const char *a, const char *b) = rpmEVRcmp;
00152
00155
00156 static struct EVRop_s {
00157
00158 const char * operator;
00159 rpmsenseFlags sense;
00160 } cops[] = {
00161 { "<=", RPMSENSE_LESS ^ RPMSENSE_EQUAL},
00162 { "=<", RPMSENSE_LESS ^ RPMSENSE_EQUAL},
00163
00164 { "==", RPMSENSE_EQUAL},
00165 { "!=", RPMSENSE_NOTEQUAL},
00166
00167 { ">=", RPMSENSE_GREATER ^ RPMSENSE_EQUAL},
00168 { "=>", RPMSENSE_GREATER ^ RPMSENSE_EQUAL},
00169
00170 { "<", RPMSENSE_LESS},
00171 { "=", RPMSENSE_EQUAL},
00172 { ">", RPMSENSE_GREATER},
00173
00174 { NULL, 0 },
00175 };
00176
00177 rpmsenseFlags rpmEVRflags(const char *op, const char **end)
00178 {
00179 rpmsenseFlags Flags = 0;
00180 struct EVRop_s *cop;
00181
00182 if (op == NULL || *op == '\0')
00183 Flags = RPMSENSE_EQUAL;
00184 else
00185 for (cop = cops; cop->operator != NULL; cop++) {
00186 if (strncmp(op, cop->operator, strlen(cop->operator)))
00187 continue;
00188 Flags = cop->sense;
00189 if (end)
00190 *end = op + strlen(cop->operator);
00191 break;
00192 }
00193 return Flags;
00194 }