summaryrefslogtreecommitdiff
path: root/perllib/Debian/PkgKde/SymbolsHelper/SymbolFile.pm
diff options
context:
space:
mode:
authorModestas Vainius <modestas@vainius.eu>2010-03-16 00:32:16 +0200
committerModestas Vainius <modestas@vainius.eu>2010-03-16 00:32:16 +0200
commitedd5387961a5b01efba9b63ec3d9187462c246ef (patch)
treeb3437ec2c7fe2ef3c7a0198fffd3bb2fca66973b /perllib/Debian/PkgKde/SymbolsHelper/SymbolFile.pm
parentd750b7bdd629cbec8560d8fbb0d133e5982c7e79 (diff)
downloadpkg-kde-tools-edd5387961a5b01efba9b63ec3d9187462c246ef.tar.gz
Reorganize source package directory structure.
- get rid of symbolshelper, debhelper, vcs subdirectires. Move perl modules to perllib subdirectory and the rest to the top of the source tree; - unify how datalibdir is found and exported in the Debian::PkgKde module ({find,setup}_datalibdir()). Make pkgkde-gensymbols and pkgkde-symbolshelper use these new subroutines; - change datalib path in pkgkde-deb2symbols; - rewrite Makefile for reorganized source tree.
Diffstat (limited to 'perllib/Debian/PkgKde/SymbolsHelper/SymbolFile.pm')
-rw-r--r--perllib/Debian/PkgKde/SymbolsHelper/SymbolFile.pm320
1 files changed, 320 insertions, 0 deletions
diff --git a/perllib/Debian/PkgKde/SymbolsHelper/SymbolFile.pm b/perllib/Debian/PkgKde/SymbolsHelper/SymbolFile.pm
new file mode 100644
index 0000000..97037a9
--- /dev/null
+++ b/perllib/Debian/PkgKde/SymbolsHelper/SymbolFile.pm
@@ -0,0 +1,320 @@
+# Copyright (C) 2008-2010 Modestas Vainius <modax@debian.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>
+
+package Debian::PkgKde::SymbolsHelper::SymbolFile;
+
+use strict;
+use warnings;
+use base 'Dpkg::Shlibs::SymbolFile';
+
+use File::Temp qw();
+use File::Copy qw();
+use Storable qw();
+use IO::Handle;
+use Dpkg::ErrorHandling;
+use Dpkg::Version;
+use Debian::PkgKde::SymbolsHelper::Symbol;
+use Debian::PkgKde::SymbolsHelper::Substs;
+
+# Use Debian::PkgKde::SymbolsHelper::Symbol as base symbol
+sub parse {
+ my ($self, $fh, $file, $seen, $obj_ref, $base_symbol) = @_;
+ unless (defined $base_symbol) {
+ $base_symbol = 'Debian::PkgKde::SymbolsHelper::Symbol';
+ }
+ if (!defined $seen) {
+ # Read 'SymbolsHelper-Confirmed' header
+ open(my $fh, "<", $file)
+ or error("unable to open symbol file '$file' for reading");
+ my $line = <$fh>;
+ close $fh;
+
+ chop $line;
+ if ($line =~ /^#\s*SymbolsHelper-Confirmed:\s+(.+)$/) {
+ $self->set_confirmed(split(/\s+/, $1));
+ }
+ }
+ return $self->SUPER::parse($fh, $file, $seen, $obj_ref, $base_symbol);
+}
+
+sub set_confirmed {
+ my ($self, $version, @arches) = @_;
+ $self->{h_confirmed_version} = $version;
+ $self->{h_confirmed_arches} = (@arches) ? \@arches : undef;
+}
+
+sub get_confirmed_version {
+ my $self = shift;
+ return $self->{h_confirmed_version};
+}
+
+sub get_confirmed_arches {
+ my $self = shift;
+ return (defined $self->{h_confirmed_arches}) ?
+ @{$self->{h_confirmed_arches}} : ();
+}
+
+sub create_symbol {
+ my ($self, $spec, %opts) = @_;
+ $opts{base} = Debian::PkgKde::SymbolsHelper::Symbol->new()
+ unless exists $opts{base};
+ return $self->SUPER::create_symbol($spec, %opts);
+}
+
+sub fork_symbol {
+ my ($self, $sym, $arch) = @_;
+ $arch = $self->get_arch() unless $arch;
+ my $nsym = $sym->clone(symbol => $sym->get_symboltempl());
+ $nsym->initialize(arch => $arch);
+ return $nsym;
+}
+
+sub output {
+ my ($self, $fh, %opts) = @_;
+ $opts{with_confirmed} = 1 unless exists $opts{with_confirmed};
+ # Write SymbolsHelper-Confirmed header
+ if ($opts{with_confirmed}) {
+ my @carches = $self->get_confirmed_arches();
+ if (@carches) {
+ print $fh '# SymbolsHelper-Confirmed: ', $self->get_confirmed_version(),
+ " ", join(" ", sort @carches), "\n" if defined $fh;
+ }
+ }
+ return $self->SUPER::output($fh, %opts);
+}
+
+sub _resync_symbol_cache {
+ my ($self, $soname, $cache) = @_;
+ my %rename;
+
+ foreach my $symkey (keys %$cache) {
+ my $sym = $cache->{$symkey};
+ if ($sym->get_symbolname() ne $symkey) {
+ $rename{$sym->get_symbolname()} = $sym;
+ delete $cache->{$symkey};
+ }
+ }
+ foreach my $newname (keys %rename) {
+ my $e = $self->get_symbol_object($rename{$newname}, $soname);
+ if ($e && ! $rename{$newname}->equals($e)) {
+ warning("caution: newly generated symbol '%s' will replace not exactly equal '%s'. Please readd if unappropriate",
+ $rename{$newname}->get_symbolspec(1),
+ $e->get_symbolspec(1));
+ }
+ $self->add_symbol($rename{$newname}, $soname);
+ }
+}
+
+sub resync_soname_symbol_caches {
+ my ($self, $soname) = @_;
+ my $obj = $self->get_object($soname);
+
+ # We need this to avoid removal of symbols which names clash when renaming
+ $self->_resync_symbol_cache($obj, $obj->{syms});
+
+ # Resync aliases too
+ foreach my $alias (values %{$obj->{patterns}{aliases}}) {
+ $self->_resync_symbol_cache($obj, $alias);
+ }
+}
+
+sub resync_soname_with_h_name {
+ my ($self, $soname) = @_;
+ my $obj = $self->get_object($soname);
+
+ sub _resync_with_h_name {
+ my $cache = shift;
+ foreach my $symkey (keys %$cache) {
+ $cache->{$symkey}->resync_name_with_h_name();
+ }
+ }
+
+ # First resync h_name with symbol name and templ
+ _resync_with_h_name($obj->{syms});
+ foreach my $alias (values %{$obj->{patterns}{aliases}}) {
+ _resync_with_h_name($alias);
+ }
+ return $self->resync_soname_symbol_caches($soname);
+}
+
+# Detects (or just neutralizes) substitutes which can be guessed from the
+# symbol name alone. Currently unused.
+#sub detect_standalone_substs {
+# my ($self, $detect) = @_;
+#
+# foreach my $sym ($self->get_symbols()) {
+# my $str = $sym->get_h_name();
+# foreach my $subst (@STANDALONE_SUBSTS) {
+# if ($detect) {
+# $subst->detect($str, $self->{arch});
+# } else {
+# $subst->neutralize($str);
+# }
+# }
+# }
+# foreach my $soname (keys %{$self->{objects}}) {
+# # Rename soname object with data in h_name
+# $self->resync_soname_with_h_name($soname);
+# }
+#}
+
+# Upgrade virtual table symbols. Needed for templating.
+sub prepare_for_templating {
+ my $self = shift;
+ my %sonames;
+
+ foreach my $soname ($self->get_sonames()) {
+ foreach my $sym ($self->get_symbols($soname)) {
+ if ($sym->upgrade_virtual_table_symbol($self->get_arch())) {
+ $sonames{$soname} = 1;
+ }
+ }
+ }
+
+ foreach my $soname (keys %sonames) {
+ $self->resync_soname_symbol_caches($soname);
+ }
+}
+
+sub patch_template {
+ my ($self, @patches) = @_;
+ my @symfiles;
+ my %dumped;
+
+ foreach my $patch (@patches) {
+ my $package = $patch->{package} || '';
+ my $tmpfile;
+ if (!exists $dumped{$package}) {
+ $tmpfile = File::Temp->new(
+ TEMPLATE => "${package}_orig.symbolsXXXXXX",
+ UNLINK => 0,
+ );
+ $self->output($tmpfile,
+ package => $package,
+ template_mode => 1,
+ with_confirmed => 0,
+ );
+ $tmpfile->close();
+ $dumped{$package} = $tmpfile->filename;
+ }
+ $tmpfile = File::Temp->new(
+ TEMPLATE => "${package}_patched.symbolsXXXXXX",
+ UNLINK => 1,
+ );
+ $tmpfile->close();
+ unless (File::Copy::copy($dumped{$package}, $tmpfile->filename)) {
+ syserror("unable to copy file '%s' to '%s'",
+ $dumped{$package}, $tmpfile->filename);
+ }
+ if ($patch->apply($tmpfile->filename)) {
+ # Patching was successful. Parse new SymbolFile and return it
+ my $symfile = Debian::PkgKde::SymbolsHelper::SymbolFile->new(
+ file => $tmpfile->filename,
+ arch => $patch->{arch},
+ );
+ if ($patch->has_info()) {
+ $symfile->set_confirmed($patch->{version}, $patch->{arch});
+ } else {
+ $symfile->set_confirmed(undef);
+ }
+ push @symfiles, $symfile;
+ last unless wantarray;
+ }
+ }
+ foreach my $file (values %dumped) {
+ unless ($FILE::Temp::KEEP_ALL) {
+ unlink $file;
+ }
+ }
+ return (wantarray) ? @symfiles : $symfiles[0];
+}
+
+sub _dclone_exclude {
+ my ($target, @exclude) = @_;
+ my %saved;
+ foreach my $e (@exclude) {
+ if (exists $target->{$e}) {
+ $saved{$e} = $target->{$e};
+ delete $target->{$e};
+ }
+ }
+ my $clone = Storable::dclone($target);
+ $target->{$_} = $saved{$_} foreach @exclude;
+ return $clone;
+}
+
+# Forks an empty symbol file (without symbols and patterns) from the current
+# one. Other properties are retained.
+sub fork_empty {
+ my $self = shift;
+
+ my $symfile = _dclone_exclude($self, qw(objects));
+ $symfile->clear();
+ foreach my $soname ($self->get_sonames()) {
+ $symfile->create_object($soname);
+ my $obj = $symfile->get_object($soname);
+ my $cloned = _dclone_exclude($self->get_object($soname),
+ qw(syms patterns minver_cache));
+ $obj->{$_} = $cloned->{$_} foreach keys %$cloned;
+ }
+ return $symfile;
+}
+
+sub fork {
+ my ($self, @optinstances) = @_;
+ unshift @optinstances, {} unless @optinstances;
+ @optinstances = ( $optinstances[0] ) unless wantarray;
+
+ my @symfiles;
+ foreach my $opts (@optinstances) {
+ my $symfile = $self->fork_empty();
+ $symfile->{$_} = $opts->{$_} foreach keys %$opts;
+ $symfile->{file} = '';
+ push @symfiles, $symfile;
+ }
+
+ # Fork symbols
+ foreach my $soname ($self->get_sonames()) {
+ foreach my $sym ($self->get_symbols($soname),
+ $self->get_patterns($soname))
+ {
+ foreach my $symfile (@symfiles) {
+ my $nsym = $self->fork_symbol($sym, $symfile->get_arch());
+ $nsym->{h_origin_symbol} = $sym;
+ $symfile->add_symbol($nsym, $soname);
+ }
+ }
+ }
+ return (wantarray) ? @symfiles : shift @symfiles;
+}
+
+
+sub get_highest_version {
+ my $self = shift;
+ my $maxver;
+
+ foreach my $sym ($self->get_symbols(),
+ $self->get_patterns()) {
+ if (!$sym->{deprecated} &&
+ (!defined $maxver || version_compare($sym->{minver}, $maxver) > 0))
+ {
+ $maxver = $sym->{minver};
+ }
+ }
+
+ return $maxver;
+}
+
+1;