- add evrcmp_str for ma
[platform/upstream/libsolv.git] / src / evr.c
1 /*
2  * Copyright (c) 2007, 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 int
20 vercmp(const char *s1, const char *q1, const char *s2, const char *q2)
21 {
22   int r = 0;
23   const char *e1, *e2;
24
25   while (s1 < q1 && s2 < q2)
26     {
27       while (s1 < q1 && !(*s1 >= '0' && *s1 <= '9') &&
28           !(*s1 >= 'a' && *s1 <= 'z') && !(*s1 >= 'A' && *s1 <= 'Z'))
29         s1++;
30       while (s2 < q2 && !(*s2 >= '0' && *s2 <= '9') &&
31           !(*s2 >= 'a' && *s2 <= 'z') && !(*s2 >= 'A' && *s2 <= 'Z'))
32         s2++;
33       if ((*s1 >= '0' && *s1 <= '9') || (*s2 >= '0' && *s2 <= '9'))
34         {
35           while (*s1 == '0' && s1[1] >= '0' && s1[1] <= '9')
36             s1++;
37           while (*s2 == '0' && s2[1] >= '0' && s2[1] <= '9')
38             s2++;
39           for (e1 = s1; *e1 >= '0' && *e1 <= '9'; )
40             e1++;
41           for (e2 = s2; *e2 >= '0' && *e2 <= '9'; )
42             e2++;
43           r = e1 - s1 - (e2 - s2);
44           if (!r)
45             r = strncmp(s1, s2, e1 - s1);
46           if (r)
47             return r > 0 ? 1 : -1;
48         }
49       else
50         {
51           for (e1 = s1; (*e1 >= 'a' && *e1 <= 'z') || (*e1 >= 'A' && *e1 <= 'Z'); )
52             e1++;
53           for (e2 = s2; (*e2 >= 'a' && *e2 <= 'z') || (*e2 >= 'A' && *e2 <= 'Z'); )
54             e2++;
55           r = e1 - s1 - (e2 - s2);
56           if (r > 0)
57             {
58               r = strncmp(s1, s2, e2 - s2);
59               return r >= 0 ? 1 : -1;
60             }
61           if (r < 0)
62             {
63               r = strncmp(s1, s2, e1 - s1);
64               return r <= 0 ? -1 : 1;
65             }
66           r = strncmp(s1, s2, e1 - s1);
67           if (r)
68             return r > 0 ? 1 : -1;
69         }
70       s1 = e1;
71       s2 = e2;
72     }
73   return s1 < q1 ? 1 : s2 < q2 ? -1 : 0;
74 }
75
76 /* edition (e:v-r) compare */
77 int
78 evrcmp_str(Pool *pool, const char *evr1, const char *evr2, int mode)
79 {
80   int r;
81   const char *s1, *s2;
82   const char *r1, *r2;
83
84   if (evr1 == evr2)
85     return 0;
86
87 #if 0
88   POOL_DEBUG(DEBUG_EVRCMP, "evrcmp %s %s mode=%d\n", evr1, evr2, mode);
89 #endif
90   for (s1 = evr1; *s1 >= '0' && *s1 <= '9'; s1++)
91     ;
92   for (s2 = evr2; *s2 >= '0' && *s2 <= '9'; s2++)
93     ;
94   if (mode == EVRCMP_MATCH && (*evr1 == ':' || *evr2 == ':'))
95     {
96       /* empty epoch, skip epoch check */
97       if (*s1 == ':')
98         evr1 = s1 + 1;
99       if (*s2 == ':')
100         evr2 = s2 + 1;
101       s1 = evr1;
102       s2 = evr2;
103     }
104   if (s1 == evr1 || *s1 != ':')
105     s1 = 0;
106   if (s2 == evr2 || *s2 != ':')
107     s2 = 0;
108   if (s1 && s2)
109     {
110       r = vercmp(evr1, s1, evr2, s2);
111       if (r)
112         return r;
113       evr1 = s1 + 1;
114       evr2 = s2 + 1;
115     }
116   else if (s1)
117     {
118       if (!pool->promoteepoch)
119         {
120           while (*evr1 == '0')
121             evr1++;
122           if (*evr1 != ':')
123             return 1;
124         }
125       evr1 = s1 + 1;
126     }
127   else if (s2)
128     {
129       while (*evr2 == '0')
130         evr2++;
131       if (*evr2 != ':')
132         return -1;
133       evr2 = s2 + 1;
134     }
135   for (s1 = evr1, r1 = 0; *s1; s1++)
136     if (*s1 == '-')
137       r1 = s1;
138   for (s2 = evr2, r2 = 0; *s2; s2++)
139     if (*s2 == '-')
140       r2 = s2;
141
142   r = 0;
143   if (mode != EVRCMP_MATCH || (evr1 != (r1 ? r1 : s1) && evr2 != (r2 ? r2 : s2)))
144     r = vercmp(evr1, r1 ? r1 : s1, evr2, r2 ? r2 : s2);
145   if (r)
146     return r;
147
148   if (mode == EVRCMP_COMPARE)
149     {
150       if (!r1 && r2)
151         return -1;
152       if (r1 && !r2)
153         return 1;
154     }
155   if (r1 && r2)
156     {
157       if (s1 != ++r1 && s2 != ++r2)
158         r = vercmp(r1, s1, r2, s2);
159     }
160   return r;
161 }
162
163 int
164 evrcmp(Pool *pool, Id evr1id, Id evr2id, int mode)
165 {
166   const char *evr1, *evr2;
167   if (evr1id == evr2id)
168     return 0;
169   evr1 = id2str(pool, evr1id);
170   evr2 = id2str(pool, evr2id);
171   return evrcmp_str(pool, evr1, evr2, mode);
172 }
173
174 int
175 evrmatch(Pool *pool, Id evrid, const char *epoch, const char *version, const char *release)
176 {
177   const char *evr1;
178   const char *s1;
179   const char *r1;
180   int r;
181
182   evr1 = id2str(pool, evrid);
183   for (s1 = evr1; *s1 >= '0' && *s1 <= '9'; s1++)
184     ;
185   if (s1 != evr1 && *s1 == ':')
186     {
187       if (epoch)
188         {
189           r = vercmp(evr1, s1, epoch, epoch + strlen(epoch));
190           if (r)
191             return r;
192         }
193       evr1 = s1 + 1;
194     }
195   else if (epoch)
196     {
197       while (*epoch == '0')
198         epoch++;
199       if (*epoch)
200         return -1;
201     }
202   for (s1 = evr1, r1 = 0; *s1; s1++)
203     if (*s1 == '-')
204       r1 = s1;
205   if (version)
206     {
207       r = vercmp(evr1, r1 ? r1 : s1, version, version + strlen(version));
208       if (r)
209         return r;
210     }
211   if (release)
212     {
213       if (!r1)
214         return -1;
215       r = vercmp(r1 + 1, s1, release, release + strlen(release));
216       if (r)
217         return r;
218     }
219   return 0;
220 }
221
222 // EOF