libxbps: two new functions to get the pkgver and arch components in a filename.

- xbps_binpkg_pkgver() returns a heap allocated string with the pkgver component.
- xbps_binpkg_arch() returns a heap allocated string with the architecture component.

A basename, full path or relative path is supported, i.e:

	/path/to/foo-1.0_1.x86_64.xbps
	../../foo/blah-0.1_1.x86_64.xbps
	baz-0.1_1.x86_64.xbps
This commit is contained in:
Juan RP 2014-09-05 20:59:00 +02:00
parent e2470f8697
commit 5863ec17fe
2 changed files with 116 additions and 1 deletions

View File

@ -1713,6 +1713,30 @@ char *xbps_pkgpattern_name(const char *pattern);
*/ */
const char *xbps_pkg_version(const char *pkg); const char *xbps_pkg_version(const char *pkg);
/**
* Gets the pkgname/version componentn of a binary package string,
* i.e <b>foo-2.0_1.<arch>.xbps</b>.
*
* @param[in] pkg Package string.
*
* @return A pointer to a malloc(ed) string with the pkgver component,
* NULL if it couldn't find the version component. The pointer should
* be free(3)d when it's no longer needed.
*/
char *xbps_binpkg_pkgver(const char *pkg);
/**
* Gets the architecture component of a binary package string,
* i.e <b><pkgver>.<arch>.xbps</b>.
*
* @param[in] pkg Package string.
*
* @return A pointer to a malloc(ed) string with the architecture component,
* NULL if it couldn't find the version component. The pointer should
* be free(3)d when it's no longer needed.
*/
char *xbps_binpkg_arch(const char *pkg);
/** /**
* Gets the package version of a package pattern string specified by * Gets the package version of a package pattern string specified by
* the \a pattern argument. * the \a pattern argument.

View File

@ -105,7 +105,98 @@ xbps_pkg_version(const char *pkg)
if (!valid) if (!valid)
return NULL; return NULL;
return p + 1; /* skip first '_' */ return p + 1; /* skip first '-' */
}
char *
xbps_binpkg_pkgver(const char *pkg)
{
const char *fname;
char *p, *res;
unsigned int i, idx = 0;
bool valid = false;
/* skip path if found, only interested in filename */
if ((fname = strrchr(pkg, '/')))
fname++;
else
fname = pkg;
/* get the version component first */
if ((p = strrchr(fname, '-')) == NULL)
return NULL;
for (i = 0; i < strlen(p); i++) {
if (p[i] == '_')
break;
if (isdigit((unsigned char)p[i]) && strchr(p, '_')) {
valid = true;
break;
}
}
if (!valid)
return NULL;
/*
* find the index until the architecture component:
* this assumes that revision contains 1 or 2 digits!
*/
for (i = 0; i < strlen(fname); i++) {
/* revision with 1 digit: _[digit]. */
if (fname[i] == '_' &&
isdigit((unsigned char)fname[i+1]) &&
fname[i+2] == '.') {
idx = i+2;
break;
}
/* revision with 2 digits: _[digit][digit]. */
if (fname[i] == '_' &&
isdigit((unsigned char)fname[i+1]) &&
isdigit((unsigned char)fname[i+2]) &&
fname[i+3] == '.') {
idx = i+3;
break;
}
}
if (!idx)
return NULL;
res = strdup(fname);
assert(res);
res[idx] = '\0';
return res;
}
char *
xbps_binpkg_arch(const char *pkg)
{
const char *p, *fname;
char *pkgver, *res;
if ((pkgver = xbps_binpkg_pkgver(pkg)) == NULL)
return NULL;
/* skip path if found, only interested in filename */
if ((fname = strrchr(pkg, '/')))
fname++;
else
fname = pkg;
p = fname + strlen(pkgver);
if (!p || p == '\0') {
free(pkgver);
return NULL;
}
if (*p == '.')
p++;
res = strdup(p);
assert(res);
free(pkgver);
res[strlen(res)-5] = '\0';
return res;
} }
const char * const char *