00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <stdio.h>
00015 #include <string.h>
00016 #include "evr.h"
00017 #include "pool.h"
00018
00019
00020
00021 #if defined(DEBIAN_SEMANTICS) || defined(MULTI_SEMANTICS)
00022
00023 #ifdef MULTI_SEMANTICS
00024 # define vercmp vercmp_deb
00025 #endif
00026
00027
00028 int
00029 vercmp(const char *s1, const char *q1, const char *s2, const char *q2)
00030 {
00031 int r, c1, c2;
00032 while (1)
00033 {
00034 c1 = s1 < q1 ? *(const unsigned char *)s1++ : 0;
00035 c2 = s2 < q2 ? *(const unsigned char *)s2++ : 0;
00036 if ((c1 >= '0' && c1 <= '9') && (c2 >= '0' && c2 <= '9'))
00037 {
00038 while (c1 == '0')
00039 c1 = s1 < q1 ? *(const unsigned char *)s1++ : 0;
00040 while (c2 == '0')
00041 c2 = s2 < q2 ? *(const unsigned char *)s2++ : 0;
00042 r = 0;
00043 while ((c1 >= '0' && c1 <= '9') && (c2 >= '0' && c2 <= '9'))
00044 {
00045 if (!r)
00046 r = c1 - c2;
00047 c1 = s1 < q1 ? *(const unsigned char *)s1++ : 0;
00048 c2 = s2 < q2 ? *(const unsigned char *)s2++ : 0;
00049 }
00050 if (c1 >= '0' && c1 <= '9')
00051 return 1;
00052 if (c2 >= '0' && c2 <= '9')
00053 return -1;
00054 if (r)
00055 return r < 0 ? -1 : 1;
00056 }
00057 c1 = c1 == '~' ? -1 : !c1 || (c1 >= '0' && c1 <= '9') || (c1 >= 'A' && c1 <= 'Z') || (c1 >= 'a' && c1 <= 'z') ? c1 : c1 + 256;
00058 c2 = c2 == '~' ? -1 : !c2 || (c2 >= '0' && c2 <= '9') || (c2 >= 'A' && c2 <= 'Z') || (c2 >= 'a' && c2 <= 'z') ? c2 : c2 + 256;
00059 r = c1 - c2;
00060 if (r)
00061 return r < 0 ? -1 : 1;
00062 if (!c1)
00063 return 0;
00064 }
00065 }
00066
00067 #ifdef MULTI_SEMANTICS
00068 # undef vercmp
00069 #endif
00070
00071 #endif
00072
00073 #if !defined(DEBIAN_SEMANTICS) || defined(MULTI_SEMANTICS)
00074
00075
00076 int
00077 vercmp(const char *s1, const char *q1, const char *s2, const char *q2)
00078 {
00079 int r = 0;
00080 const char *e1, *e2;
00081
00082 while (s1 < q1 && s2 < q2)
00083 {
00084 while (s1 < q1 && !(*s1 >= '0' && *s1 <= '9') &&
00085 !(*s1 >= 'a' && *s1 <= 'z') && !(*s1 >= 'A' && *s1 <= 'Z'))
00086 s1++;
00087 while (s2 < q2 && !(*s2 >= '0' && *s2 <= '9') &&
00088 !(*s2 >= 'a' && *s2 <= 'z') && !(*s2 >= 'A' && *s2 <= 'Z'))
00089 s2++;
00090 if ((*s1 >= '0' && *s1 <= '9') || (*s2 >= '0' && *s2 <= '9'))
00091 {
00092 while (*s1 == '0' && s1[1] >= '0' && s1[1] <= '9')
00093 s1++;
00094 while (*s2 == '0' && s2[1] >= '0' && s2[1] <= '9')
00095 s2++;
00096 for (e1 = s1; *e1 >= '0' && *e1 <= '9'; )
00097 e1++;
00098 for (e2 = s2; *e2 >= '0' && *e2 <= '9'; )
00099 e2++;
00100 r = e1 - s1 - (e2 - s2);
00101 if (!r)
00102 r = strncmp(s1, s2, e1 - s1);
00103 if (r)
00104 return r > 0 ? 1 : -1;
00105 }
00106 else
00107 {
00108 for (e1 = s1; (*e1 >= 'a' && *e1 <= 'z') || (*e1 >= 'A' && *e1 <= 'Z'); )
00109 e1++;
00110 for (e2 = s2; (*e2 >= 'a' && *e2 <= 'z') || (*e2 >= 'A' && *e2 <= 'Z'); )
00111 e2++;
00112 r = e1 - s1 - (e2 - s2);
00113 if (r > 0)
00114 {
00115 r = strncmp(s1, s2, e2 - s2);
00116 return r >= 0 ? 1 : -1;
00117 }
00118 if (r < 0)
00119 {
00120 r = strncmp(s1, s2, e1 - s1);
00121 return r <= 0 ? -1 : 1;
00122 }
00123 r = strncmp(s1, s2, e1 - s1);
00124 if (r)
00125 return r > 0 ? 1 : -1;
00126 }
00127 s1 = e1;
00128 s2 = e2;
00129 }
00130 return s1 < q1 ? 1 : s2 < q2 ? -1 : 0;
00131 }
00132
00133 #endif
00134
00135 #if defined(MULTI_SEMANTICS)
00136 # define vercmp (*(pool->disttype == DISTTYPE_DEB ? &vercmp_deb : &ver##cmp))
00137 #endif
00138
00139
00140 int
00141 evrcmp_str(const Pool *pool, const char *evr1, const char *evr2, int mode)
00142 {
00143 int r;
00144 const char *s1, *s2;
00145 const char *r1, *r2;
00146
00147 if (evr1 == evr2)
00148 return 0;
00149
00150 #if 0
00151 POOL_DEBUG(DEBUG_EVRCMP, "evrcmp %s %s mode=%d\n", evr1, evr2, mode);
00152 #endif
00153 for (s1 = evr1; *s1 >= '0' && *s1 <= '9'; s1++)
00154 ;
00155 for (s2 = evr2; *s2 >= '0' && *s2 <= '9'; s2++)
00156 ;
00157 if (mode == EVRCMP_MATCH && (*evr1 == ':' || *evr2 == ':'))
00158 {
00159
00160 if (*s1 == ':')
00161 evr1 = s1 + 1;
00162 if (*s2 == ':')
00163 evr2 = s2 + 1;
00164 s1 = evr1;
00165 s2 = evr2;
00166 }
00167 if (s1 == evr1 || *s1 != ':')
00168 s1 = 0;
00169 if (s2 == evr2 || *s2 != ':')
00170 s2 = 0;
00171 if (s1 && s2)
00172 {
00173 r = vercmp(evr1, s1, evr2, s2);
00174 if (r)
00175 return r;
00176 evr1 = s1 + 1;
00177 evr2 = s2 + 1;
00178 }
00179 else if (s1)
00180 {
00181 if (!pool->promoteepoch)
00182 {
00183 while (*evr1 == '0')
00184 evr1++;
00185 if (*evr1 != ':')
00186 return 1;
00187 }
00188 evr1 = s1 + 1;
00189 }
00190 else if (s2)
00191 {
00192 while (*evr2 == '0')
00193 evr2++;
00194 if (*evr2 != ':')
00195 return -1;
00196 evr2 = s2 + 1;
00197 }
00198 for (s1 = evr1, r1 = 0; *s1; s1++)
00199 if (*s1 == '-')
00200 r1 = s1;
00201 for (s2 = evr2, r2 = 0; *s2; s2++)
00202 if (*s2 == '-')
00203 r2 = s2;
00204
00205 r = 0;
00206 if (mode != EVRCMP_MATCH || (evr1 != (r1 ? r1 : s1) && evr2 != (r2 ? r2 : s2)))
00207 r = vercmp(evr1, r1 ? r1 : s1, evr2, r2 ? r2 : s2);
00208 if (r)
00209 return r;
00210
00211 if (mode == EVRCMP_COMPARE)
00212 {
00213 if (!r1 && r2)
00214 return -1;
00215 if (r1 && !r2)
00216 return 1;
00217 }
00218 if (mode == EVRCMP_COMPARE_EVONLY)
00219 return 0;
00220 if (r1 && r2)
00221 {
00222 if (s1 != ++r1 && s2 != ++r2)
00223 r = vercmp(r1, s1, r2, s2);
00224 }
00225 return r;
00226 }
00227
00228 int
00229 evrcmp(const Pool *pool, Id evr1id, Id evr2id, int mode)
00230 {
00231 const char *evr1, *evr2;
00232 if (evr1id == evr2id)
00233 return 0;
00234 evr1 = id2str(pool, evr1id);
00235 evr2 = id2str(pool, evr2id);
00236 return evrcmp_str(pool, evr1, evr2, mode);
00237 }
00238
00239 int
00240 evrmatch(const Pool *pool, Id evrid, const char *epoch, const char *version, const char *release)
00241 {
00242 const char *evr1;
00243 const char *s1;
00244 const char *r1;
00245 int r;
00246
00247 evr1 = id2str(pool, evrid);
00248 for (s1 = evr1; *s1 >= '0' && *s1 <= '9'; s1++)
00249 ;
00250 if (s1 != evr1 && *s1 == ':')
00251 {
00252 if (epoch)
00253 {
00254 r = vercmp(evr1, s1, epoch, epoch + strlen(epoch));
00255 if (r)
00256 return r;
00257 }
00258 evr1 = s1 + 1;
00259 }
00260 else if (epoch)
00261 {
00262 while (*epoch == '0')
00263 epoch++;
00264 if (*epoch)
00265 return -1;
00266 }
00267 for (s1 = evr1, r1 = 0; *s1; s1++)
00268 if (*s1 == '-')
00269 r1 = s1;
00270 if (version)
00271 {
00272 r = vercmp(evr1, r1 ? r1 : s1, version, version + strlen(version));
00273 if (r)
00274 return r;
00275 }
00276 if (release)
00277 {
00278 if (!r1)
00279 return -1;
00280 r = vercmp(r1 + 1, s1, release, release + strlen(release));
00281 if (r)
00282 return r;
00283 }
00284 return 0;
00285 }
00286
00287