Sat Jul 30 08:53:42 2022 UTC ()
pkg_install: use tabs for indentation, not spaces


(rillig)
diff -r1.12 -r1.13 pkgsrc/pkgtools/pkg_install/files/lib/dewey.c

cvs diff -r1.12 -r1.13 pkgsrc/pkgtools/pkg_install/files/lib/dewey.c (switch to unified diff)

--- pkgsrc/pkgtools/pkg_install/files/lib/dewey.c 2022/07/30 08:41:25 1.12
+++ pkgsrc/pkgtools/pkg_install/files/lib/dewey.c 2022/07/30 08:53:42 1.13
@@ -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 */
49enum { 49enum {
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 */
58typedef struct arr_t { 58typedef 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 */
66typedef struct test_t { 66typedef 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. */
74const test_t tests[] = { 74const 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
84const test_t modifiers[] = { 84const 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 */
98int 98int
99dewey_mktest(int *op, const char *test) 99dewey_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 */
122static int 122static int
123mkcomponent(arr_t *ap, const char *num) 123mkcomponent(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 */
177static int 177static int
178mkversion(arr_t *ap, const char *num) 178mkversion(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
191static void 191static void
192freeversion(arr_t *ap) 192freeversion(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 */
203static int 203static int
204result(int cmp, int tst) 204result(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 */
225static int 225static int
226vtest(arr_t *lhs, int tst, arr_t *rhs) 226vtest(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 */
242int 242int
243dewey_cmp(const char *lhs, int op, const char *rhs) 243dewey_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 */
265int 265int
266dewey_match(const char *pattern, const char *pkg) 266dewey_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}