aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPer Øyvind Karlsen <peroyvind@mandriva.org>2010-10-12 23:34:33 +0000
committerPer Øyvind Karlsen <peroyvind@mandriva.org>2010-10-12 23:34:33 +0000
commitce335e84938eeab479a88bf46478d082eff2de3b (patch)
tree0665a0b2eec95ef8a65fc91d7075232a080059f9
parent16006ce8387889e3be3159b4f69dccd2c164732f (diff)
downloadperl-URPM-ce335e84938eeab479a88bf46478d082eff2de3b.tar
perl-URPM-ce335e84938eeab479a88bf46478d082eff2de3b.tar.gz
perl-URPM-ce335e84938eeab479a88bf46478d082eff2de3b.tar.bz2
perl-URPM-ce335e84938eeab479a88bf46478d082eff2de3b.tar.xz
perl-URPM-ce335e84938eeab479a88bf46478d082eff2de3b.zip
* add support for fetching disttag & distepoch with get_fullname_parts()
* refactorize get_fullname_parts() and friends using it
-rw-r--r--URPM.xs372
1 files changed, 173 insertions, 199 deletions
diff --git a/URPM.xs b/URPM.xs
index 43b0e4a..87f687a 100644
--- a/URPM.xs
+++ b/URPM.xs
@@ -120,6 +120,25 @@ int rpmError_callback() {
static int rpm_codeset_is_utf8 = 0;
+static struct s_backup {
+ char *ptr;
+ char chr;
+} char_backups[32];
+
+static int BI = 0;
+
+static void
+backup_char(char *c) {
+ char_backups[BI].chr = *c,
+ *(char_backups[BI++].ptr = &(*c)) = 0; /* mark end of string to enable searching backwards */
+}
+
+static void
+restore_chars() {
+ for(; BI > 0; char_backups[BI].ptr = NULL)
+ BI--, *char_backups[BI].ptr = char_backups[BI].chr;
+}
+
static SV*
newSVpv_utf8(const char *s, STRLEN len)
{
@@ -128,31 +147,6 @@ newSVpv_utf8(const char *s, STRLEN len)
return sv;
}
-static void
-get_fullname_parts(URPM__Package pkg, char **name, char **version, char **release, char **arch, char **eos) {
- char *_version = NULL, *_release = NULL, *_arch = NULL, *_eos = NULL;
-
- if ((_eos = strchr(pkg->info, '@')) != NULL) {
- *_eos = 0; /* mark end of string to enable searching backwards */
- if ((_arch = strrchr(pkg->info, '.')) != NULL) {
- *_arch = 0;
- if ((release != NULL || version != NULL || name != NULL) && (_release = strrchr(pkg->info, '-')) != NULL) {
- *_release = 0;
- if ((version != NULL || name != NULL) && (_version = strrchr(pkg->info, '-')) != NULL) {
- if (name != NULL) *name = pkg->info;
- if (version != NULL) *version = _version + 1;
- }
- if (release != NULL) *release = _release + 1;
- *_release = '-';
- }
- if (arch != NULL) *arch = _arch + 1;
- *_arch = '.';
- }
- if (eos != NULL) *eos = _eos;
- *_eos = '@';
- }
-}
-
/* Since the NVRA format won't change, we'll store it in a global variable so
* that we only have to expand the macro once.
*/
@@ -228,6 +222,60 @@ get_int(Header header, rpmTag tag) {
}
static int
+get_fullname_parts(URPM__Package pkg, char **name, int *epoch, char **version, char **release, char **disttag, char **distepoch, char **arch, char **eos) {
+ char *_version = NULL, *_release = NULL, *_disttag = NULL, *_distepoch = NULL, *_arch = NULL, *_eos = NULL, *tmp = NULL;
+
+ if(pkg->info) {
+ if ((_eos = strchr(pkg->info, '@')) != NULL) {
+ backup_char(_eos);
+ if (eos != NULL) *eos = _eos+1;
+ if (epoch != NULL) *epoch = isdigit(_eos[1]) ? atoi(_eos+1) : 0;
+ if ((_arch = strrchr(pkg->info, '.')) != NULL) {
+ backup_char(_arch);
+ if (arch != NULL) *arch = _arch + 1;
+ if (distepoch != NULL || disttag != NULL || release != NULL || version != NULL || name != NULL) {
+ if((_distepoch = strchr(strrchr(pkg->provides, '-'), ':')) != NULL) {
+ tmp = strrchr(_distepoch+1, ']');
+ backup_char(tmp);
+ tmp = strstr(pkg->info, _distepoch+1);
+ backup_char(tmp);
+ }
+ if(distepoch != NULL) *distepoch = _distepoch ? _distepoch+1 : NULL;
+ if (disttag != NULL || release != NULL || version != NULL || name != NULL) {
+ if ((_disttag = strrchr(pkg->info, '-')) != NULL && (strstr(pkg->provides, _disttag)) == NULL) {
+ backup_char(_disttag);
+ } else _disttag = NULL;
+ if (disttag != NULL) *disttag = _disttag ? _disttag + 1: NULL;
+ if ((release != NULL || version != NULL || name != NULL) && (_release = strrchr(pkg->info, '-')) != NULL) {
+ backup_char(_release);
+ if (release != NULL) *release = _release + 1;
+ if ((version != NULL || name != NULL) && (_version = strrchr(pkg->info, '-')) != NULL) {
+ backup_char(_version);
+ if (version != NULL) *version = _version + 1;
+ if (name != NULL) *name = pkg->info;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ else if(pkg->h) {
+ if (name != NULL) *name = (char*)get_name(pkg->h, RPMTAG_NAME);
+ if (epoch != NULL) *epoch = get_int(pkg->h, RPMTAG_EPOCH);
+ if (version != NULL) *version = (char*)get_name(pkg->h, RPMTAG_VERSION);
+ if (release != NULL) *release = (char*)get_name(pkg->h, RPMTAG_RELEASE);
+ if (disttag != NULL) *disttag = (char*)get_name(pkg->h, RPMTAG_DISTTAG);
+ if (distepoch != NULL) *distepoch = (char*)get_name(pkg->h, RPMTAG_DISTEPOCH);
+ if (arch != NULL) *arch = headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? (char*)get_name(pkg->h, RPMTAG_ARCH) : "src";
+ if (eos != NULL) *eos = NULL;
+ }
+ else
+ return 1;
+ return 0;
+}
+
+static int
sigsize_to_filesize(int sigsize) {
return sigsize + 440; /* 440 is the rpm header size (?) empirical, but works */
}
@@ -644,36 +692,61 @@ return_list_tag(URPM__Package pkg, rpmTag tag_name) {
}
} else {
char *name;
+ int epoch;
char *version;
char *release;
+ char *disttag;
+ char *distepoch;
+
char *arch;
char *eos;
switch (tag_name) {
case RPMTAG_NAME:
{
- get_fullname_parts(pkg, &name, &version, &release, &arch, &eos);
- if (version - name < 1) croak("invalid fullname");
- XPUSHs(sv_2mortal(newSVpv(name, version-name - 1)));
+ if(get_fullname_parts(pkg, &name, &epoch, &version, &release, &arch, &disttag, &distepoch, &eos))
+ croak("invalid fullname");
+ XPUSHs(sv_2mortal(newSVpv(name, 0)));
}
break;
+ case RPMTAG_EPOCH: {
+ if(get_fullname_parts(pkg, &name, &epoch, &version, &release, &arch, &disttag, &distepoch, &eos))
+ croak("invalid fullname");
+ XPUSHs(sv_2mortal(newSViv(epoch)));
+ }
case RPMTAG_VERSION:
{
- get_fullname_parts(pkg, &name, &version, &release, &arch, &eos);
- if (release - version < 1) croak("invalid fullname");
- XPUSHs(sv_2mortal(newSVpv(version, release-version - 1)));
+ if(get_fullname_parts(pkg, &name, &epoch, &version, &release, &arch, &disttag, &distepoch, &eos))
+ croak("invalid fullname");
+ XPUSHs(sv_2mortal(newSVpv(version, 0)));
}
break;
case RPMTAG_RELEASE:
{
- get_fullname_parts(pkg, &name, &version, &release, &arch, &eos);
- if (arch - release < 1) croak("invalid fullname");
- XPUSHs(sv_2mortal(newSVpv(release, arch-release - 1)));
+ if(get_fullname_parts(pkg, &name, &epoch, &version, &release, &arch, &disttag, &distepoch, &eos))
+ croak("invalid fullname");
+ XPUSHs(sv_2mortal(newSVpv(release, 0)));
+
+ }
+ break;
+ case RPMTAG_DISTTAG:
+ {
+ if(get_fullname_parts(pkg, &name, &epoch, &version, &release, &arch, &disttag, &distepoch, &eos))
+ croak("invalid fullname");
+ XPUSHs(sv_2mortal(newSVpv(disttag, 0)));
+ }
+ break;
+ case RPMTAG_DISTEPOCH:
+ {
+ if(get_fullname_parts(pkg, &name, &epoch, &version, &release, &arch, &disttag, &distepoch, &eos))
+ croak("invalid fullname");
+ XPUSHs(sv_2mortal(newSVpv(distepoch, 0)));
}
break;
case RPMTAG_ARCH:
{
- get_fullname_parts(pkg, &name, &version, &release, &arch, &eos);
- XPUSHs(sv_2mortal(newSVpv(arch, eos-arch)));
+ if(get_fullname_parts(pkg, &name, &epoch, &version, &release, &arch, &disttag, &distepoch, &eos))
+ croak("invalid fullname");
+ XPUSHs(sv_2mortal(newSVpv(arch, 0)));
}
break;
case RPMTAG_SUMMARY:
@@ -683,6 +756,7 @@ return_list_tag(URPM__Package pkg, rpmTag tag_name) {
croak("unexpected tag");
break;
}
+ restore_chars();
}
PUTBACK;
}
@@ -1545,60 +1619,44 @@ void
Pkg_name(pkg)
URPM::Package pkg
PPCODE:
- if (pkg->info) {
- char *name;
- char *version;
+ char *name;
- get_fullname_parts(pkg, &name, &version, NULL, NULL, NULL);
- if (version - name < 1) croak("invalid fullname");
- XPUSHs(sv_2mortal(newSVpv(name, version-name-1)));
- } else if (pkg->h) {
- XPUSHs(sv_2mortal(newSVpv(get_name(pkg->h, RPMTAG_NAME), 0)));
- }
+ if(get_fullname_parts(pkg, &name, NULL, NULL, NULL, NULL, NULL, NULL, NULL))
+ croak("invalid fullname");
+ XPUSHs(sv_2mortal(newSVpv(name, 0)));
+ restore_chars();
void
Pkg_version(pkg)
URPM::Package pkg
PPCODE:
- if (pkg->info) {
- char *version;
- char *release;
+ char *version;
- get_fullname_parts(pkg, NULL, &version, &release, NULL, NULL);
- if (release - version < 1) croak("invalid fullname");
- XPUSHs(sv_2mortal(newSVpv(version, release-version-1)));
- } else if (pkg->h) {
- XPUSHs(sv_2mortal(newSVpv(get_name(pkg->h, RPMTAG_VERSION), 0)));
- }
+ if(get_fullname_parts(pkg, NULL, NULL, &version, NULL, NULL, NULL, NULL, NULL))
+ croak("invalid fullname");
+ XPUSHs(sv_2mortal(newSVpv(version, 0)));
+ restore_chars();
void
Pkg_release(pkg)
URPM::Package pkg
PPCODE:
- if (pkg->info) {
- char *release;
- char *arch;
+ char *release;
- get_fullname_parts(pkg, NULL, NULL, &release, &arch, NULL);
- if (arch - release < 1) croak("invalid fullname");
- XPUSHs(sv_2mortal(newSVpv(release, arch-release-1)));
- } else if (pkg->h) {
- XPUSHs(sv_2mortal(newSVpv(get_name(pkg->h, RPMTAG_RELEASE), 0)));
- }
+ if(get_fullname_parts(pkg, NULL, NULL, NULL, &release, NULL, NULL, NULL, NULL))
+ croak("invalid fullname");
+ XPUSHs(sv_2mortal(newSVpv(release, 0)));
+ restore_chars();
void
Pkg_arch(pkg)
URPM::Package pkg
PPCODE:
- if (pkg->info) {
- char *arch;
- char *eos;
+ char *arch;
- get_fullname_parts(pkg, NULL, NULL, NULL, &arch, &eos);
- XPUSHs(sv_2mortal(newSVpv(arch, eos-arch)));
- } else if (pkg->h) {
- XPUSHs(sv_2mortal(newSVpv(headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? get_name(pkg->h, RPMTAG_ARCH) : "src", 0)));
- }
+ get_fullname_parts(pkg, NULL, NULL, NULL, NULL, NULL, NULL, &arch, NULL);
+ XPUSHs(sv_2mortal(newSVpv(arch, 0)));
+ restore_chars();
int
Pkg_is_arch_compat__XS(pkg)
@@ -1609,14 +1667,12 @@ Pkg_is_arch_compat__XS(pkg)
read_config_files(0);
if (pkg->info) {
char *arch;
- char *eos;
- get_fullname_parts(pkg, NULL, NULL, NULL, &arch, &eos);
- *eos = 0;
+ get_fullname_parts(pkg, NULL, NULL, NULL, NULL, NULL, NULL, &arch, NULL);
platform = rpmExpand(arch, "-%{_target_vendor}-%{_target_os}%{?_gnu}", NULL);
RETVAL = rpmPlatformScore(platform, NULL, 0);
_free(platform);
- *eos = '@';
+ restore_chars();
} else if (pkg->h && headerIsEntry(pkg->h, RPMTAG_SOURCERPM)) {
const char *arch = get_name(pkg->h, RPMTAG_ARCH);
platform = rpmExpand(arch, "-%{_target_vendor}-%{_target_os}%{?_gnu}", NULL);
@@ -1647,11 +1703,10 @@ Pkg_is_platform_compat(pkg)
char *arch;
char *eos;
- get_fullname_parts(pkg, NULL, NULL, NULL, &arch, &eos);
- *eos = 0;
+ get_fullname_parts(pkg, NULL, NULL, NULL, NULL, NULL, NULL, &arch, &eos);
platform = rpmExpand(arch, "-%{_target_vendor}-", eos, "%{?_gnu}", NULL);
RETVAL = rpmPlatformScore(platform, NULL, 0);
- *eos = '@';
+ restore_chars();
_free(platform);
} else {
RETVAL = 0;
@@ -1780,57 +1835,50 @@ Pkg_fullname(pkg)
PREINIT:
I32 gimme = GIMME_V;
PPCODE:
- if (pkg->info) {
- if (gimme == G_SCALAR) {
+ if (gimme == G_ARRAY) {
+ char *name, *version, *release, *disttag, *distepoch, *arch, *eos;
+ int items = 4;
+
+ if(get_fullname_parts(pkg, &name, NULL, &version, &release, &disttag, &distepoch, &arch, &eos))
+ croak("invalid fullname");
+
+ /* XXX: This might result in the number of items and the order which returned
+ * being unexpected in the case of disttag/disttag being present.
+ */
+ if(disttag != NULL) items++;
+ if(distepoch != NULL) items++;
+
+ EXTEND(SP, items);
+ PUSHs(sv_2mortal(newSVpv(name, 0)));
+ PUSHs(sv_2mortal(newSVpv(version, 0)));
+ PUSHs(sv_2mortal(newSVpv(release, 0)));
+ if(disttag != NULL)
+ PUSHs(sv_2mortal(newSVpv(disttag, 0)));
+ if(distepoch != NULL)
+ PUSHs(sv_2mortal(newSVpv(distepoch, 0)));
+ PUSHs(sv_2mortal(newSVpv(arch, 0)));
+ restore_chars();
+ } else if (gimme == G_SCALAR) {
+ if (pkg->info) {
char *eos;
- if ((eos = strchr(pkg->info, '@')) != NULL) {
+ if ((eos = strchr(pkg->info, '@')) != NULL)
XPUSHs(sv_2mortal(newSVpv(pkg->info, eos-pkg->info)));
- }
- } else if (gimme == G_ARRAY) {
- char *name, *version, *release, *arch, *eos;
- get_fullname_parts(pkg, &name, &version, &release, &arch, &eos);
- if (version - name < 1 || release - version < 1 || arch - release < 1)
- croak("invalid fullname");
- EXTEND(SP, 4);
- PUSHs(sv_2mortal(newSVpv(name, version-name-1)));
- PUSHs(sv_2mortal(newSVpv(version, release-version-1)));
- PUSHs(sv_2mortal(newSVpv(release, arch-release-1)));
- PUSHs(sv_2mortal(newSVpv(arch, eos-arch)));
- }
- } else if (pkg->h) {
- const char *name = get_name(pkg->h, RPMTAG_NAME);
- const char *version = get_name(pkg->h, RPMTAG_VERSION);
- const char *release = get_name(pkg->h, RPMTAG_RELEASE);
- const char *arch = headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? get_name(pkg->h, RPMTAG_ARCH) : "src";
-
- if (gimme == G_SCALAR) {
+ } else if (pkg->h) {
const char *nvra = get_nvra(pkg->h);
XPUSHs(sv_2mortal(newSVpvf("%s", nvra)));
_free(nvra);
- } else if (gimme == G_ARRAY) {
- EXTEND(SP, 4);
- PUSHs(sv_2mortal(newSVpv(name, 0)));
- PUSHs(sv_2mortal(newSVpv(version, 0)));
- PUSHs(sv_2mortal(newSVpv(release, 0)));
- PUSHs(sv_2mortal(newSVpv(arch, 0)));
}
}
int
Pkg_epoch(pkg)
URPM::Package pkg
+ PREINIT:
+ int epoch;
CODE:
- if (pkg->info) {
- char *s;
-
- if ((s = strchr(pkg->info, '@')) != NULL) {
- RETVAL = strtoul(s+1, NULL, 10);
- } else {
- RETVAL = 0;
- }
- } else if (pkg->h) {
- RETVAL = get_int(pkg->h, RPMTAG_EPOCH);
- } else RETVAL = 0;
+ get_fullname_parts(pkg, NULL, &epoch, NULL, NULL, NULL, NULL, NULL, NULL);
+ restore_chars();
+ RETVAL = epoch;
OUTPUT:
RETVAL
@@ -1843,63 +1891,20 @@ Pkg_compare_pkg(lpkg, rpkg)
int lepoch;
char *lversion;
char *lrelease;
+ char *ldistepoch;
char *larch;
char *leos;
int repoch;
char *rversion;
char *rrelease;
+ char *rdistepoch;
char *rarch;
char *reos;
CODE:
if (lpkg == rpkg) RETVAL = 0;
else {
- if (lpkg->info) {
- char *s;
-
- if ((s = strchr(lpkg->info, '@')) != NULL) {
- if ((leos = strchr(s+1, '@')) != NULL) *leos = 0; /* mark end of string to enable searching backwards */
- lepoch = atoi(s+1);
- if (leos != NULL) *leos = '@';
- } else {
- lepoch = 0;
- }
- get_fullname_parts(lpkg, NULL, &lversion, &lrelease, &larch, &leos);
- /* temporarily mark end of each substring */
- lrelease[-1] = 0;
- larch[-1] = 0;
- } else if (lpkg->h) {
- lepoch = get_int(lpkg->h, RPMTAG_EPOCH);
- lversion = (char*)get_name(lpkg->h, RPMTAG_VERSION);
- lrelease = (char*)get_name(lpkg->h, RPMTAG_RELEASE);
- larch = headerIsEntry(lpkg->h, RPMTAG_SOURCERPM) ? (char*)get_name(lpkg->h, RPMTAG_ARCH) : "src";
- } else croak("undefined package");
- if (rpkg->info) {
- char *s;
-
- if ((s = strchr(rpkg->info, '@')) != NULL) {
- if ((reos = strchr(s+1, '@')) != NULL) *reos = 0; /* mark end of string to enable searching backwards */
- repoch = atoi(s+1);
- if (reos != NULL) *reos = '@';
- } else {
- repoch = 0;
- }
- get_fullname_parts(rpkg, NULL, &rversion, &rrelease, &rarch, &reos);
- /* temporarily mark end of each substring */
- rrelease[-1] = 0;
- rarch[-1] = 0;
- } else if (rpkg->h) {
- repoch = get_int(rpkg->h, RPMTAG_EPOCH);
- rversion = (char*)get_name(rpkg->h, RPMTAG_VERSION);
- rrelease = (char*)get_name(rpkg->h, RPMTAG_RELEASE);
- rarch = headerIsEntry(rpkg->h, RPMTAG_SOURCERPM) ? (char*)get_name(rpkg->h, RPMTAG_ARCH) : "src";
- } else {
- /* restore info string modified */
- if (lpkg->info) {
- lrelease[-1] = '-';
- larch[-1] = '.';
- }
+ if(get_fullname_parts(lpkg, NULL, &lepoch, &lversion, &lrelease, &ldistepoch, NULL, &larch, &leos) || get_fullname_parts(rpkg, NULL, &repoch, &rversion, &rrelease, &rdistepoch, NULL, &rarch, &reos))
croak("undefined package");
- }
compare = lepoch - repoch;
if (!compare) {
compare = rpmvercmp(lversion, rversion);
@@ -1945,15 +1950,7 @@ Pkg_compare_pkg(lpkg, rpkg)
}
}
}
- /* restore info string modified */
- if (lpkg->info) {
- lrelease[-1] = '-';
- larch[-1] = '.';
- }
- if (rpkg->info) {
- rrelease[-1] = '-';
- rarch[-1] = '.';
- }
+ restore_chars();
RETVAL = compare;
}
OUTPUT:
@@ -1968,25 +1965,11 @@ Pkg_compare(pkg, evr)
int _epoch;
char *_version;
char *_release;
+ char *_distepoch;
char *_eos;
CODE:
- if (pkg->info) {
- char *s;
-
- if ((s = strchr(pkg->info, '@')) != NULL) {
- if ((_eos = strchr(s+1, '@')) != NULL) *_eos = 0; /* mark end of string to enable searching backwards */
- _epoch = atoi(s+1);
- if (_eos != NULL) *_eos = '@';
- } else {
- _epoch = 0;
- }
- get_fullname_parts(pkg, NULL, &_version, &_release, &_eos, NULL);
- /* temporarily mark end of each substring */
- _release[-1] = 0;
- _eos[-1] = 0;
- } else if (pkg->h) {
- _epoch = get_int(pkg->h, RPMTAG_EPOCH);
- } else croak("undefined package");
+ if(get_fullname_parts(pkg, NULL, &_epoch, &_version, &_release, &_distepoch, NULL, NULL, &_eos))
+ croak("undefined package");
if (!compare) {
char *epoch, *version, *release;
@@ -1998,36 +1981,27 @@ Pkg_compare(pkg, evr)
*version++ = 0;
if (!*epoch) epoch = "0";
compare = _epoch - (*epoch ? atoi(epoch) : 0);
- version[-1] = ':'; /* restore in memory modification */
} else {
/* there is no epoch defined, so assume epoch = 0 */
version = evr;
compare = _epoch;
}
if (!compare) {
- if (!pkg->info)
- _version = (char*)get_name(pkg->h, RPMTAG_VERSION);
/* continue extracting release if any */
if ((release = strrchr(version, '-')) != NULL) {
*release++ = 0;
compare = rpmvercmp(_version, version);
if (!compare) {
/* need to compare with release here */
- if (!pkg->info)
- _release = (char*)get_name(pkg->h, RPMTAG_RELEASE);
compare = rpmvercmp(_release, release);
}
- release[-1] = '-'; /* restore in memory modification */
} else {
compare = rpmvercmp(_version, version);
}
}
}
/* restore info string modified */
- if (pkg->info) {
- _release[-1] = '-';
- _eos[-1] = '.';
- }
+ restore_chars();
RETVAL = compare;
OUTPUT:
RETVAL