- add inferior arch handling
[platform/upstream/libsolv.git] / src / evr.c
1 /*
2  * Copyright (c) 2007-2009, Novell Inc.
3  *
4  * This program is licensed under the BSD license, read LICENSE.BSD
5  * for further information
6  */
7
8 /*
9  * evr.c
10  *
11  * version compare
12  */
13
14 #include <stdio.h>
15 #include <string.h>
16 #include "evr.h"
17 #include "pool.h"
18
19
20 #ifdef DEBIAN_SEMANTICS
21
22 int
23 vercmp(const char *s1, const char *q1, const char *s2, const char *q2)
24 {
25   int r, c1, c2;
26   while (1)
27     {
28       c1 = s1 < q1 ? *(const unsigned char *)s1++ : 0;
29       c2 = s2 < q2 ? *(const unsigned char *)s2++ : 0;
30       if ((c1 >= '0' && c1 <= '9') && (c2 >= '0' && c2 <= '9'))
31         {
32           while (c1 == '0')
33             c1 = s1 < q1 ? *(const unsigned char *)s1++ : 0;
34           while (c2 == '0')
35             c2 = s2 < q2 ? *(const unsigned char *)s2++ : 0;
36           r = 0;
37           while ((c1 >= '0' && c1 <= '9') && (c2 >= '0' && c2 <= '9'))
38             {
39               if (!r)
40                 r = c1 - c2;
41               c1 = s1 < q1 ? *(const unsigned char *)s1++ : 0;
42               c2 = s2 < q2 ? *(const unsigned char *)s2++ : 0;
43             }
44           if (c1 >= '0' && c1 <= '9')
45             return 1;
46           if (c2 >= '0' && c2 <= '9')
47             return -1;
48           if (r)
49             return r < 0 ? -1 : 1;
50         }
51       c1 = c1 == '~' ? -1 : !c1 || (c1 >= '0' && c1 <= '9') || (c1 >= 'A' && c1 <= 'Z') || (c1 >= 'a' && c1 <= 'z')  ? c1 : c1 + 256;
52       c2 = c2 == '~' ? -1 : !c2 || (c2 >= '0' && c2 <= '9') || (c2 >= 'A' && c2 <= 'Z') || (c2 >= 'a' && c2 <= 'z')  ? c2 : c2 + 256;
53       r = c1 - c2;
54       if (r)
55         return r < 0 ? -1 : 1;
56       if (!c1)
57         return 0;
58     }
59 }
60
61 #else
62
63 int
64 vercmp(const char *s1, const char *q1, const char *s2, const char *q2)
65 {
66   int r = 0;
67   const char *e1, *e2;
68
69   while (s1 < q1 && s2 < q2)
70     {
71       while (s1 < q1 && !(*s1 >= '0' && *s1 <= '9') &&
72           !(*s1 >= 'a' && *s1 <= 'z') && !(*s1 >= 'A' && *s1 <= 'Z'))
73         s1++;
74       while (s2 < q2 && !(*s2 >= '0' && *s2 <= '9') &&
75           !(*s2 >= 'a' && *s2 <= 'z') && !(*s2 >= 'A' && *s2 <= 'Z'))
76         s2++;
77       if ((*s1 >= '0' && *s1 <= '9') || (*s2 >= '0' && *s2 <= '9'))
78         {
79           while (*s1 == '0' && s1[1] >= '0' && s1[1] <= '9')
80             s1++;
81           while (*s2 == '0' && s2[1] >= '0' && s2[1] <= '9')
82             s2++;
83           for (e1 = s1; *e1 >= '0' && *e1 <= '9'; )
84             e1++;
85           for (e2 = s2; *e2 >= '0' && *e2 <= '9'; )
86             e2++;
87           r = e1 - s1 - (e2 - s2);
88           if (!r)
89             r = strncmp(s1, s2, e1 - s1);
90           if (r)
91             return r > 0 ? 1 : -1;
92         }
93       else
94         {
95           for (e1 = s1; (*e1 >= 'a' && *e1 <= 'z') || (*e1 >= 'A' && *e1 <= 'Z'); )
96             e1++;
97           for (e2 = s2; (*e2 >= 'a' && *e2 <= 'z') || (*e2 >= 'A' && *e2 <= 'Z'); )
98             e2++;
99           r = e1 - s1 - (e2 - s2);
100           if (r > 0)
101             {
102               r = strncmp(s1, s2, e2 - s2);
103               return r >= 0 ? 1 : -1;
104             }
105           if (r < 0)
106             {
107               r = strncmp(s1, s2, e1 - s1);
108               return r <= 0 ? -1 : 1;
109             }
110           r = strncmp(s1, s2, e1 - s1);
111           if (r)
112             return r > 0 ? 1 : -1;
113         }
114       s1 = e1;
115       s2 = e2;
116     }
117   return s1 < q1 ? 1 : s2 < q2 ? -1 : 0;
118 }
119
120 #endif
121
122
123 /* edition (e:v-r) compare */
124 int
125 evrcmp_str(Pool *pool, const char *evr1, const char *evr2, int mode)
126 {
127   int r;
128   const char *s1, *s2;
129   const char *r1, *r2;
130
131   if (evr1 == evr2)
132     return 0;
133
134 #if 0
135   POOL_DEBUG(DEBUG_EVRCMP, "evrcmp %s %s mode=%d\n", evr1, evr2, mode);
136 #endif
137   for (s1 = evr1; *s1 >= '0' && *s1 <= '9'; s1++)
138     ;
139   for (s2 = evr2; *s2 >= '0' && *s2 <= '9'; s2++)
140     ;
141   if (mode == EVRCMP_MATCH && (*evr1 == ':' || *evr2 == ':'))
142     {
143       /* empty epoch, skip epoch check */
144       if (*s1 == ':')
145         evr1 = s1 + 1;
146       if (*s2 == ':')
147         evr2 = s2 + 1;
148       s1 = evr1;
149       s2 = evr2;
150     }
151   if (s1 == evr1 || *s1 != ':')
152     s1 = 0;
153   if (s2 == evr2 || *s2 != ':')
154     s2 = 0;
155   if (s1 && s2)
156     {
157       r = vercmp(evr1, s1, evr2, s2);
158       if (r)
159         return r;
160       evr1 = s1 + 1;
161       evr2 = s2 + 1;
162     }
163   else if (s1)
164     {
165       if (!pool->promoteepoch)
166         {
167           while (*evr1 == '0')
168             evr1++;
169           if (*evr1 != ':')
170             return 1;
171         }
172       evr1 = s1 + 1;
173     }
174   else if (s2)
175     {
176       while (*evr2 == '0')
177         evr2++;
178       if (*evr2 != ':')
179         return -1;
180       evr2 = s2 + 1;
181     }
182   for (s1 = evr1, r1 = 0; *s1; s1++)
183     if (*s1 == '-')
184       r1 = s1;
185   for (s2 = evr2, r2 = 0; *s2; s2++)
186     if (*s2 == '-')
187       r2 = s2;
188
189   r = 0;
190   if (mode != EVRCMP_MATCH || (evr1 != (r1 ? r1 : s1) && evr2 != (r2 ? r2 : s2)))
191     r = vercmp(evr1, r1 ? r1 : s1, evr2, r2 ? r2 : s2);
192   if (r)
193     return r;
194
195   if (mode == EVRCMP_COMPARE)
196     {
197       if (!r1 && r2)
198         return -1;
199       if (r1 && !r2)
200         return 1;
201     }
202   if (r1 && r2)
203     {
204       if (s1 != ++r1 && s2 != ++r2)
205         r = vercmp(r1, s1, r2, s2);
206     }
207   return r;
208 }
209
210 int
211 evrcmp(Pool *pool, Id evr1id, Id evr2id, int mode)
212 {
213   const char *evr1, *evr2;
214   if (evr1id == evr2id)
215     return 0;
216   evr1 = id2str(pool, evr1id);
217   evr2 = id2str(pool, evr2id);
218   return evrcmp_str(pool, evr1, evr2, mode);
219 }
220
221 int
222 evrmatch(Pool *pool, Id evrid, const char *epoch, const char *version, const char *release)
223 {
224   const char *evr1;
225   const char *s1;
226   const char *r1;
227   int r;
228
229   evr1 = id2str(pool, evrid);
230   for (s1 = evr1; *s1 >= '0' && *s1 <= '9'; s1++)
231     ;
232   if (s1 != evr1 && *s1 == ':')
233     {
234       if (epoch)
235         {
236           r = vercmp(evr1, s1, epoch, epoch + strlen(epoch));
237           if (r)
238             return r;
239         }
240       evr1 = s1 + 1;
241     }
242   else if (epoch)
243     {
244       while (*epoch == '0')
245         epoch++;
246       if (*epoch)
247         return -1;
248     }
249   for (s1 = evr1, r1 = 0; *s1; s1++)
250     if (*s1 == '-')
251       r1 = s1;
252   if (version)
253     {
254       r = vercmp(evr1, r1 ? r1 : s1, version, version + strlen(version));
255       if (r)
256         return r;
257     }
258   if (release)
259     {
260       if (!r1)
261         return -1;
262       r = vercmp(r1 + 1, s1, release, release + strlen(release));
263       if (r)
264         return r;
265     }
266   return 0;
267 }
268
269 // EOF