satsolver 0.16.3
|
00001 /* 00002 * Copyright (c) 2007-2009, Novell Inc. 00003 * 00004 * This program is licensed under the BSD license, read LICENSE.BSD 00005 * for further information 00006 */ 00007 00008 /* 00009 * evr.c 00010 * 00011 * version compare 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 /* debian type version compare */ 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 /* rpm type version compare */ 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 /* edition (e:v-r) compare */ 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 /* empty epoch, skip epoch check */ 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 // EOF