diff --git a/perl-RPM2/Makefile.PL b/perl-RPM2/Makefile.PL index 3676612e6..0e1a179c4 100644 --- a/perl-RPM2/Makefile.PL +++ b/perl-RPM2/Makefile.PL @@ -15,7 +15,10 @@ if (open FH, "<$filename") { my ($line, @rest) = grep { /^dependency_libs=/ } ; if ($line and not @rest) { if ($line =~ /^dependency_libs='(.*)'$/) { - $libs = "$extra_libs -lrpm $1"; + my $l = $1; + my @l = split /\s+/, $l; + @l = grep { /^-l/ } @l; + $libs = "$libs -lrpm @l"; } } } diff --git a/perl-RPM2/RPM2.pm b/perl-RPM2/RPM2.pm index 33406ebe0..870c9df60 100644 --- a/perl-RPM2/RPM2.pm +++ b/perl-RPM2/RPM2.pm @@ -7,48 +7,24 @@ use Data::Dumper; use Cwd qw/realpath/; use vars qw/$VERSION/; -$VERSION = '0.48'; +$VERSION = '0.60'; use vars qw/@ISA/; @ISA = qw/DynaLoader/; bootstrap RPM2 $VERSION; -my %tagmap; - -RPM2_C::_init_rpm(); -RPM2_C::_populate_header_tags(\%tagmap); - -sub rpmvercmp { - return RPM2_C::rpmvercmp(@_); -} - -sub add_macro { - my $class = shift; - my $name = shift; - my $val = shift; - - RPM2_C::_add_macro($name, $val); -} - -sub delete_macro { - my $class = shift; - my $name = shift; - - RPM2_C::_delete_macro($name); -} - sub open_rpm_db { my $class = shift; my %params = @_; - my $self = bless { }, $class; + my $self = bless { }, "RPM2::DB"; if ($params{-path}) { $class->add_macro("_dbpath", $params{-path}); - $self->{db} = RPM2_C::_open_rpm_db($params{-readwrite} ? 1 : 0); + $self->{c_db} = RPM2::_open_rpm_db($params{-readwrite} ? 1 : 0); $class->delete_macro("_dbpath"); } else { - $self->{db} = RPM2_C::_open_rpm_db($params{-readwrite} ? 1 : 0); + $self->{c_db} = RPM2::_open_rpm_db($params{-readwrite} ? 1 : 0); } return $self; @@ -61,39 +37,32 @@ sub open_package { open FH, "<$file" or die "Can't open $file: $!"; - my $hdr = RPM2_C::_read_package_info(*FH); + my $hdr = RPM2::_read_package_info(*FH); close FH; - $hdr = RPM2::Header->_new_raw($hdr, 1, realpath($file)); - + $hdr = RPM2::Header->_new_raw($hdr, realpath($file)); return $hdr; } -sub close_rpm_db { - my $self = shift; - die "db not open" unless $self->{db}; - - RPM2_C::_close_rpm_db($self->{db}); - $self->{db} = undef; -} +package RPM2::DB; sub find_all_iter { my $self = shift; - return $self->iterator("RPMTAG_NAME") + return RPM2::PackageIterator->new_iterator($self, "RPMTAG_NAME") } sub find_all { my $self = shift; - return $self->iterator()->expand_iter(); + return RPM2::PackageIterator->new_iterator($self)->expand_iter(); } sub find_by_name_iter { my $self = shift; my $name = shift; - return $self->iterator("RPMTAG_NAME", $name); + return RPM2::PackageIterator->new_iterator($self, "RPMTAG_NAME", $name); } sub find_by_name { my $self = shift; @@ -106,7 +75,7 @@ sub find_by_provides_iter { my $self = shift; my $name = shift; - return $self->iterator("RPMTAG_PROVIDES", $name); + return RPM2::PackageIterator->new_iterator($self, "RPMTAG_PROVIDES", $name); } sub find_by_provides { my $self = shift; @@ -119,7 +88,7 @@ sub find_by_requires_iter { my $self = shift; my $name = shift; - return $self->iterator("RPMTAG_REQUIRENAME", $name); + return RPM2::PackageIterator->new_iterator($self, "RPMTAG_REQUIRENAME", $name); } sub find_by_requires { @@ -133,8 +102,9 @@ sub find_by_file_iter { my $self = shift; my $name = shift; - return $self->iterator("RPMTAG_BASENAMES", $name); + return RPM2::PackageIterator->new_iterator($self, "RPMTAG_BASENAMES", $name); } + sub find_by_file { my $self = shift; my $name = shift; @@ -142,25 +112,6 @@ sub find_by_file { return $self->find_by_file_iter($name)->expand_iter; } -sub iterator { - my $self = shift; - my $tag = shift; - my $str = shift; - - die "db closed" unless $self->{db}; - my $iter = RPM2::PackageIterator->new_iterator($self->{db}, $tag, $str); - - return $iter; -} - -sub DESTROY { - my $self = shift; - - if ($self->{db}) { - $self->close_rpm_db(); - } -} - package RPM2::Header; use overload '<=>' => \&op_spaceship, @@ -169,12 +120,10 @@ use overload '<=>' => \&op_spaceship, sub _new_raw { my $class = shift; my $c_header = shift; - my $need_free = shift; my $filename = shift; my $self = bless { }, $class; - $self->{header} = $c_header; - $self->{need_free} = $need_free; + $self->{c_header} = $c_header; $self->{filename} = $filename if defined $filename; return $self; @@ -187,22 +136,29 @@ sub tag { $tag = uc "RPMTAG_$tag"; die "tag $tag invalid" - unless exists $tagmap{$tag}; + unless exists $RPM2::header_tag_map{$tag}; - return RPM2_C::_header_tag($self->{header}, $tagmap{$tag}); + return $self->{c_header}->tag_by_id($RPM2::header_tag_map{$tag}); +} + +sub tagformat { + my $self = shift; + my $format = shift; + + return RPM2::C::Header::_header_sprintf($self->{c_header}, $format); } sub compare { my $h1 = shift; my $h2 = shift; - return RPM2_C::_header_compare($h1->{header}, $h2->{header}); + return RPM2::C::Header::_header_compare($h1->{c_header}, $h2->{c_header}); } sub op_bool { my $self = shift; - return defined($self) && defined($self->{header}); + return defined($self) && defined($self->{c_header}); } sub op_spaceship { @@ -220,7 +176,7 @@ sub op_spaceship { sub is_source_package { my $self = shift; - return RPM2_C::_header_is_source($self->{header}); + return $self->tag("sourcepackage"); } sub filename { @@ -243,7 +199,7 @@ sub as_nvre { return $ret; } -foreach my $tag (keys %tagmap) { +foreach my $tag (keys %RPM2::header_tag_map) { $tag =~ s/^RPMTAG_//g; my $sub = q { @@ -282,14 +238,6 @@ sub files { return @{$self->{files}}; } -sub DESTROY { - my $self = shift; - - if ($self->{need_free}) { - RPM2_C::_free_header(delete $self->{header}); - } -} - package RPM2::PackageIterator; sub new_iterator { @@ -299,21 +247,21 @@ sub new_iterator { my $key = shift; my $self = bless { }, $class; - $self->{iter} = RPM2_C::_init_iterator($db, $tagmap{$tag}, $key || "", defined $key ? length $key : 0); - $self->{db} = $db; - + $self->{c_iter} = RPM2::C::DB::_init_iterator($db->{c_db}, + $RPM2::header_tag_map{$tag}, + $key || "", + defined $key ? length $key : 0); return $self; } sub next { my $self = shift; - return unless $self->{iter}; - - my $hdr = RPM2_C::_iterator_next($self->{iter}); + return unless $self->{c_iter}; + my $hdr = $self->{c_iter}->_iterator_next(); return unless $hdr; - my $ret = RPM2::Header->_new_raw($hdr, 1); + my $ret = RPM2::Header->_new_raw($hdr); return $ret; } @@ -328,14 +276,6 @@ sub expand_iter { return @ret; } -sub DESTROY { - my $self = shift; - - if ($self->{iter}) { - RPM2_C::_destroy_iterator($self->{iter}); - } -} - # Preloaded methods go here. 1; diff --git a/perl-RPM2/RPM2.xs b/perl-RPM2/RPM2.xs index 11f1838c8..b05c03375 100644 --- a/perl-RPM2/RPM2.xs +++ b/perl-RPM2/RPM2.xs @@ -13,83 +13,46 @@ #include "perl.h" #include "XSUB.h" -const char *CLASS = "RPM2_C"; -MODULE = RPM2 PACKAGE = RPM2_C +void +_populate_header_tags(HV *href) +{ + int i = 0; + + for (i = 0; i < rpmTagTableSize; i++) { + hv_store(href, rpmTagTable[i].name, strlen(rpmTagTable[i].name), newSViv(rpmTagTable[i].val), 0); + } +} + +MODULE = RPM2 PACKAGE = RPM2 PROTOTYPES: ENABLE - -int -rpmvercmp(one, two) - char* one - char* two - -void -_init_rpm() - CODE: +BOOT: + { + HV *header_tags; rpmReadConfigFiles(NULL, NULL); + header_tags = perl_get_hv("RPM2::header_tag_map", TRUE); + _populate_header_tags(header_tags); + } void -_add_macro(name, val) +add_macro(pkg, name, val) + char * pkg char * name char * val CODE: addMacro(NULL, name, NULL, val, RMIL_DEFAULT); void -_delete_macro(name) +delete_macro(pkg, name) + char * pkg char * name CODE: delMacro(NULL, name); -void -_close_rpm_db(db) - rpmdb db - CODE: - rpmdbClose(db); - -rpmdb -_open_rpm_db(for_write) - int for_write - PREINIT: - rpmdb db; - CODE: - if (rpmdbOpen(NULL, &db, for_write ? O_RDWR | O_CREAT : O_RDONLY, 0644)) { - croak("rpmdbOpen failed"); - RETVAL = NULL; - } - RETVAL = db; - OUTPUT: - RETVAL - -rpmdbMatchIterator -_init_iterator(db, rpmtag, key, len) - rpmdb db - int rpmtag - char *key - size_t len - CODE: - RETVAL = rpmdbInitIterator(db, rpmtag, key && *key ? key : NULL, len); - OUTPUT: - RETVAL - -void -_destroy_iterator(i) - rpmdbMatchIterator i - CODE: - rpmdbFreeIterator(i); - -Header -_iterator_next(i) - rpmdbMatchIterator i - PREINIT: - Header ret; - CODE: - ret = rpmdbNextIterator(i); - if (ret) - headerLink(ret); - RETVAL = ret; - OUTPUT: - RETVAL +int +rpmvercmp(one, two) + char* one + char* two void _read_package_info(fp) @@ -130,7 +93,7 @@ _read_package_info(fp) EXTEND(SP, 1); h_sv = sv_newmortal(); - sv_setref_pv(h_sv, "Header", (void *)ret); + sv_setref_pv(h_sv, "RPM2::C::Header", (void *)ret); PUSHs(h_sv); } @@ -141,14 +104,76 @@ _read_package_info(fp) ts = rpmtsFree(ts); #endif +rpmdb +_open_rpm_db(for_write) + int for_write + PREINIT: + rpmdb db; + CODE: + if (rpmdbOpen(NULL, &db, for_write ? O_RDWR | O_CREAT : O_RDONLY, 0644)) { + croak("rpmdbOpen failed"); + RETVAL = NULL; + } + RETVAL = db; + OUTPUT: + RETVAL + +MODULE = RPM2 PACKAGE = RPM2::C::DB + void -_free_header(h) +DESTROY(db) + rpmdb db + CODE: + rpmdbClose(db); + +void +_close_rpm_db(self) + rpmdb self + CODE: + rpmdbClose(self); + +rpmdbMatchIterator +_init_iterator(db, rpmtag, key, len) + rpmdb db + int rpmtag + char *key + size_t len + CODE: + RETVAL = rpmdbInitIterator(db, rpmtag, key && *key ? key : NULL, len); + OUTPUT: + RETVAL + +MODULE = RPM2 PACKAGE = RPM2::C::PackageIterator +Header +_iterator_next(i) + rpmdbMatchIterator i + PREINIT: + Header ret; + CODE: + ret = rpmdbNextIterator(i); + if (ret) + headerLink(ret); + RETVAL = ret; + OUTPUT: + RETVAL + +void +DESTROY(i) + rpmdbMatchIterator i + CODE: + rpmdbFreeIterator(i); + + +MODULE = RPM2 PACKAGE = RPM2::C::Header + +void +DESTROY(h) Header h CODE: headerFree(h); void -_header_tag(h, tag) +tag_by_id(h, tag) Header h int tag PREINIT: @@ -212,22 +237,13 @@ _header_compare(h1, h2) OUTPUT: RETVAL -int -_header_is_source(h) - Header h - CODE: - RETVAL = headerIsEntry(h, RPMTAG_SOURCEPACKAGE); - OUTPUT: - RETVAL - void -_populate_header_tags(href) - SV *href +_header_sprintf(h, format) + Header h + char * format PREINIT: - int i = 0; - HV *h; - CODE: - h = (HV *)SvRV(href); - for (i = 0; i < rpmTagTableSize; i++) { - hv_store(h, rpmTagTable[i].name, strlen(rpmTagTable[i].name), newSViv(rpmTagTable[i].val), 0); - } + char * s; + PPCODE: + s = headerSprintf(h, format, rpmTagTable, rpmHeaderFormats, NULL); + PUSHs(sv_2mortal(newSVpv((char *)s, 0))); + s = _free(s); diff --git a/perl-RPM2/test.pl b/perl-RPM2/test.pl index bd92b608f..24c6a66d9 100644 --- a/perl-RPM2/test.pl +++ b/perl-RPM2/test.pl @@ -11,7 +11,7 @@ use strict; use Test; use strict; -BEGIN { plan tests => 28 }; +BEGIN { plan tests => 30 }; use RPM2; ok(1); # If we made it this far, we're ok. @@ -24,8 +24,9 @@ ok(RPM2::rpmvercmp("1.0", "1.1") == -1); ok(RPM2::rpmvercmp("1.1", "1.0") == 1); ok(RPM2::rpmvercmp("1.0", "1.0") == 0); -# this is a bug case in rpmvervmp; good one for testing -ok(RPM2::rpmvercmp("1.a", "1.0") == RPM2::rpmvercmp("1.0", "1.a")); +# UPDATE: the vercmp bug was finally fixed, and broke this test, heh +# this is a bug case in rpmvervmp; good one for testing +# ok(RPM2::rpmvercmp("1.a", "1.0") == RPM2::rpmvercmp("1.0", "1.a")); my $db = RPM2->open_rpm_db(); ok(defined $db); @@ -37,11 +38,11 @@ ok($i); while (my $pkg = $i->next) { push @pkg, $pkg; } + ok(@pkg); ok($pkg[0]->name); @pkg = (); - $i = $db->find_by_name_iter("kernel"); ok($i); while (my $pkg = $i->next) { @@ -82,11 +83,14 @@ if (@pkg) { my $pkg = RPM2->open_package("test-rpm-1.0-1.noarch.rpm"); ok($pkg); ok($pkg->name eq 'test-rpm'); +ok($pkg->tagformat("--%{NAME}%{VERSION}--") eq '--test-rpm1.0--'); +ok($pkg->tagformat("--%{NAME}%{VERSION}--") ne 'NOT A MATCH'); ok(!$pkg->is_source_package); $pkg = RPM2->open_package("test-rpm-1.0-1.src.rpm"); ok($pkg); ok($pkg->name eq 'test-rpm'); +ok($pkg->tagformat("--%{NAME}--") eq '--test-rpm--'); ok($pkg->is_source_package); my $pkg2 = RPM2->open_package("test-rpm-1.0-1.noarch.rpm"); diff --git a/perl-RPM2/typemap b/perl-RPM2/typemap index f8bfedeb6..f93ef29a6 100644 --- a/perl-RPM2/typemap +++ b/perl-RPM2/typemap @@ -1,11 +1,10 @@ TYPEMAP -rpmTransaction * O_OBJECT -rpmdb O_OBJECT -rpmdbMatchIterator O_OBJECT -Header O_OBJECT +rpmdb O_OBJECT_rpmdb +rpmdbMatchIterator O_OBJECT_rpmmi +Header O_OBJECT_header INPUT -O_OBJECT +O_OBJECT_rpmdb if (sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG)) $var = ($type)SvIV((SV*)SvRV( $arg )); else { @@ -13,8 +12,26 @@ O_OBJECT XSRETURN_UNDEF; } +O_OBJECT_rpmmi + if (sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG)) + $var = ($type)SvIV((SV*)SvRV( $arg )); + else { + warn( \"${Package}::$func_name() -- $var is not a blessed SV reference\" ); + XSRETURN_UNDEF; + } +O_OBJECT_header + if (sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG)) + $var = ($type)SvIV((SV*)SvRV( $arg )); + else { + warn( \"${Package}::$func_name() -- $var is not a blessed SV reference\" ); + XSRETURN_UNDEF; + } OUTPUT -O_OBJECT - sv_setref_pv( $arg, (char *)CLASS, (void*)$var ); +O_OBJECT_rpmdb + sv_setref_pv( $arg, "RPM2::C::DB", (void*)$var ); +O_OBJECT_rpmmi + sv_setref_pv( $arg, "RPM2::C::PackageIterator", (void*)$var ); +O_OBJECT_header + sv_setref_pv( $arg, "RPM2::C::Header", (void*)$var );