2 * Copyright (c) 2007-2009, Novell Inc.
4 * This program is licensed under the BSD license, read LICENSE.BSD
5 * for further information
21 #if defined(DEBIAN_SEMANTICS) || defined(MULTI_SEMANTICS)
23 #ifdef MULTI_SEMANTICS
24 # define vercmp vercmp_deb
27 /* debian type version compare */
29 vercmp(const char *s1, const char *q1, const char *s2, const char *q2)
34 c1 = s1 < q1 ? *(const unsigned char *)s1++ : 0;
35 c2 = s2 < q2 ? *(const unsigned char *)s2++ : 0;
36 if ((c1 >= '0' && c1 <= '9') && (c2 >= '0' && c2 <= '9'))
39 c1 = s1 < q1 ? *(const unsigned char *)s1++ : 0;
41 c2 = s2 < q2 ? *(const unsigned char *)s2++ : 0;
43 while ((c1 >= '0' && c1 <= '9') && (c2 >= '0' && c2 <= '9'))
47 c1 = s1 < q1 ? *(const unsigned char *)s1++ : 0;
48 c2 = s2 < q2 ? *(const unsigned char *)s2++ : 0;
50 if (c1 >= '0' && c1 <= '9')
52 if (c2 >= '0' && c2 <= '9')
55 return r < 0 ? -1 : 1;
57 c1 = c1 == '~' ? -1 : !c1 || (c1 >= '0' && c1 <= '9') || (c1 >= 'A' && c1 <= 'Z') || (c1 >= 'a' && c1 <= 'z') ? c1 : c1 + 256;
58 c2 = c2 == '~' ? -1 : !c2 || (c2 >= '0' && c2 <= '9') || (c2 >= 'A' && c2 <= 'Z') || (c2 >= 'a' && c2 <= 'z') ? c2 : c2 + 256;
61 return r < 0 ? -1 : 1;
67 #ifdef MULTI_SEMANTICS
73 #if !defined(DEBIAN_SEMANTICS) || defined(MULTI_SEMANTICS)
75 /* rpm type version compare */
77 vercmp(const char *s1, const char *q1, const char *s2, const char *q2)
82 while (s1 < q1 && s2 < q2)
84 while (s1 < q1 && !(*s1 >= '0' && *s1 <= '9') &&
85 !(*s1 >= 'a' && *s1 <= 'z') && !(*s1 >= 'A' && *s1 <= 'Z'))
87 while (s2 < q2 && !(*s2 >= '0' && *s2 <= '9') &&
88 !(*s2 >= 'a' && *s2 <= 'z') && !(*s2 >= 'A' && *s2 <= 'Z'))
90 if ((*s1 >= '0' && *s1 <= '9') || (*s2 >= '0' && *s2 <= '9'))
92 while (*s1 == '0' && s1[1] >= '0' && s1[1] <= '9')
94 while (*s2 == '0' && s2[1] >= '0' && s2[1] <= '9')
96 for (e1 = s1; *e1 >= '0' && *e1 <= '9'; )
98 for (e2 = s2; *e2 >= '0' && *e2 <= '9'; )
100 r = e1 - s1 - (e2 - s2);
102 r = strncmp(s1, s2, e1 - s1);
104 return r > 0 ? 1 : -1;
108 for (e1 = s1; (*e1 >= 'a' && *e1 <= 'z') || (*e1 >= 'A' && *e1 <= 'Z'); )
110 for (e2 = s2; (*e2 >= 'a' && *e2 <= 'z') || (*e2 >= 'A' && *e2 <= 'Z'); )
112 r = e1 - s1 - (e2 - s2);
115 r = strncmp(s1, s2, e2 - s2);
116 return r >= 0 ? 1 : -1;
120 r = strncmp(s1, s2, e1 - s1);
121 return r <= 0 ? -1 : 1;
123 r = strncmp(s1, s2, e1 - s1);
125 return r > 0 ? 1 : -1;
130 return s1 < q1 ? 1 : s2 < q2 ? -1 : 0;
135 #if defined(MULTI_SEMANTICS)
136 # define vercmp (*(pool->disttype == DISTTYPE_DEB ? &vercmp_deb : &ver##cmp))
139 /* edition (e:v-r) compare */
141 evrcmp_str(const Pool *pool, const char *evr1, const char *evr2, int mode)
151 POOL_DEBUG(DEBUG_EVRCMP, "evrcmp %s %s mode=%d\n", evr1, evr2, mode);
153 for (s1 = evr1; *s1 >= '0' && *s1 <= '9'; s1++)
155 for (s2 = evr2; *s2 >= '0' && *s2 <= '9'; s2++)
157 if (mode == EVRCMP_MATCH && (*evr1 == ':' || *evr2 == ':'))
159 /* empty epoch, skip epoch check */
167 if (s1 == evr1 || *s1 != ':')
169 if (s2 == evr2 || *s2 != ':')
173 r = vercmp(evr1, s1, evr2, s2);
181 if (!pool->promoteepoch)
198 for (s1 = evr1, r1 = 0; *s1; s1++)
201 for (s2 = evr2, r2 = 0; *s2; s2++)
206 if (mode != EVRCMP_MATCH || (evr1 != (r1 ? r1 : s1) && evr2 != (r2 ? r2 : s2)))
207 r = vercmp(evr1, r1 ? r1 : s1, evr2, r2 ? r2 : s2);
211 if (mode == EVRCMP_COMPARE)
218 if (mode == EVRCMP_COMPARE_EVONLY)
222 if (s1 != ++r1 && s2 != ++r2)
223 r = vercmp(r1, s1, r2, s2);
229 evrcmp(const Pool *pool, Id evr1id, Id evr2id, int mode)
231 const char *evr1, *evr2;
232 if (evr1id == evr2id)
234 evr1 = id2str(pool, evr1id);
235 evr2 = id2str(pool, evr2id);
236 return evrcmp_str(pool, evr1, evr2, mode);
240 evrmatch(const Pool *pool, Id evrid, const char *epoch, const char *version, const char *release)
247 evr1 = id2str(pool, evrid);
248 for (s1 = evr1; *s1 >= '0' && *s1 <= '9'; s1++)
250 if (s1 != evr1 && *s1 == ':')
254 r = vercmp(evr1, s1, epoch, epoch + strlen(epoch));
262 while (*epoch == '0')
267 for (s1 = evr1, r1 = 0; *s1; s1++)
272 r = vercmp(evr1, r1 ? r1 : s1, version, version + strlen(version));
280 r = vercmp(r1 + 1, s1, release, release + strlen(release));