- add a license
[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
77 // edition (e:v-r) compare
78 int
79 evrcmp(Pool *pool, Id evr1id, Id evr2id)
80 {
81   int r;
82   const char *evr1, *evr2;
83   const char *s1, *s2;
84   const char *r1, *r2;
85
86   if (evr1id == evr2id)
87     return 0;
88   evr1 = id2str(pool, evr1id);
89   evr2 = id2str(pool, evr2id);
90
91 #if 0
92   printf("evrcmp %s %s\n", evr1, evr2);
93 #endif
94   for (s1 = evr1; *s1 >= '0' && *s1 <= '9'; s1++)
95     ;
96   for (s2 = evr2; *s2 >= '0' && *s2 <= '9'; s2++)
97     ;
98   if (s1 == evr1 || *s1 != ':')
99     s1 = 0;
100   if (s2 == evr2 || *s2 != ':')
101     s2 = 0;
102   if (s1 && s2)
103     {
104       r = vercmp(evr1, s1, evr2, s2);
105       if (r)
106         return r;
107       evr1 = s1 + 1;
108       evr2 = s2 + 1;
109     }
110   else if (s1)
111     {
112       if (!pool->promoteepoch)
113         {
114           while (*evr1 == '0')
115             evr1++;
116           if (*evr1 != ':')
117             return 1;
118         }
119       evr1 = s1 + 1;
120     }
121   else if (s2)
122     {
123       while (*evr2 == '0')
124         evr2++;
125       if (*evr2 != ':')
126         return -1;
127       evr2 = s2 + 1;
128     }
129   for (s1 = evr1, r1 = 0; *s1; s1++)
130     if (*s1 == '-')
131       r1 = s1;
132   for (s2 = evr2, r2 = 0; *s2; s2++)
133     if (*s2 == '-')
134       r2 = s2;
135   r = vercmp(evr1, r1 ? r1 : s1, evr2, r2 ? r2 : s2);
136   if (r)
137     return r;
138   if (r1 && r2)
139     {
140       if (s1 != ++r1 && s2 != ++r2)
141         r = vercmp(r1, s1, r2, s2);
142     }
143   return r;
144 }
145
146 // EOF