aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPer Øyvind Karlsen <peroyvind@mandriva.org>2009-08-05 21:20:54 +0000
committerPer Øyvind Karlsen <peroyvind@mandriva.org>2009-08-05 21:20:54 +0000
commitfd1f166c0530e862020939c3ee8a878eec7f653d (patch)
treee1d56bbdcc934d7364b00bdcdb33c9bbe929b24f
parentfee6493885dd548871e71824f049ea37c903c312 (diff)
downloadperl-URPM-fd1f166c0530e862020939c3ee8a878eec7f653d.tar
perl-URPM-fd1f166c0530e862020939c3ee8a878eec7f653d.tar.gz
perl-URPM-fd1f166c0530e862020939c3ee8a878eec7f653d.tar.bz2
perl-URPM-fd1f166c0530e862020939c3ee8a878eec7f653d.tar.xz
perl-URPM-fd1f166c0530e862020939c3ee8a878eec7f653d.zip
* add support for fetching disttag & distepoch with get_fullname_parts()
* refactorize get_fullname_parts() and friends using it
-rw-r--r--URPM.xs329
1 files changed, 170 insertions, 159 deletions
diff --git a/URPM.xs b/URPM.xs
index 71d27f4..d6e47f6 100644
--- a/URPM.xs
+++ b/URPM.xs
@@ -127,6 +127,25 @@ int rpmError_callback() {
static int rpm_codeset_is_utf8 = 0;
+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)
+ *char_backups[--BI].ptr = char_backups[BI].chr;
+}
+
static SV*
newSVpv_utf8(const char *s, STRLEN len)
{
@@ -135,31 +154,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 = '@';
- }
-}
-
static char *
get_name(Header header, int32_t tag) {
struct rpmtd_s val;
@@ -178,6 +172,58 @@ get_int(Header header, int32_t tag) {
return ep ? *ep : 0;
}
+static int
+get_fullname_parts(URPM__Package pkg, char **name, char **version, char **release, char **disttag, char **distepoch, char **arch, char **eos) {
+ char *_version = NULL, *_release = NULL, *_disttag = NULL, *_distepoch, *_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 ((_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 = get_name(pkg->h, RPMTAG_NAME);
+ if (version != NULL) *version = get_name(pkg->h, RPMTAG_VERSION);
+ if (release != NULL) *release = get_name(pkg->h, RPMTAG_RELEASE);
+ if (disttag != NULL) *disttag = get_name(pkg->h, RPMTAG_DISTTAG);
+ if (distepoch != NULL) *distepoch = get_name(pkg->h, RPMTAG_DISTEPOCH);
+ if (arch != NULL) *arch = headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? get_name(pkg->h, RPMTAG_ARCH) : "src";
+ if (eos != NULL) *eos = NULL;
+ }
+ else
+ return 1;
+ return 0;
+}
+
/* 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.
*/
@@ -644,40 +690,58 @@ return_list_tag(URPM__Package pkg, int32_t tag_name) {
char *name;
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, &version, &release, &arch, &disttag, &distepoch, &eos))
+ croak("invalid fullname");
+ XPUSHs(sv_2mortal(newSVpv(name, 0)));
}
break;
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, &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, &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, &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, &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)));
+ get_fullname_parts(pkg, &name, &version, &release, &arch, &disttag, &distepoch, &eos);
+ XPUSHs(sv_2mortal(newSVpv(arch, 0)));
}
break;
case RPMTAG_SUMMARY:
XPUSHs(sv_2mortal(newSVpv(pkg->summary, 0)));
break;
}
+ restore_chars();
}
PUTBACK;
}
@@ -1496,60 +1560,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))
+ 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, &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, &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, &arch, NULL);
+ XPUSHs(sv_2mortal(newSVpv(arch, 0)));
+ restore_chars();
int
Pkg_is_arch_compat__XS(pkg)
@@ -1562,10 +1610,8 @@ 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, &arch, NULL);
#ifndef RPM_ORG
platform = rpmExpand(arch, "-%{_target_vendor}-%{_target_os}%{?_gnu}", NULL);
RETVAL = rpmPlatformScore(platform, NULL, 0);
@@ -1573,7 +1619,7 @@ Pkg_is_arch_compat__XS(pkg)
#else
RETVAL = rpmMachineScore(RPM_MACHTABLE_INSTARCH, arch);
#endif
- *eos = '@';
+ restore_chars();
} else if (pkg->h && headerIsEntry(pkg->h, RPMTAG_SOURCERPM)) {
char *arch = get_name(pkg->h, RPMTAG_ARCH);
#ifndef RPM_ORG
@@ -1609,11 +1655,11 @@ 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, &arch, &eos);
platform = rpmExpand(arch, "-%{_target_vendor}-", eos, "%{?_gnu}", NULL);
RETVAL = rpmPlatformScore(platform, NULL, 0);
- *eos = '@';
+ restore_chars();
_free(platform);
} else {
#else
@@ -1746,39 +1792,38 @@ 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, &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) {
- char *name = get_name(pkg->h, RPMTAG_NAME);
- char *version = get_name(pkg->h, RPMTAG_VERSION);
- char *release = get_name(pkg->h, RPMTAG_RELEASE);
- char *arch = headerIsEntry(pkg->h, RPMTAG_SOURCERPM) ? get_name(pkg->h, RPMTAG_ARCH) : "src";
-
- if (gimme == G_SCALAR) {
+ } else if (pkg->h) {
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)));
}
}
@@ -1821,51 +1866,34 @@ Pkg_compare_pkg(lpkg, rpkg)
CODE:
if (lpkg == rpkg) RETVAL = 0;
else {
+ get_fullname_parts(lpkg, NULL, &lversion, &lrelease, &larch, NULL, NULL, &leos);
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 = '@';
+ if ((s = strchr(leos, '@')) != NULL) {
+ backup_char(s);
+ lepoch = atoi(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 = get_name(lpkg->h, RPMTAG_VERSION);
- lrelease = get_name(lpkg->h, RPMTAG_RELEASE);
- larch = headerIsEntry(lpkg->h, RPMTAG_SOURCERPM) ? get_name(lpkg->h, RPMTAG_ARCH) : "src";
} else croak("undefined package");
+
+ get_fullname_parts(rpkg, NULL, &rversion, &rrelease, NULL, NULL, &rarch, &reos);
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 = '@';
+ if ((s = strchr(reos, '@')) != NULL) {
+ backup_char(s);
+ repoch = atoi(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 = get_name(rpkg->h, RPMTAG_VERSION);
- rrelease = get_name(rpkg->h, RPMTAG_RELEASE);
- rarch = headerIsEntry(rpkg->h, RPMTAG_SOURCERPM) ? get_name(rpkg->h, RPMTAG_ARCH) : "src";
} else {
- /* restore info string modified */
- if (lpkg->info) {
- lrelease[-1] = '-';
- larch[-1] = '.';
- }
+ restore_chars();
croak("undefined package");
}
compare = lepoch - repoch;
@@ -1875,12 +1903,10 @@ Pkg_compare_pkg(lpkg, rpkg)
compare = rpmvercmp(lrelease, rrelease);
if (!compare) {
int lscore, rscore;
- char *eolarch = strchr(larch, '@');
- char *eorarch = strchr(rarch, '@');
read_config_files(0);
- if (eolarch) *eolarch = 0; lscore = rpmMachineScore(RPM_MACHTABLE_INSTARCH, larch);
- if (eorarch) *eorarch = 0; rscore = rpmMachineScore(RPM_MACHTABLE_INSTARCH, rarch);
+ lscore = rpmMachineScore(RPM_MACHTABLE_INSTARCH, larch);
+ rscore = rpmMachineScore(RPM_MACHTABLE_INSTARCH, rarch);
if (lscore == 0) {
if (rscore == 0)
#if 0
@@ -1897,20 +1923,11 @@ Pkg_compare_pkg(lpkg, rpkg)
else
compare = rscore - lscore; /* score are lower for better */
}
- if (eolarch) *eolarch = '@';
- if (eorarch) *eorarch = '@';
}
}
}
/* restore info string modified */
- if (lpkg->info) {
- lrelease[-1] = '-';
- larch[-1] = '.';
- }
- if (rpkg->info) {
- rrelease[-1] = '-';
- rarch[-1] = '.';
- }
+ restore_chars();
RETVAL = compare;
}
OUTPUT:
@@ -1925,22 +1942,19 @@ Pkg_compare(pkg, evr)
int _epoch;
char *_version;
char *_release;
+ char *_arch;
char *_eos;
CODE:
+ get_fullname_parts(pkg, NULL, &_version, &_release, NULL, NULL, &_arch, &_eos);
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 = '@';
+ if ((s = strchr(_eos, '@')) != NULL) {
+ backup_char(s);
+ _epoch = atoi(_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");
@@ -1981,10 +1995,7 @@ Pkg_compare(pkg, evr)
}
}
/* restore info string modified */
- if (pkg->info) {
- _release[-1] = '-';
- _eos[-1] = '.';
- }
+ restore_chars();
RETVAL = compare;
OUTPUT:
RETVAL