| @@ -1,319 +1,319 @@ | | | @@ -1,319 +1,319 @@ |
1 | /* $NetBSD: dewey.c,v 1.12 2022/07/30 08:41:25 rillig Exp $ */ | | 1 | /* $NetBSD: dewey.c,v 1.13 2022/07/30 08:53:42 rillig Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2002 Alistair G. Crooks. All rights reserved. | | 4 | * Copyright (c) 2002 Alistair G. Crooks. All rights reserved. |
5 | * | | 5 | * |
6 | * Redistribution and use in source and binary forms, with or without | | 6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions | | 7 | * modification, are permitted provided that the following conditions |
8 | * are met: | | 8 | * are met: |
9 | * 1. Redistributions of source code must retain the above copyright | | 9 | * 1. Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. | | 10 | * notice, this list of conditions and the following disclaimer. |
11 | * 2. Redistributions in binary form must reproduce the above copyright | | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the | | 12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. | | 13 | * documentation and/or other materials provided with the distribution. |
14 | * 3. The name of the author may not be used to endorse or promote | | 14 | * 3. The name of the author may not be used to endorse or promote |
15 | * products derived from this software without specific prior written | | 15 | * products derived from this software without specific prior written |
16 | * permission. | | 16 | * permission. |
17 | * | | 17 | * |
18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS | | 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS |
19 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | | 19 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | | 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
22 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 22 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE | | 23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
24 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 24 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | | 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | | 26 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | | 27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | */ | | 29 | */ |
30 | | | 30 | |
31 | #if HAVE_CONFIG_H | | 31 | #if HAVE_CONFIG_H |
32 | #include "config.h" | | 32 | #include "config.h" |
33 | #endif | | 33 | #endif |
34 | #include <nbcompat.h> | | 34 | #include <nbcompat.h> |
35 | | | 35 | |
36 | #if HAVE_CTYPE_H | | 36 | #if HAVE_CTYPE_H |
37 | #include <ctype.h> | | 37 | #include <ctype.h> |
38 | #endif | | 38 | #endif |
39 | #if HAVE_STDLIB_H | | 39 | #if HAVE_STDLIB_H |
40 | #include <stdlib.h> | | 40 | #include <stdlib.h> |
41 | #endif | | 41 | #endif |
42 | | | 42 | |
43 | #include "defs.h" | | 43 | #include "defs.h" |
44 | #include "dewey.h" | | 44 | #include "dewey.h" |
45 | | | 45 | |
46 | #define PKG_PATTERN_MAX 1024 | | 46 | #define PKG_PATTERN_MAX 1024 |
47 | | | 47 | |
48 | /* do not modify these values, or things will NOT work */ | | 48 | /* do not modify these values, or things will NOT work */ |
49 | enum { | | 49 | enum { |
50 | Alpha = -3, | | 50 | Alpha = -3, |
51 | Beta = -2, | | 51 | Beta = -2, |
52 | RC = -1, | | 52 | RC = -1, |
53 | Dot = 0, | | 53 | Dot = 0, |
54 | Patch = 1 | | 54 | Patch = 1 |
55 | }; | | 55 | }; |
56 | | | 56 | |
57 | /* this struct defines a version number */ | | 57 | /* this struct defines a version number */ |
58 | typedef struct arr_t { | | 58 | typedef struct arr_t { |
59 | unsigned c; /* # of version numbers */ | | 59 | unsigned c; /* # of version numbers */ |
60 | unsigned size; /* size of array */ | | 60 | unsigned size; /* size of array */ |
61 | int *v; /* array of decimal numbers */ | | 61 | int *v; /* array of decimal numbers */ |
62 | int netbsd; /* any "nb" suffix */ | | 62 | int netbsd; /* any "nb" suffix */ |
63 | } arr_t; | | 63 | } arr_t; |
64 | | | 64 | |
65 | /* this struct describes a test */ | | 65 | /* this struct describes a test */ |
66 | typedef struct test_t { | | 66 | typedef struct test_t { |
67 | const char *s; /* string representation */ | | 67 | const char *s; /* string representation */ |
68 | unsigned len; /* length of string */ | | 68 | unsigned len; /* length of string */ |
69 | int t; /* enumerated type of test */ | | 69 | int t; /* enumerated type of test */ |
70 | } test_t; | | 70 | } test_t; |
71 | | | 71 | |
72 | | | 72 | |
73 | /* the tests that are recognised. */ | | 73 | /* the tests that are recognised. */ |
74 | const test_t tests[] = { | | 74 | const test_t tests[] = { |
75 | { "<=", 2, DEWEY_LE }, | | 75 | { "<=", 2, DEWEY_LE }, |
76 | { "<", 1, DEWEY_LT }, | | 76 | { "<", 1, DEWEY_LT }, |
77 | { ">=", 2, DEWEY_GE }, | | 77 | { ">=", 2, DEWEY_GE }, |
78 | { ">", 1, DEWEY_GT }, | | 78 | { ">", 1, DEWEY_GT }, |
79 | { "==", 2, DEWEY_EQ }, | | 79 | { "==", 2, DEWEY_EQ }, |
80 | { "!=", 2, DEWEY_NE }, | | 80 | { "!=", 2, DEWEY_NE }, |
81 | { NULL, 0, 0 } | | 81 | { NULL, 0, 0 } |
82 | }; | | 82 | }; |
83 | | | 83 | |
84 | const test_t modifiers[] = { | | 84 | const test_t modifiers[] = { |
85 | { "alpha", 5, Alpha }, | | 85 | { "alpha", 5, Alpha }, |
86 | { "beta", 4, Beta }, | | 86 | { "beta", 4, Beta }, |
87 | { "pre", 3, RC }, | | 87 | { "pre", 3, RC }, |
88 | { "rc", 2, RC }, | | 88 | { "rc", 2, RC }, |
89 | { "pl", 2, Dot }, | | 89 | { "pl", 2, Dot }, |
90 | { "_", 1, Dot }, | | 90 | { "_", 1, Dot }, |
91 | { ".", 1, Dot }, | | 91 | { ".", 1, Dot }, |
92 | { NULL, 0, 0 } | | 92 | { NULL, 0, 0 } |
93 | }; | | 93 | }; |
94 | | | 94 | |
95 | | | 95 | |
96 | | | 96 | |
97 | /* locate the test in the tests array */ | | 97 | /* locate the test in the tests array */ |
98 | int | | 98 | int |
99 | dewey_mktest(int *op, const char *test) | | 99 | dewey_mktest(int *op, const char *test) |
100 | { | | 100 | { |
101 | const test_t *tp; | | 101 | const test_t *tp; |
102 | | | 102 | |
103 | for (tp = tests ; tp->s ; tp++) { | | 103 | for (tp = tests ; tp->s ; tp++) { |
104 | if (strncasecmp(test, tp->s, tp->len) == 0) { | | 104 | if (strncasecmp(test, tp->s, tp->len) == 0) { |
105 | *op = tp->t; | | 105 | *op = tp->t; |
106 | return tp->len; | | 106 | return tp->len; |
107 | } | | 107 | } |
108 | } | | 108 | } |
109 | return -1; | | 109 | return -1; |
110 | } | | 110 | } |
111 | | | 111 | |
112 | /* | | 112 | /* |
113 | * make a component of a version number. | | 113 | * make a component of a version number. |
114 | * '.' encodes as Dot which is '0' | | 114 | * '.' encodes as Dot which is '0' |
115 | * '_' encodes as 'patch level', or 'Dot', which is 0. | | 115 | * '_' encodes as 'patch level', or 'Dot', which is 0. |
116 | * 'pl' encodes as 'patch level', or 'Dot', which is 0. | | 116 | * 'pl' encodes as 'patch level', or 'Dot', which is 0. |
117 | * 'alpha' encodes as 'alpha version', or Alpha, which is -3. | | 117 | * 'alpha' encodes as 'alpha version', or Alpha, which is -3. |
118 | * 'beta' encodes as 'beta version', or Beta, which is -2. | | 118 | * 'beta' encodes as 'beta version', or Beta, which is -2. |
119 | * 'rc' encodes as 'release candidate', or RC, which is -1. | | 119 | * 'rc' encodes as 'release candidate', or RC, which is -1. |
120 | * 'nb' encodes as 'netbsd version', which is used after all other tests | | 120 | * 'nb' encodes as 'netbsd version', which is used after all other tests |
121 | */ | | 121 | */ |
122 | static int | | 122 | static int |
123 | mkcomponent(arr_t *ap, const char *num) | | 123 | mkcomponent(arr_t *ap, const char *num) |
124 | { | | 124 | { |
125 | static const char alphas[] = "abcdefghijklmnopqrstuvwxyz"; | | 125 | static const char alphas[] = "abcdefghijklmnopqrstuvwxyz"; |
126 | const test_t *modp; | | 126 | const test_t *modp; |
127 | int n; | | 127 | int n; |
128 | const char *cp; | | 128 | const char *cp; |
129 | | | 129 | |
130 | if (ap->c == ap->size) { | | 130 | if (ap->c == ap->size) { |
131 | if (ap->size == 0) { | | 131 | if (ap->size == 0) { |
132 | ap->size = 62; | | 132 | ap->size = 62; |
133 | if ((ap->v = malloc(ap->size * sizeof(int))) == NULL) | | 133 | if ((ap->v = malloc(ap->size * sizeof(int))) == NULL) |
134 | err(EXIT_FAILURE, "mkver malloc failed"); | | 134 | err(EXIT_FAILURE, "mkver malloc failed"); |
135 | } else { | | 135 | } else { |
136 | ap->size *= 2; | | 136 | ap->size *= 2; |
137 | if ((ap->v = realloc(ap->v, ap->size * sizeof(int))) | | 137 | if ((ap->v = realloc(ap->v, ap->size * sizeof(int))) |
138 | == NULL) | | 138 | == NULL) |
139 | err(EXIT_FAILURE, "mkver realloc failed"); | | 139 | err(EXIT_FAILURE, "mkver realloc failed"); |
140 | } | | 140 | } |
141 | } | | 141 | } |
142 | if (isdigit((unsigned char)*num)) { | | 142 | if (isdigit((unsigned char)*num)) { |
143 | for (cp = num, n = 0 ; isdigit((unsigned char)*num) ; num++) { | | 143 | for (cp = num, n = 0 ; isdigit((unsigned char)*num) ; num++) { |
144 | n = (n * 10) + (*num - '0'); | | 144 | n = (n * 10) + (*num - '0'); |
145 | } | | 145 | } |
146 | ap->v[ap->c++] = n; | | 146 | ap->v[ap->c++] = n; |
147 | return (int)(num - cp); | | 147 | return (int)(num - cp); |
148 | } | | 148 | } |
149 | for (modp = modifiers ; modp->s ; modp++) { | | 149 | for (modp = modifiers ; modp->s ; modp++) { |
150 | if (strncasecmp(num, modp->s, modp->len) == 0) { | | 150 | if (strncasecmp(num, modp->s, modp->len) == 0) { |
151 | ap->v[ap->c++] = modp->t; | | 151 | ap->v[ap->c++] = modp->t; |
152 | return modp->len; | | 152 | return modp->len; |
153 | } | | 153 | } |
154 | } | | 154 | } |
155 | if (strncasecmp(num, "nb", 2) == 0) { | | 155 | if (strncasecmp(num, "nb", 2) == 0) { |
156 | for (cp = num, num += 2, n = 0 ; isdigit((unsigned char)*num) ; num++) { | | 156 | for (cp = num, num += 2, n = 0 ; isdigit((unsigned char)*num) ; num++) { |
157 | n = (n * 10) + (*num - '0'); | | 157 | n = (n * 10) + (*num - '0'); |
158 | } | | 158 | } |
159 | ap->netbsd = n; | | 159 | ap->netbsd = n; |
160 | return (int)(num - cp); | | 160 | return (int)(num - cp); |
161 | } | | 161 | } |
162 | if (isalpha((unsigned char)*num)) { | | 162 | if (isalpha((unsigned char)*num)) { |
163 | ap->v[ap->c++] = Dot; | | 163 | ap->v[ap->c++] = Dot; |
164 | cp = strchr(alphas, tolower((unsigned char)*num)); | | 164 | cp = strchr(alphas, tolower((unsigned char)*num)); |
165 | if (ap->c == ap->size) { | | 165 | if (ap->c == ap->size) { |
166 | ap->size *= 2; | | 166 | ap->size *= 2; |
167 | if ((ap->v = realloc(ap->v, ap->size * sizeof(int))) == NULL) | | 167 | if ((ap->v = realloc(ap->v, ap->size * sizeof(int))) == NULL) |
168 | err(EXIT_FAILURE, "mkver realloc failed"); | | 168 | err(EXIT_FAILURE, "mkver realloc failed"); |
169 | } | | 169 | } |
170 | ap->v[ap->c++] = (int)(cp - alphas) + 1; | | 170 | ap->v[ap->c++] = (int)(cp - alphas) + 1; |
171 | return 1; | | 171 | return 1; |
172 | } | | 172 | } |
173 | return 1; | | 173 | return 1; |
174 | } | | 174 | } |
175 | | | 175 | |
176 | /* make a version number string into an array of comparable ints */ | | 176 | /* make a version number string into an array of comparable ints */ |
177 | static int | | 177 | static int |
178 | mkversion(arr_t *ap, const char *num) | | 178 | mkversion(arr_t *ap, const char *num) |
179 | { | | 179 | { |
180 | ap->c = 0; | | 180 | ap->c = 0; |
181 | ap->size = 0; | | 181 | ap->size = 0; |
182 | ap->v = NULL; | | 182 | ap->v = NULL; |
183 | ap->netbsd = 0; | | 183 | ap->netbsd = 0; |
184 | | | 184 | |
185 | while (*num) { | | 185 | while (*num) { |
186 | num += mkcomponent(ap, num); | | 186 | num += mkcomponent(ap, num); |
187 | } | | 187 | } |
188 | return 1; | | 188 | return 1; |
189 | } | | 189 | } |
190 | | | 190 | |
191 | static void | | 191 | static void |
192 | freeversion(arr_t *ap) | | 192 | freeversion(arr_t *ap) |
193 | { | | 193 | { |
194 | free(ap->v); | | 194 | free(ap->v); |
195 | ap->v = NULL; | | 195 | ap->v = NULL; |
196 | ap->c = 0; | | 196 | ap->c = 0; |
197 | ap->size = 0; | | 197 | ap->size = 0; |
198 | } | | 198 | } |
199 | | | 199 | |
200 | #define DIGIT(v, c, n) (((n) < (c)) ? v[n] : 0) | | 200 | #define DIGIT(v, c, n) (((n) < (c)) ? v[n] : 0) |
201 | | | 201 | |
202 | /* compare the result against the test we were expecting */ | | 202 | /* compare the result against the test we were expecting */ |
203 | static int | | 203 | static int |
204 | result(int cmp, int tst) | | 204 | result(int cmp, int tst) |
205 | { | | 205 | { |
206 | switch(tst) { | | 206 | switch(tst) { |
207 | case DEWEY_LT: | | 207 | case DEWEY_LT: |
208 | return cmp < 0; | | 208 | return cmp < 0; |
209 | case DEWEY_LE: | | 209 | case DEWEY_LE: |
210 | return cmp <= 0; | | 210 | return cmp <= 0; |
211 | case DEWEY_GT: | | 211 | case DEWEY_GT: |
212 | return cmp > 0; | | 212 | return cmp > 0; |
213 | case DEWEY_GE: | | 213 | case DEWEY_GE: |
214 | return cmp >= 0; | | 214 | return cmp >= 0; |
215 | case DEWEY_EQ: | | 215 | case DEWEY_EQ: |
216 | return cmp == 0; | | 216 | return cmp == 0; |
217 | case DEWEY_NE: | | 217 | case DEWEY_NE: |
218 | return cmp != 0; | | 218 | return cmp != 0; |
219 | default: | | 219 | default: |
220 | return 0; | | 220 | return 0; |
221 | } | | 221 | } |
222 | } | | 222 | } |
223 | | | 223 | |
224 | /* do the test on the 2 vectors */ | | 224 | /* do the test on the 2 vectors */ |
225 | static int | | 225 | static int |
226 | vtest(arr_t *lhs, int tst, arr_t *rhs) | | 226 | vtest(arr_t *lhs, int tst, arr_t *rhs) |
227 | { | | 227 | { |
228 | int cmp; | | 228 | int cmp; |
229 | unsigned int c, i; | | 229 | unsigned int c, i; |
230 | | | 230 | |
231 | for (i = 0, c = MAX(lhs->c, rhs->c) ; i < c ; i++) { | | 231 | for (i = 0, c = MAX(lhs->c, rhs->c) ; i < c ; i++) { |
232 | if ((cmp = DIGIT(lhs->v, lhs->c, i) - DIGIT(rhs->v, rhs->c, i)) != 0) { | | 232 | if ((cmp = DIGIT(lhs->v, lhs->c, i) - DIGIT(rhs->v, rhs->c, i)) != 0) { |
233 | return result(cmp, tst); | | 233 | return result(cmp, tst); |
234 | } | | 234 | } |
235 | } | | 235 | } |
236 | return result(lhs->netbsd - rhs->netbsd, tst); | | 236 | return result(lhs->netbsd - rhs->netbsd, tst); |
237 | } | | 237 | } |
238 | | | 238 | |
239 | /* | | 239 | /* |
240 | * Compare two dewey decimal numbers | | 240 | * Compare two dewey decimal numbers |
241 | */ | | 241 | */ |
242 | int | | 242 | int |
243 | dewey_cmp(const char *lhs, int op, const char *rhs) | | 243 | dewey_cmp(const char *lhs, int op, const char *rhs) |
244 | { | | 244 | { |
245 | arr_t right; | | 245 | arr_t right; |
246 | arr_t left; | | 246 | arr_t left; |
247 | int retval; | | 247 | int retval; |
248 | | | 248 | |
249 | if (!mkversion(&left, lhs)) | | 249 | if (!mkversion(&left, lhs)) |
250 | return 0; | | 250 | return 0; |
251 | if (!mkversion(&right, rhs)) { | | 251 | if (!mkversion(&right, rhs)) { |
252 | freeversion(&left); | | 252 | freeversion(&left); |
253 | return 0; | | 253 | return 0; |
254 | } | | 254 | } |
255 | retval = vtest(&left, op, &right); | | 255 | retval = vtest(&left, op, &right); |
256 | freeversion(&left); | | 256 | freeversion(&left); |
257 | freeversion(&right); | | 257 | freeversion(&right); |
258 | return retval; | | 258 | return retval; |
259 | } | | 259 | } |
260 | | | 260 | |
261 | /* | | 261 | /* |
262 | * Perform dewey match on "pkg" against "pattern". | | 262 | * Perform dewey match on "pkg" against "pattern". |
263 | * Return 1 on match, 0 on non-match, -1 on error. | | 263 | * Return 1 on match, 0 on non-match, -1 on error. |
264 | */ | | 264 | */ |
265 | int | | 265 | int |
266 | dewey_match(const char *pattern, const char *pkg) | | 266 | dewey_match(const char *pattern, const char *pkg) |
267 | { | | 267 | { |
268 | const char *version; | | 268 | const char *version; |
269 | const char *sep, *sep2; | | 269 | const char *sep, *sep2; |
270 | int op, op2; | | 270 | int op, op2; |
271 | int n; | | 271 | int n; |
272 | | | 272 | |
273 | /* compare names */ | | 273 | /* compare names */ |
274 | if ((version=strrchr(pkg, '-')) == NULL) { | | 274 | if ((version=strrchr(pkg, '-')) == NULL) { |
275 | return 0; | | 275 | return 0; |
276 | } | | 276 | } |
277 | if ((sep = strpbrk(pattern, "<>")) == NULL) | | 277 | if ((sep = strpbrk(pattern, "<>")) == NULL) |
278 | return -1; | | 278 | return -1; |
279 | /* compare name lengths */ | | 279 | /* compare name lengths */ |
280 | if ((sep-pattern != version-pkg) || | | 280 | if ((sep-pattern != version-pkg) || |
281 | strncmp(pkg, pattern, (size_t)(version-pkg)) != 0) | | 281 | strncmp(pkg, pattern, (size_t)(version-pkg)) != 0) |
282 | return 0; | | 282 | return 0; |
283 | version++; | | 283 | version++; |
284 | | | 284 | |
285 | /* extract comparison operator */ | | 285 | /* extract comparison operator */ |
286 | if ((n = dewey_mktest(&op, sep)) < 0) { | | 286 | if ((n = dewey_mktest(&op, sep)) < 0) { |
287 | return 0; | | 287 | return 0; |
288 | } | | 288 | } |
289 | /* skip operator */ | | 289 | /* skip operator */ |
290 | sep += n; | | 290 | sep += n; |
291 | | | 291 | |
292 | /* if greater than, look for less than */ | | 292 | /* if greater than, look for less than */ |
293 | sep2 = NULL; | | 293 | sep2 = NULL; |
294 | if (op == DEWEY_GT || op == DEWEY_GE) { | | 294 | if (op == DEWEY_GT || op == DEWEY_GE) { |
295 | if ((sep2 = strchr(sep, '<')) != NULL) { | | 295 | if ((sep2 = strchr(sep, '<')) != NULL) { |
296 | if ((n = dewey_mktest(&op2, sep2)) < 0) { | | 296 | if ((n = dewey_mktest(&op2, sep2)) < 0) { |
297 | return 0; | | 297 | return 0; |
298 | } | | 298 | } |
299 | /* compare upper limit */ | | 299 | /* compare upper limit */ |
300 | if (!dewey_cmp(version, op2, sep2+n)) | | 300 | if (!dewey_cmp(version, op2, sep2+n)) |
301 | return 0; | | 301 | return 0; |
302 | } | | 302 | } |
303 | } | | 303 | } |
304 | | | 304 | |
305 | /* compare only pattern / lower limit */ | | 305 | /* compare only pattern / lower limit */ |
306 | if (sep2) { | | 306 | if (sep2) { |
307 | char ver[PKG_PATTERN_MAX]; | | 307 | char ver[PKG_PATTERN_MAX]; |
308 | | | 308 | |
309 | strlcpy(ver, sep, MIN((ssize_t)sizeof(ver), sep2-sep+1)); | | 309 | strlcpy(ver, sep, MIN((ssize_t)sizeof(ver), sep2-sep+1)); |
310 | if (dewey_cmp(version, op, ver)) | | 310 | if (dewey_cmp(version, op, ver)) |
311 | return 1; | | 311 | return 1; |
312 | } | | 312 | } |
313 | else { | | 313 | else { |
314 | if (dewey_cmp(version, op, sep)) | | 314 | if (dewey_cmp(version, op, sep)) |
315 | return 1; | | 315 | return 1; |
316 | } | | 316 | } |
317 | | | 317 | |
318 | return 0; | | 318 | return 0; |
319 | } | | 319 | } |