libxbps: require an underscore in strings to detect correctly pkgname/version.

This commit is contained in:
Juan RP 2012-06-05 10:58:39 +02:00
parent 9441f9f14b
commit c37026d4c6
11 changed files with 159 additions and 130 deletions

9
NEWS
View File

@ -1,12 +1,17 @@
xbps-0.16 (???):
* Always require an underscore at package versions, if any provided
pkgver (i.e 'foo-1.0_1') does not contain an underscore the name/version
won't be detected for a string. That means that now any package can contain
any character in pkgname and version, and as bonus there's no need to
make some tricks to perform installation of exact package versions.
* xbps-bin(8): the 'install' target now can (re)install an exact package
version as specified on its arguments, i.e:
$ xbps-bin install foo=1.0
$ xbps-bin install foo-1.0_1
If that version is not available no other version will be installed.
The equal sign must be used to specify exact versions.
* xbps-repo(8): 'genindex' target is now able to remove binary packages
when a greater version exists on the index.

View File

@ -1,4 +1,4 @@
.Dd June 3, 2012
.Dd June 5, 2012
.Os Void GNU/Linux
.Dt xbps-bin 8
.Sh NAME
@ -154,26 +154,25 @@ Prints the name of the installed
.Em package(s)
matching the pattern on its file list. Multiple patterns can be specified
as arguments.
.It Sy install Ar pkgname(s) | Ar pkgpattern(s)
Install binary package(s) from repository pool by specifying
.Em pkgname(s)
or
.Em package pattern(s) .
.It Sy install Ar pattern Ar [patterns ...]
Install binary package(s) from repository pool by specifying a
.Em pattern .
Three different ways exist to install packages: by specifying just the
.Em package name ,
the best available version from repositories will be installed; by specifying a
.Em package pattern
with '>' '<' '>=' or '<='
.Em ( foo>=2.0 )
or by specifying an exact package version delimited
by the equal sign, i.e
.Em ( foo=1.0) .
The first repository matching the arguments will be used. The package(s) will be
or by specifying an exact package version, i.e
.Em ( foo-1.0_1) .
The first repository matching
.Em pattern
will be used. The package(s) will be
.Em downloaded
(if found in a remote repository),
.Em unpacked
and
.EM configured .
.Em configured .
The
.Em unpack
stage will execute the pre-install action on its INSTALL script, and unpack its files.
@ -206,13 +205,17 @@ to installed in the package database. The
keyword can be used to reconfigure all not configured packages. If
.Ql -f
option is used, the package will be reconfigured even if its state is already installed.
.It Sy remove Ar pkgname(s)
.It Sy remove Ar pkgname Ar [pkgnames ...]
Removes the installed package
.Em pkgname(s) .
Files not matching the original SHA256 hash will be preserved. If
.Ql -f
option is used, package files will be
.Em removed even if its SHA256 hash don't match .
If
.Ql -F
option is used, package will be removed even if there are
.Em installed reverse dependencies .
.It Sy remove-orphans
Removes package orphans. These packages were installed as dependencies and
currently there is not any package depending on it, directly or indirectly.
@ -240,11 +243,11 @@ Shows the reverse dependencies for
Reverse dependencies are packages that are currently depending in
.Em pkgname
directly.
.It Sy update Ar pkgname(s)
.It Sy update Ar pkgname Ar [pkgnames ...]
Updates
.Em pkgname(s)
to the most newer version available in repository pool. This can be used if only
.Em pkgname(s)
.Em pkgname
to the newest version available in repository pool. This can be used if only
.Em pkgname
need to be updated, unlike the
.Em dist-upgrade
target that will update all currently installed packages.
@ -287,7 +290,7 @@ XBPS master package database plist file.
.It Pa /var/cache/xbps
XBPS cache directory for downloaded binary packages.
.Sh EXAMPLES
Install a package by specifying a
Install best package version by specifying a
.Em pkgname :
.Pp
.Dl $ xbps-bin install foo
@ -297,12 +300,19 @@ Install a package by specifying a
.Pp
.Dl $ xbps-bin install \*qfoo>=3.0\*q
.Pp
Install an exact
.Em package version :
.Pp
.Dl $ xbps-bin install foo-1.0_1
.Pp
Install multiple packages by specifying
.Em pkgnames
and
.Em package patterns :
.Em package patterns
and
.Em exact package versions :
.Pp
.Dl $ xbps-bin install foo \*qblah<=4.0\*q baz-2.0 \*qblob>4.[0-9]\*q
.Dl $ xbps-bin install foo \*qblah<=4.0\*q baz-2.0_1 \*qblob>1.0<1.8\*q
.Pp
Find the package that owns the file
.Pa /bin/mount :
@ -326,7 +336,7 @@ and
.Em recursively
all packages that were installed automatically by it:
.Pp
.Dl $ xbps-bin -R remove bsdtar
.Dl $ xbps-bin -Ry remove bsdtar
.Pp
.Sh SEE ALSO
.Xr xbps-repo 8 ,

View File

@ -56,7 +56,7 @@
*/
#define XBPS_PKGINDEX_VERSION "1.5"
#define XBPS_API_VERSION "20120604-1"
#define XBPS_API_VERSION "20120605"
#define XBPS_VERSION "0.16"
/**

View File

@ -71,7 +71,6 @@ find_pkg_in_array(prop_array_t array,
*/
if (xbps_match_virtual_pkg_in_dict(obj, str, bypattern))
break;
} else if (bypattern) {
/*
* Check if package pattern matches the
@ -166,7 +165,7 @@ find_virtualpkg_user_in_conf(const char *vpkg, bool bypattern)
{
const struct xbps_handle *xhp;
const char *vpkgver, *pkg = NULL;
char *vpkgname = NULL;
char *vpkgname = NULL, *tmp;
size_t i, j, cnt;
xhp = xbps_handle_get();
@ -181,8 +180,16 @@ find_virtualpkg_user_in_conf(const char *vpkg, bool bypattern)
for (i = 0; i < cnt; i++) {
cfg_t *sec = cfg_getnsec(xhp->cfg, "virtual-package", i);
for (j = 0; j < cfg_size(sec, "targets"); j++) {
tmp = NULL;
vpkgver = cfg_getnstr(sec, "targets", j);
vpkgname = xbps_pkg_name(vpkgver);
if (strchr(vpkgver, '_') == NULL) {
tmp = xbps_xasprintf("%s_1", vpkgver);
assert(tmp != NULL);
vpkgname = xbps_pkg_name(tmp);
free(tmp);
} else {
vpkgname = xbps_pkg_name(vpkgver);
}
if (vpkgname == NULL)
break;
if (bypattern) {

View File

@ -63,15 +63,27 @@ xbps_match_any_virtualpkg_in_rundeps(prop_array_t rundeps,
prop_array_t provides)
{
const char *vpkgver, *pkgpattern;
char *tmp;
size_t i, x;
for (i = 0; i < prop_array_count(provides); i++) {
tmp = NULL;
prop_array_get_cstring_nocopy(provides, i, &vpkgver);
if (strchr(vpkgver, '_') == NULL) {
tmp = xbps_xasprintf("%s_1", vpkgver);
assert(tmp != NULL);
vpkgver = tmp;
}
for (x = 0; x < prop_array_count(rundeps); x++) {
prop_array_get_cstring_nocopy(rundeps, x, &pkgpattern);
if (xbps_pkgpattern_match(vpkgver, pkgpattern))
if (xbps_pkgpattern_match(vpkgver, pkgpattern)) {
if (tmp != NULL)
free(tmp);
return true;
}
}
if (tmp != NULL)
free(tmp);
}
return false;
}
@ -82,7 +94,7 @@ match_string_in_array(prop_array_t array, const char *str, int mode)
prop_object_iterator_t iter;
prop_object_t obj;
const char *pkgdep;
char *curpkgname;
char *curpkgname, *tmp;
bool found = false;
assert(prop_object_type(array) == PROP_TYPE_ARRAY);
@ -93,7 +105,7 @@ match_string_in_array(prop_array_t array, const char *str, int mode)
return false;
while ((obj = prop_object_iterator_next(iter))) {
assert(prop_object_type(obj) == PROP_TYPE_STRING);
tmp = NULL;
if (mode == 0) {
/* match by string */
if (prop_string_equals_cstring(obj, str)) {
@ -103,7 +115,14 @@ match_string_in_array(prop_array_t array, const char *str, int mode)
} else if (mode == 1) {
/* match by pkgname */
pkgdep = prop_string_cstring_nocopy(obj);
curpkgname = xbps_pkg_name(pkgdep);
if (strchr(pkgdep, '_') == NULL) {
tmp = xbps_xasprintf("%s_1", pkgdep);
assert(tmp != NULL);
curpkgname = xbps_pkg_name(tmp);
free(tmp);
} else {
curpkgname = xbps_pkg_name(pkgdep);
}
if (curpkgname == NULL)
break;
if (strcmp(curpkgname, str) == 0) {
@ -115,17 +134,36 @@ match_string_in_array(prop_array_t array, const char *str, int mode)
} else if (mode == 2) {
/* match pkgpattern against pkgdep */
pkgdep = prop_string_cstring_nocopy(obj);
if (strchr(pkgdep, '_') == NULL) {
tmp = xbps_xasprintf("%s_1", pkgdep);
assert(tmp != NULL);
pkgdep = tmp;
}
if (xbps_pkgpattern_match(pkgdep, str)) {
if (tmp != NULL)
free(tmp);
found = true;
break;
}
if (tmp != NULL)
free(tmp);
} else if (mode == 3) {
/* match pkgdep against pkgpattern */
pkgdep = prop_string_cstring_nocopy(obj);
if (strchr(pkgdep, '_') == NULL) {
tmp = xbps_xasprintf("%s_1", pkgdep);
assert(tmp != NULL);
pkgdep = tmp;
}
if (xbps_pkgpattern_match(str, pkgdep)) {
if (tmp != NULL)
free(tmp);
found = true;
break;
}
if (tmp != NULL)
free(tmp);
}
}
prop_object_iterator_release(iter);

View File

@ -241,8 +241,6 @@ xbps_transaction_install_pkg(const char *pkg, bool reinstall)
{
prop_dictionary_t pkgd;
pkg_state_t state;
size_t len, i;
char *pkgname, *pkgstr = NULL;
bool bypattern, best, exact;
int rv;
@ -250,7 +248,7 @@ xbps_transaction_install_pkg(const char *pkg, bool reinstall)
bypattern = true;
best = false;
exact = false;
} else if (strchr(pkg, '=')) {
} else if (xbps_pkg_name(pkg)) {
exact = true;
bypattern = false;
best = false;
@ -260,29 +258,7 @@ xbps_transaction_install_pkg(const char *pkg, bool reinstall)
best = true;
}
if (exact) {
/* find out pkgname */
pkgname = strdup(pkg);
assert(pkgname != NULL);
len = strcspn(pkg, "=");
for (i = 0; i < len; i++)
pkgname[i] = pkg[i];
pkgname[i] = '\0';
pkgd = xbps_pkgdb_get_pkgd(pkgname, false);
free(pkgname);
/* replace equal with an hyphen */
pkgstr = strdup(pkg);
for (i = 0; i < strlen(pkgstr); i++) {
if (pkgstr[i] == '=') {
pkgstr[i] = '-';
break;
}
}
} else {
pkgd = xbps_pkgdb_get_pkgd(pkg, bypattern);
}
if (pkgd != NULL) {
if ((pkgd = xbps_pkgdb_get_pkgd(pkg, bypattern)) != NULL) {
if (xbps_pkg_state_dictionary(pkgd, &state) != 0) {
prop_object_release(pkgd);
return EINVAL;
@ -293,11 +269,7 @@ xbps_transaction_install_pkg(const char *pkg, bool reinstall)
return EEXIST;
}
}
rv = transaction_find_pkg(pkgstr ? pkgstr : pkg, bypattern,
best, exact, TRANS_INSTALL);
if (pkgstr != NULL)
free(pkgstr);
rv = transaction_find_pkg(pkg, bypattern, best, exact, TRANS_INSTALL);
return rv;
}

View File

@ -102,67 +102,61 @@ xbps_check_is_installed_pkg_by_name(const char *pkgname)
assert(pkgname != NULL);
pkgd = xbps_find_virtualpkg_dict_installed(pkgname, false);
if (prop_object_type(pkgd) == PROP_TYPE_DICTIONARY) {
prop_object_release(pkgd);
return true;
}
if (((pkgd = xbps_find_pkg_dict_installed(pkgname, false)) == NULL) &&
((pkgd = xbps_find_virtualpkg_dict_installed(pkgname, false)) == NULL))
return false;
return false;
prop_object_release(pkgd);
return true;
}
const char *
xbps_pkg_version(const char *pkg)
{
const char *tmp;
const char *p;
assert(pkg != NULL);
/* Get the required version */
tmp = strrchr(pkg, '-');
if (tmp == NULL)
if ((p = strrchr(pkg, '-')) == NULL)
return NULL;
return tmp + 1; /* skip first '-' */
if (strrchr(p, '_') == NULL)
return NULL;
return p + 1; /* skip first '_' */
}
const char *
xbps_pkg_revision(const char *pkg)
{
const char *tmp;
const char *p;
assert(pkg != NULL);
/* Get the required revision */
tmp = strrchr(pkg, '_');
if (tmp == NULL)
if ((p = strrchr(pkg, '_')) == NULL)
return NULL;
return tmp + 1; /* skip first '_' */
return p + 1; /* skip first '_' */
}
char *
xbps_pkg_name(const char *pkg)
{
const char *tmp;
char *pkgname;
size_t len = 0;
const char *p;
char *buf;
size_t len;
assert(pkg != NULL);
/* Get package name */
tmp = strrchr(pkg, '-');
if (tmp == NULL)
if ((p = strrchr(pkg, '-')) == NULL)
return NULL;
len = strlen(pkg) - strlen(tmp) + 1;
pkgname = malloc(len);
if (pkgname == NULL)
if (strrchr(p, '_') == NULL)
return NULL;
strlcpy(pkgname, pkg, len);
len = strlen(pkg) - strlen(p) + 1;
buf = malloc(len);
assert(buf != NULL);
strlcpy(buf, pkg, len);
return pkgname;
return buf;
}
char *
@ -173,8 +167,7 @@ xbps_pkgpattern_name(const char *pkg)
assert(pkg != NULL);
res = strpbrk(pkg, "><*?[]");
if (res == NULL)
if ((res = strpbrk(pkg, "><*?[]")) == NULL)
return NULL;
len = strlen(pkg) - strlen(res) + 1;
@ -182,9 +175,7 @@ xbps_pkgpattern_name(const char *pkg)
len--;
pkgname = malloc(len);
if (pkgname == NULL)
return NULL;
assert(pkgname != NULL);
strlcpy(pkgname, pkg, len);
return pkgname;
@ -193,15 +184,9 @@ xbps_pkgpattern_name(const char *pkg)
const char *
xbps_pkgpattern_version(const char *pkg)
{
char *res;
assert(pkg != NULL);
res = strpbrk(pkg, "><*?[]");
if (res == NULL)
return NULL;
return res;
return strpbrk(pkg, "><*?[]");
}
static char *

View File

@ -38,21 +38,21 @@ static const char dictxml[] =
" <key>pkgname</key>\n"
" <string>afoo</string>\n"
" <key>version</key>\n"
" <string>1.1</string>\n"
" <string>1.1_1</string>\n"
" <key>pkgver</key>\n"
" <string>afoo-1.1</string>\n"
" <string>afoo-1.1_1</string>\n"
" <key>provides</key>\n"
" <array>\n"
" <string>virtualpkg-9999</string>\n"
" <string>virtualpkg-9999_1</string>\n"
" </array>\n"
" </dict>\n"
" <dict>\n"
" <key>pkgname</key>\n"
" <string>foo</string>\n"
" <key>version</key>\n"
" <string>2.0</string>\n"
" <string>2.0_1</string>\n"
" <key>pkgver</key>\n"
" <string>foo-2.0</string>\n"
" <string>foo-2.0_1</string>\n"
" </dict>\n"
" </array>\n"
"</dict>\n"
@ -105,7 +105,7 @@ ATF_TC_BODY(find_pkg_in_dict_by_pkgver_test, tc)
ATF_REQUIRE_EQ(prop_object_type(d), PROP_TYPE_DICTIONARY);
/* exact match by pkgver */
dr = xbps_find_pkg_in_dict_by_pkgver(d, "packages", "foo-2.0");
dr = xbps_find_pkg_in_dict_by_pkgver(d, "packages", "foo-2.0_1");
ATF_REQUIRE_EQ(prop_object_type(dr), PROP_TYPE_DICTIONARY);
}
@ -123,10 +123,15 @@ ATF_TC_BODY(find_virtualpkg_in_dict_by_pattern_test, tc)
ATF_REQUIRE_EQ(prop_object_type(d), PROP_TYPE_DICTIONARY);
/* match virtualpkg by pattern */
dr = xbps_find_virtualpkg_in_dict_by_pattern(d, "packages", "virtualpkg<=9999");
dr = xbps_find_virtualpkg_in_dict_by_pattern(d, "packages", "virtualpkg>=9999");
ATF_REQUIRE_EQ(prop_object_type(dr), PROP_TYPE_DICTIONARY);
prop_dictionary_get_cstring_nocopy(dr, "pkgver", &pkgver);
ATF_REQUIRE_STREQ(pkgver, "afoo-1.1");
ATF_REQUIRE_STREQ(pkgver, "afoo-1.1_1");
dr = xbps_find_virtualpkg_in_dict_by_pattern(d, "packages", "virtualpkg<=9999_1");
ATF_REQUIRE_EQ(prop_object_type(dr), PROP_TYPE_DICTIONARY);
prop_dictionary_get_cstring_nocopy(dr, "pkgver", &pkgver);
ATF_REQUIRE_STREQ(pkgver, "afoo-1.1_1");
}
ATF_TC(find_virtualpkg_in_dict_by_name_test);
@ -146,7 +151,7 @@ ATF_TC_BODY(find_virtualpkg_in_dict_by_name_test, tc)
dr = xbps_find_virtualpkg_in_dict_by_name(d, "packages", "virtualpkg");
ATF_REQUIRE_EQ(prop_object_type(dr), PROP_TYPE_DICTIONARY);
prop_dictionary_get_cstring_nocopy(dr, "pkgver", &pkgver);
ATF_REQUIRE_STREQ(pkgver, "afoo-1.1");
ATF_REQUIRE_STREQ(pkgver, "afoo-1.1_1");
}
ATF_TP_ADD_TCS(tp)

View File

@ -33,8 +33,8 @@ array_init(void)
a = prop_array_create();
ATF_REQUIRE(a != NULL);
prop_array_add_cstring_nocopy(a, "foo-2.0");
prop_array_add_cstring_nocopy(a, "blah-2.1");
prop_array_add_cstring_nocopy(a, "foo-2.0_1");
prop_array_add_cstring_nocopy(a, "blah-2.1_1");
return a;
}
@ -48,8 +48,8 @@ ATF_TC_HEAD(match_string_test, tc)
ATF_TC_BODY(match_string_test, tc)
{
prop_array_t a = array_init();
ATF_REQUIRE_EQ(xbps_match_string_in_array(a, "foo-2.0"), true);
ATF_REQUIRE_EQ(xbps_match_string_in_array(a, "foo-2.1"), false);
ATF_REQUIRE_EQ(xbps_match_string_in_array(a, "foo-2.0_1"), true);
ATF_REQUIRE_EQ(xbps_match_string_in_array(a, "foo-2.1_1"), false);
}
ATF_TC(match_pkgname_test);
@ -87,7 +87,7 @@ ATF_TC_HEAD(match_pkgdep_test, tc)
ATF_TC_BODY(match_pkgdep_test, tc)
{
prop_array_t a = array_init();
ATF_REQUIRE_EQ(xbps_match_pkgdep_in_array(a, "foo-2.0"), true);
ATF_REQUIRE_EQ(xbps_match_pkgdep_in_array(a, "foo-2.0_1"), true);
}
ATF_TP_ADD_TCS(tp)

View File

@ -37,17 +37,17 @@ static const char dictxml[] =
" <key>pkgname</key>\n"
" <string>afoo</string>\n"
" <key>version</key>\n"
" <string>1.1</string>\n"
" <string>1.1_1</string>\n"
" <key>pkgver</key>\n"
" <string>afoo-1.1</string>\n"
" <string>afoo-1.1_1</string>\n"
" </dict>\n"
" <dict>\n"
" <key>pkgname</key>\n"
" <string>foo</string>\n"
" <key>version</key>\n"
" <string>2.0</string>\n"
" <string>2.0_1</string>\n"
" <key>pkgver</key>\n"
" <string>foo-2.0</string>\n"
" <string>foo-2.0_1</string>\n"
" </dict>\n"
" </array>\n"
"</dict>\n"
@ -64,9 +64,9 @@ static const char dictxml2[] =
" <key>pkgname</key>\n"
" <string>foo</string>\n"
" <key>version</key>\n"
" <string>2.0</string>\n"
" <string>2.0_1</string>\n"
" <key>pkgver</key>\n"
" <string>foo-2.0</string>\n"
" <string>foo-2.0_1</string>\n"
" </dict>\n"
" </array>\n"
"</dict>\n"
@ -77,8 +77,8 @@ static const char axml[] =
"<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
"<plist version=\"1.0\">\n"
"<array>\n"
" <string>foo-1.0</string>\n"
" <string>blah-2.0</string>\n"
" <string>foo-1.0_1</string>\n"
" <string>blah-2.0_1</string>\n"
"</array>\n"
"</plist>\n";
@ -87,7 +87,7 @@ static const char axml2[] =
"<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
"<plist version=\"1.0\">\n"
"<array>\n"
" <string>blah-2.0</string>\n"
" <string>blah-2.0_1</string>\n"
"</array>\n"
"</plist>\n";
@ -156,7 +156,7 @@ ATF_TC_BODY(remove_pkg_from_array_by_pkgver_test, tc)
ATF_REQUIRE_EQ(prop_object_type(d2), PROP_TYPE_DICTIONARY);
a = prop_dictionary_get(d, "packages");
ATF_REQUIRE_EQ(xbps_remove_pkg_from_array_by_pkgver(a, "afoo-1.1", NULL), true);
ATF_REQUIRE_EQ(xbps_remove_pkg_from_array_by_pkgver(a, "afoo-1.1_1", NULL), true);
ATF_REQUIRE_EQ(prop_dictionary_equals(d, d2), true);
}
@ -177,7 +177,7 @@ ATF_TC_BODY(remove_string_from_array_test, tc)
a2 = prop_array_internalize(axml2);
ATF_REQUIRE_EQ(prop_object_type(a2), PROP_TYPE_ARRAY);
ATF_REQUIRE_EQ(xbps_remove_string_from_array(a, "foo-1.0"), true);
ATF_REQUIRE_EQ(xbps_remove_string_from_array(a, "foo-1.0_1"), true);
ATF_REQUIRE_EQ(prop_array_equals(a, a2), true);
}

View File

@ -36,16 +36,23 @@ ATF_TC_HEAD(util_test, tc)
ATF_TC_BODY(util_test, tc)
{
ATF_REQUIRE_STREQ(xbps_pkg_name("font-adobe-100dpi-7.8"), "font-adobe-100dpi");
ATF_CHECK_EQ(xbps_pkg_name("font-adobe-100dpi-7.8"), NULL);
ATF_CHECK_EQ(xbps_pkg_version("font-adobe-100dpi"), NULL);
ATF_CHECK_EQ(xbps_pkg_version("font-adobe-100dpi-7.8"), NULL);
ATF_REQUIRE_STREQ(xbps_pkg_name("font-adobe-100dpi-7.8_2"), "font-adobe-100dpi");
ATF_REQUIRE_STREQ(xbps_pkg_name("systemd-43_1"), "systemd");
ATF_REQUIRE_STREQ(xbps_pkg_name("font-adobe-100dpi-1.8_blah"), "font-adobe-100dpi");
ATF_REQUIRE_STREQ(xbps_pkg_version("font-adobe-100dpi-7.8_2"), "7.8_2");
ATF_REQUIRE_STREQ(xbps_pkg_version("font-adobe-100dpi-1.8_blah"), "1.8_blah");
ATF_REQUIRE_STREQ(xbps_pkg_revision("systemd-43_1_0"), "0");
ATF_REQUIRE_STREQ(xbps_pkg_revision("systemd_21-43_0"), "0");
ATF_REQUIRE_STREQ(xbps_pkgpattern_name("systemd>=43"), "systemd");
ATF_REQUIRE_STREQ(xbps_pkgpattern_name("systemd>=43"), "systemd");
ATF_REQUIRE_STREQ(xbps_pkgpattern_name("systemd>43"), "systemd");
ATF_REQUIRE_STREQ(xbps_pkgpattern_name("systemd<43"), "systemd");
ATF_REQUIRE_STREQ(xbps_pkgpattern_name("systemd<=43"), "systemd");
ATF_REQUIRE_STREQ(xbps_pkgpattern_name("systemd-[0-9]*"), "systemd");
ATF_REQUIRE_STREQ(xbps_pkgpattern_name("systemd>4[3-9]?"), "systemd");
ATF_REQUIRE_STREQ(xbps_pkgpattern_name("systemd<4_1?"), "systemd");
}
ATF_TP_ADD_TCS(tp)