Subject: Ranges support for pkg_install
To: None <tech-pkg@NetBSD.org>
From: Thomas Klausner <wiz@NetBSD.org>
List: tech-pkg
Date: 05/27/2005 00:51:21
--uQr8t48UFsdbeI+V
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Hi!
The attached patch adds version number ranges support to the
pkg_install tools.
The initial consumer will be audit-packages (after the next branch)
and a few packages that already need it, but work around it, can
be converted to use it too.
The syntax is a direct extension of what we currently have:
"foo>=1.3<2.0" will match package foo, versions 1.3 (inclusive) to
2.0 (exclusive). Of course, > and <= also work, but the lower
bound has to come first.
Diff attached (with some related const poisoning).
Comments?
Thomas & Dillo
--uQr8t48UFsdbeI+V
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="pkg_install-ranges.diff"
Index: info/pkg_info.1
===================================================================
RCS file: /cvsroot/src/usr.sbin/pkg_install/info/pkg_info.1,v
retrieving revision 1.48
diff -u -r1.48 pkg_info.1
--- info/pkg_info.1 18 Apr 2005 12:28:46 -0000 1.48
+++ info/pkg_info.1 26 May 2005 22:24:02 -0000
@@ -17,7 +17,7 @@
.\"
.\" @(#)pkg_info.1
.\"
-.Dd February 10, 2005
+.Dd May 27, 2005
.Dt PKG_INFO 1
.Os
.Sh NAME
@@ -210,6 +210,15 @@
will match versions 1.3 and later of the
.Pa name
package.
+Additionally, ranges can be defined by giving a lower bound with
+\*[Gt] or \*[Ge] and an upper bound with \*[Lt] or \*[Le].
+The lower bound has to come first.
+For example,
+.Pa pkg_info -e 'name\*[Ge]1.3\*[Lt]2.0'
+will match versions 1.3 (inclusive) to 2.0 (exclusive)
+of package
+.Pa name .
+.Pp
The collating sequence of the various package version numbers is
unusual, but strives to be consistent.
The magic string
Index: lib/str.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/pkg_install/lib/str.c,v
retrieving revision 1.50
diff -u -r1.50 str.c
--- lib/str.c 29 Dec 2004 11:35:04 -0000 1.50
+++ lib/str.c 26 May 2005 22:24:02 -0000
@@ -163,7 +163,7 @@
/* locate the test in the tests array */
static int
-mktest(int *op, char *test)
+mktest(int *op, const char *test)
{
const test_t *tp;
@@ -188,12 +188,12 @@
* 'nb' encodes as 'netbsd version', which is used after all other tests
*/
static int
-mkcomponent(arr_t *ap, char *num)
+mkcomponent(arr_t *ap, const char *num)
{
static const char alphas[] = "abcdefghijklmnopqrstuvwxyz";
const test_t *modp;
int64_t n;
- char *cp;
+ const char *cp;
if (*num == 0) {
return 0;
@@ -232,7 +232,7 @@
/* make a version number string into an array of comparable 64bit ints */
static int
-mkversion(arr_t *ap, char *num)
+mkversion(arr_t *ap, const char *num)
{
(void) memset(ap, 0, sizeof(arr_t));
while (*num) {
@@ -286,7 +286,7 @@
* Compare two dewey decimal numbers
*/
static int
-deweycmp(char *lhs, int op, char *rhs)
+deweycmp(const char *lhs, int op, const char *rhs)
{
arr_t right;
arr_t left;
@@ -359,31 +359,59 @@
static int
dewey_match(const char *pattern, const char *pkg)
{
- char *cp;
- char *sep;
- char *ver;
- char name[MaxPathSize];
- int op;
- int n;
-
- if ((sep = strpbrk(pattern, "<>")) == NULL) {
- errx(EXIT_FAILURE, "dewey_match(): '<' or '>' expected in `%s'", pattern);
+ const char *version;
+ const char *sep, *sep2;
+ int op, op2;
+ int n;
+
+ /* compare names */
+ if ((version=strrchr(pkg, '-')) == NULL) {
+ warnx("Invalid package name `%s'", pkg);
+ return 0;
}
- (void) snprintf(name, sizeof(name), "%.*s", (int) (sep - pattern), pattern);
+ if ((sep = strpbrk(pattern, "<>")) == NULL)
+ errx(EXIT_FAILURE, "dewey_match: '<' or '>' expected in `%s'", pattern);
+ /* compare name lengths */
+ if ((sep-pattern != version-pkg) ||
+ strncmp(pkg, pattern, (size_t)(version-pkg)) != 0)
+ return 0;
+ version++;
+
+ /* extract comparison operator */
if ((n = mktest(&op, sep)) < 0) {
warnx("Bad comparison `%s'", sep);
return 0;
}
- ver = sep + n;
- n = (int) (sep - pattern);
- if ((cp = strrchr(pkg, '-')) != (char *) NULL) {
- if (strncmp(pkg, name, (size_t) (cp - pkg)) == 0 &&
- n == (int)(cp - pkg)) {
- if (deweycmp(cp + 1, op, ver)) {
- return 1;
+ /* skip operator */
+ sep += n;
+
+ /* if greater than, look for less than */
+ sep2 = NULL;
+ if (op == GT || op == GE) {
+ if ((sep2 = strchr(sep, '<')) != NULL) {
+ if ((n = mktest(&op2, sep2)) < 0) {
+ warnx("Bad comparison `%s'", sep2);
+ return 0;
}
+ /* compare upper limit */
+ if (!deweycmp(version, op2, sep2+n))
+ return 0;
}
}
+
+ /* compare only pattern / lower limit */
+ if (sep2) {
+ char ver[PKG_PATTERN_MAX];
+
+ strlcpy(ver, sep, MIN(sizeof(ver), sep2-sep+1));
+ if (deweycmp(version, op, ver))
+ return 1;
+ }
+ else {
+ if (deweycmp(version, op, sep))
+ return 1;
+ }
+
return 0;
}
Index: lib/version.h
===================================================================
RCS file: /cvsroot/src/usr.sbin/pkg_install/lib/version.h,v
retrieving revision 1.65
diff -u -r1.65 version.h
--- lib/version.h 18 Mar 2005 00:12:35 -0000 1.65
+++ lib/version.h 26 May 2005 22:24:02 -0000
@@ -33,6 +33,6 @@
#ifndef _INST_LIB_VERSION_H_
#define _INST_LIB_VERSION_H_
-#define PKGTOOLS_VERSION "20050318"
+#define PKGTOOLS_VERSION "20050527"
#endif /* _INST_LIB_VERSION_H_ */
--uQr8t48UFsdbeI+V--