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