rev 12691 - in branches/kde4.2/packages/pkg-kde-tools/trunk: . debian symbolshelper symbolshelper/Debian symbolshelper/Debian/PkgKde symbolshelper/Debian/PkgKde/SymHelper symbolshelper/Debian/PkgKde/SymHelper/Handler

Modestas Vainius modax-guest at alioth.debian.org
Thu Nov 20 19:04:38 UTC 2008


Author: modax-guest
Date: 2008-11-20 19:04:38 +0000 (Thu, 20 Nov 2008)
New Revision: 12691

Added:
   branches/kde4.2/packages/pkg-kde-tools/trunk/Makefile
   branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/
   branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/
   branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/
   branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper.pm
   branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/
   branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/CompileTest.pm
   branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/
   branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/Base.pm
   branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/SimpleTypeDiff.pm
   branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/VirtTable.pm
   branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/qreal.pm
   branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/size_t.pm
   branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/ssize_t.pm
   branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handlers.pm
   branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/SymbFile.pm
   branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Symbol.pm
   branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Symbol2.pm
   branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/pkgkde-symbolshelper
Modified:
   branches/kde4.2/packages/pkg-kde-tools/trunk/debian/changelog
   branches/kde4.2/packages/pkg-kde-tools/trunk/debian/control
   branches/kde4.2/packages/pkg-kde-tools/trunk/debian/copyright
   branches/kde4.2/packages/pkg-kde-tools/trunk/debian/rules
Log:
pkgkde-symbolshelper

Added: branches/kde4.2/packages/pkg-kde-tools/trunk/Makefile
===================================================================
--- branches/kde4.2/packages/pkg-kde-tools/trunk/Makefile	                        (rev 0)
+++ branches/kde4.2/packages/pkg-kde-tools/trunk/Makefile	2008-11-20 19:04:38 UTC (rev 12691)
@@ -0,0 +1,8 @@
+PERLLIBDIR := $(shell perl -MConfig -e 'print $$Config{vendorlib}')
+SYMBOLSHELPER_DIR := symbolshelper
+
+install:
+	install -d $(DESTDIR)/usr/bin
+	cd $(SYMBOLSHELPER_DIR) && find Debian -type f -name "*.pm" -exec \
+	    install -D -m 0644 {} $(DESTDIR)/$(PERLLIBDIR)/{} \;
+	install -m 0755 $(SYMBOLSHELPER_DIR)/pkgkde-symbolshelper $(DESTDIR)/usr/bin

Modified: branches/kde4.2/packages/pkg-kde-tools/trunk/debian/changelog
===================================================================
--- branches/kde4.2/packages/pkg-kde-tools/trunk/debian/changelog	2008-11-20 12:59:09 UTC (rev 12690)
+++ branches/kde4.2/packages/pkg-kde-tools/trunk/debian/changelog	2008-11-20 19:04:38 UTC (rev 12691)
@@ -1,3 +1,15 @@
+pkg-kde-tools (0.3~pre3) UNRELEASED; urgency=low
+
+  * Add pkgkde-symbolshelper. It aims to make handling of symbols in
+    C++ libraries easier. Symbols in C++ libraries are inconsistent among
+    arches due to mangling and other issues.
+    - Add GPL3 notice to debian/copyright which pkgkde-symbolshelper is under.
+  * Add myself to Uploaders.
+  * Tweak description.
+  * Add DM-Upload-Allowed: yes.
+
+ -- Modestas Vainius <modestas at vainius.eu>  Thu, 20 Nov 2008 19:05:22 +0200
+
 pkg-kde-tools (0.2) unstable; urgency=low
 
   * The no .svn dir in release release.

Modified: branches/kde4.2/packages/pkg-kde-tools/trunk/debian/control
===================================================================
--- branches/kde4.2/packages/pkg-kde-tools/trunk/debian/control	2008-11-20 12:59:09 UTC (rev 12690)
+++ branches/kde4.2/packages/pkg-kde-tools/trunk/debian/control	2008-11-20 19:04:38 UTC (rev 12691)
@@ -4,16 +4,19 @@
 Maintainer: Debian Qt/KDE Maintainers <debian-qt-kde at lists.debian.org>
 Build-Depends: debhelper (>= 5)
 Standards-Version: 3.8.0
-Uploaders: Sune Vuorela <debian at pusling.com>
+Uploaders: Sune Vuorela <debian at pusling.com>, Modestas Vainius <modestas at vainius.eu>
+DM-Upload-Allowed: yes
 
 Package: pkg-kde-tools
 Architecture: all
+Depends: ${perl:Depends}
 Suggests: debhelper, cdbs
-Description: common makesnippets and other build scripts for KDE4 related packages
- This package contains makefiles setting the default build arguments for KDE4 
+Description: common makesnippets and build scripts for KDE4 related packages
+ This package contains makefiles setting the default build arguments for KDE4
  packages.
  .
- Currently, it is only a few makesnippets, but it will grow larger in the future.
+ Currently, it contains a few makesnippets, and pkgkde-symbolshelper tool,
+ but it will grow larger in the future.
  .
  NOTE: if you use cdbs or debhelper, you need to build-depend on those as well,
  as this package is expected to be useful in cases without debhelper or cdbs.

Modified: branches/kde4.2/packages/pkg-kde-tools/trunk/debian/copyright
===================================================================
--- branches/kde4.2/packages/pkg-kde-tools/trunk/debian/copyright	2008-11-20 12:59:09 UTC (rev 12690)
+++ branches/kde4.2/packages/pkg-kde-tools/trunk/debian/copyright	2008-11-20 19:04:38 UTC (rev 12691)
@@ -17,7 +17,7 @@
     Copyright 2007-2008 Ana Beatriz Guerrero Lopez <ana at debian.org>
     Copyright 2007-2008 Armin Berres <trigger+debian at space-based.de>
 
-License:
+License (unless stated otherwise in the following paragraphs):
 
     This package is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -36,5 +36,26 @@
 On Debian systems, the complete text of the GNU General
 Public License can be found in `/usr/share/common-licenses/GPL-2'.
 
+The license and copyright for the software under "symbolshelper"
+directory are:
+
+    Copyright (C) 2008 Modestas Vainius <modestas at vainius.eu>
+
+    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/>
+
+On Debian systems, the complete text of the GNU General
+Public License can be found in `/usr/share/common-licenses/GPL-3'.
+
 The Debian packaging is (C) 2008, Sune Vuorela <debian at pusling.com> and
 is licensed under any license, including the GPL, see above.

Modified: branches/kde4.2/packages/pkg-kde-tools/trunk/debian/rules
===================================================================
--- branches/kde4.2/packages/pkg-kde-tools/trunk/debian/rules	2008-11-20 12:59:09 UTC (rev 12690)
+++ branches/kde4.2/packages/pkg-kde-tools/trunk/debian/rules	2008-11-20 19:04:38 UTC (rev 12691)
@@ -13,6 +13,7 @@
 binary-indep:
 	dh_testdir
 	dh_testroot
+	$(MAKE) install DESTDIR=$(CURDIR)/debian/`dh_listpackages | head -n1`
 	dh_installchangelogs 
 	dh_installdocs
 	dh_installexamples
@@ -21,6 +22,7 @@
 	#if triggered, please build source package with -I
 	test ! -e $(CURDIR)/debian/pkg-kde-tools/usr/share/pkg-kde-tools/makefiles/1/.svn/
 	dh_link
+	dh_perl
 	dh_strip
 	dh_compress
 	dh_fixperms

Added: branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/CompileTest.pm
===================================================================
--- branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/CompileTest.pm	                        (rev 0)
+++ branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/CompileTest.pm	2008-11-20 19:04:38 UTC (rev 12691)
@@ -0,0 +1,70 @@
+package Debian::PkgKde::SymHelper::CompileTest;
+
+use strict;
+use warnings;
+use File::Temp qw(tempdir);
+use File::Spec;
+use Debian::PkgKde::SymHelper qw(error);
+
+sub new {
+    my ($cls, $compiler, $lib) = @_;
+
+    my $tmpdir = tempdir();
+    my $sourcefile = "testcomp";
+    my $out = "testcomp";
+    my $cmd;
+
+    error("Unable to create a temporary directory for test compilation") unless $tmpdir;
+
+    if ($compiler =~ /gcc/) {
+        $sourcefile .= ".c";
+    } elsif ($compiler =~ /g\+\+/) {
+        $sourcefile  .= ".cpp";
+    } else {
+        error("Unrecognized compiler: $compiler");
+    }
+    $sourcefile = File::Spec::catfile($tmpdir, $sourcefile);
+
+    if ($lib) {
+        $cmd = "$compiler -shared -fPIC";
+        $out .= ".so";
+    } else {
+        $cmd = "$compiler";
+    }
+    $out = File::Spec::catfile($tmpdir, $out);
+
+    my $self = bless { tmpdir => $tmpdir,
+        sourcefile => $sourcefile, out => $out }, $cls;
+    $self->set_cmd($cmd);
+    return $self;
+}
+
+sub set_cmd {
+    my ($self, $cmd) = @_;
+    $self->{cmd} = "$cmd $self->{sourcefile} -o $self->{out}";
+}
+
+sub compile {
+    my ($self, $sourcecode) = @_;
+
+    open(SOURCE, ">", $self->{sourcefile})
+        or error("Unable to open temporary source file for writing: $self->{sourcefile}");
+    print SOURCE $sourcecode
+        or error("Unable to write to temporary source file $self->{sourcefile}");
+    close(SOURCE);
+
+    system($self->{cmd}) == 0 or error("Compilation failed: $self->{cmd}");
+    return $self->get_output_file();
+}
+
+sub get_output_file {
+    my $self = shift;
+    return (-f $self->{out}) ? $self->{out} : undef;
+}
+
+sub rm {
+    my $self = shift;
+    system("rm -rf $self->{tmpdir}") == 0 or error("Unable to delete temporary directory: $self->{tmpdir}");
+}
+
+1;

Added: branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/Base.pm
===================================================================
--- branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/Base.pm	                        (rev 0)
+++ branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/Base.pm	2008-11-20 19:04:38 UTC (rev 12691)
@@ -0,0 +1,86 @@
+package Debian::PkgKde::SymHelper::Handler::Base;
+
+use strict;
+use warnings;
+use Debian::PkgKde::SymHelper qw(error warning);
+
+sub new {
+    my ($cls, $arch) = @_;
+    my $self = bless {
+        arch => undef,
+    }, $cls;
+    $self->set_arch($arch);
+    return $self;
+}
+
+sub get_host_arch {
+    my $arch = `dpkg-architecture -qDEB_HOST_ARCH_CPU`;
+    chomp $arch;
+    return $arch;
+}
+
+sub set_arch {
+    my ($self, $arch) = @_;
+    $arch = get_host_arch() unless defined $arch;
+
+    error("Unknown architecture: $arch") unless grep($arch, @Debian::PkgKde::SymHelper::ARCHES);
+
+    my $arch_params;
+    $self->{"${arch}_params"} = $arch_params
+        if ($arch_params = $self->get_predef_arch_params($arch));
+    $self->{arch} = $arch;
+}
+
+sub _preload_arch_params {
+    my $self = shift;
+    foreach my $arch (@_) {
+        $self->{"${arch}_params"} = $self->get_predef_arch_params($arch);
+    }
+}
+
+sub get_arch_param {
+    my ($self, $name, $arch) = @_;
+    $arch = $self->{arch} unless defined $arch;
+
+    $self->_preload_arch_params($arch) unless (exists $self->{"${arch}_params"});
+    return $self->{"${arch}_params"}{$name};
+}
+
+sub dump_arch_params {
+    my ($self, $arch) = @_;
+    $arch = $self->{arch} unless defined $arch;
+
+    if (exists $self->{"${arch}_params"}) {
+        print "Arch: $arch", "\n";
+        foreach my $key (keys %{$self->{"${arch}_params"}}) {
+           print "$key: ", $self->get_arch_param($key, $arch), "\n";
+        }
+    }
+}
+
+sub get_host_arch_params {
+    my $self = shift;
+    return undef;
+}
+
+sub get_predef_arch_params {
+    my ($self, $arch) = @_;
+    return undef;
+}
+
+sub clean {
+    my ($self, $sym) = @_;
+    return $sym;
+}
+
+sub detect {
+    my ($self, $symversions) = @_;
+    return undef;
+}
+
+sub replace {
+    my ($self, $substvar, $sym) = @_;
+    return undef;
+}
+
+1;

Added: branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/SimpleTypeDiff.pm
===================================================================
--- branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/SimpleTypeDiff.pm	                        (rev 0)
+++ branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/SimpleTypeDiff.pm	2008-11-20 19:04:38 UTC (rev 12691)
@@ -0,0 +1,63 @@
+package Debian::PkgKde::SymHelper::Handler::SimpleTypeDiff;
+our @ISA = qw( Debian::PkgKde::SymHelper::Handler::Base );
+
+use strict;
+use warnings;
+use Debian::PkgKde::SymHelper::Handler::Base;
+
+sub new {
+    return Debian::PkgKde::SymHelper::Handler::Base::new(@_);
+}
+
+sub clean {
+    my ($self, $symbol) = @_;
+    my $sym = $symbol->get_symbol();
+    my $ret = 0;
+    while ($sym =~ m/$self->{type_re}/g) {
+        $symbol->substr(pos($sym)-1, 1, $self->{main_type});
+        $ret = 1;
+    }
+    return $ret;
+}
+
+sub detect {
+    my ($self, $main_symbol, $archsymbols) = @_;
+
+    my $s1 = $main_symbol->get_symbol();
+    my $t1 = $self->get_arch_param("type", $main_symbol->get_arch());
+    my ($s2, $t2, $a2);
+
+    # Find architecture with other type
+    while (($a2, my $symbol) = each(%$archsymbols)) {
+        $t2 = $self->get_arch_param("type", $a2);
+        if ($t2 ne $t1) {
+            $s2 = $symbol->get_symbol();
+            last;
+        }
+    }
+
+    return 0 unless defined $s2;
+
+    # Compare letter by letter until difference is found
+    my @s1 = split(//, $s1);
+    my @s2 = split(//, $s2);
+    my $ret = 0;
+    for (my $i = 0; $i <= $#s1; $i++) {
+        if ($s1[$i] eq $t1 && $s2[$i] eq $t2) {
+            $main_symbol->substr($i, 1, $self->{main_type}, $self->{substvar});
+            $ret = 1;
+        }
+    }
+    return $ret;
+}
+
+sub replace {
+    my ($self, $substvar) = @_;
+    if ($substvar =~ /^$self->{substvar}$/) {
+        return $self->get_arch_param("type");
+    } else {
+        return undef;
+    }
+}
+
+1;

Added: branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/VirtTable.pm
===================================================================
--- branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/VirtTable.pm	                        (rev 0)
+++ branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/VirtTable.pm	2008-11-20 19:04:38 UTC (rev 12691)
@@ -0,0 +1,116 @@
+package Debian::PkgKde::SymHelper::Handler::VirtTable;
+our @ISA = qw( Debian::PkgKde::SymHelper::Handler::Base );
+
+use Debian::PkgKde::SymHelper::CompileTest;
+use Debian::PkgKde::SymHelper qw(error);
+
+sub get_host_arch_params {
+    my $params = {};
+    my $c = new Debian::PkgKde::SymHelper::CompileTest("gcc");
+    my $exe = $c->compile("#include <stdio.h>\nint main() { printf \"%d\\n\", sizeof(void*) \ 4; }");
+    $params->{mult} = `$exe`;
+    $c->rm();
+    return $params;
+}
+
+sub get_predef_arch_params {
+    my ($self, $arch) = @_;
+
+    # Mult should be 1 on 32bit arches and 2 on 64bit arches and so on
+    my $params = { mult => 1 };
+    $params->{mult} = 2 if ($arch =~ /amd64|ia64|alpha/);
+    return $params;
+}
+
+sub subvt {
+    my ($self, $symbol, $number, $stroffset) = @_;
+    my $l = length("$number");
+
+    if ((my $mult = $self->get_arch_param("mult", $symbol->get_arch())) > 1) {
+        $number /= $mult;
+    }
+    $symbol->substr($stroffset, $l, "$number", "{vt:$number}");
+    return 1;
+}
+
+sub find_ztc_offset {
+    my ($self, $symbol) = @_;
+
+    # The idea behind the algorithm is that c++filt output does not
+    # change when offset is changed.
+    # e.g. _ZTCN6KParts15DockMainWindow3E56_NS_8PartBaseE
+
+    my @matches = ($symbol =~ m/(\d+)_/gc);
+    if (!@matches) {
+        error("Invalid construction table symbol: $symbol");
+    } elsif (@matches == 1) {
+        # Found it
+        return (pos($symbol) - length($1) - 1, $1);
+    } else {
+        # The idea behind the algorithm is that c++filt output does not
+        # change when an offset is changed.
+        $symbol =~ s/@[^@]+$//;
+        my $demangled = `c++filt '$symbol'`;
+        pos($symbol) = undef;
+        while ($symbol =~ m/(\d+)_/g) {
+            my $offset = $1;
+            my $pos = pos($symbol) - length($offset) - 1;
+            my $newsymbol = $symbol; 
+            substr($newsymbol, $pos, length($offset)) = $offset + 1234;
+            my $newdemangled = `c++filt '$newsymbol'`;
+            return ($pos, $offset) if ($demangled eq $newdemangled);
+        }
+        error("Unable to determine construction table offset position in symbol '$symbol'");
+    }
+}
+
+sub diff_symbol {
+    my ($self, $symbol) = @_;
+    my @diffs;
+    my $sym = $symbol->get_symbol();
+    my $ret = 0;
+
+    # construction vtable: e.g. _ZTCN6KParts15DockMainWindow3E56_NS_8PartBaseE
+    if ($sym =~ /^_ZTC/) {
+        my ($pos, $num) = $self->find_ztc_offset($sym);
+        $ret = $self->subvt($symbol, $num, $pos) if ($num > 0);
+    } elsif ($sym =~ /^_ZThn(\d+)_/) {
+        # non-virtual base override: e.g. _ZThn8_N6KParts13ReadWritePartD0Ev
+        my $num = $1;
+        $ret = $self->subvt($symbol, $num, 5) if ($num > 0);
+    } elsif ($sym =~ /^_ZTvn?(\d+)_(n?\d+)/) {
+        # virtual base override, with vcall offset, e.g. _ZTv0_n12_N6KParts6PluginD0Ev
+        my $voffset = $1;
+        my $num = $2;
+        my $numoffset = 4 + length("$voffset") + 1 + (($num =~ /^n/) ? 1 : 0);
+        $num =~ s/^n//;
+
+        $ret = $self->subvt($symbol, $voffset, 4) if ($voffset > 0);
+        $ret = $self->subvt($symbol, $num, $numoffset) || $ret if ($num > 0);
+    } 
+    return $ret;
+}
+
+sub clean {
+    my $self = shift;
+    return $self->diff_symbol(@_);
+}
+
+sub detect {
+    my ($self, $symbol) = @_;
+    return $self->diff_symbol($symbol);
+}
+
+sub replace {
+    my ($self, $substvar, $sym) = @_;
+    # vt:$number
+    if ($substvar =~ /^{vt:(\d+)}$/) {
+        my $number = $1;
+        $number *= $self->get_arch_param("mult");
+        return "$number";
+    } else {
+        return undef;
+    }
+}
+
+1;

Added: branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/qreal.pm
===================================================================
--- branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/qreal.pm	                        (rev 0)
+++ branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/qreal.pm	2008-11-20 19:04:38 UTC (rev 12691)
@@ -0,0 +1,25 @@
+package Debian::PkgKde::SymHelper::Handler::qreal;
+our @ISA = qw( Debian::PkgKde::SymHelper::Handler::SimpleTypeDiff );
+
+use strict;
+use warnings;
+use Debian::PkgKde::SymHelper::Handler::SimpleTypeDiff; 
+
+sub new {
+    my $self = Debian::PkgKde::SymHelper::Handler::SimpleTypeDiff::new(@_);
+    $self->{substvar} = "{qreal}";
+    $self->{main_type} = "d"; # unsigned int
+    $self->{type_re} = "[fd]";
+    return $self;
+}
+
+sub get_predef_arch_params {
+    my ($self, $arch) = @_;
+
+    # Mult should be 1 on 32bit arches and 2 on 64bit arches and so on
+    my $params = { type => "d" }; # int
+    $params->{type} = "f" if ($arch =~ /arm/); # unsigned long
+    return $params;
+}
+
+1;

Added: branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/size_t.pm
===================================================================
--- branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/size_t.pm	                        (rev 0)
+++ branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/size_t.pm	2008-11-20 19:04:38 UTC (rev 12691)
@@ -0,0 +1,25 @@
+package Debian::PkgKde::SymHelper::Handler::size_t;
+our @ISA = qw( Debian::PkgKde::SymHelper::Handler::SimpleTypeDiff );
+
+use strict;
+use warnings;
+use Debian::PkgKde::SymHelper::Handler::SimpleTypeDiff; 
+
+sub new {
+    my $self = Debian::PkgKde::SymHelper::Handler::SimpleTypeDiff::new(@_);
+    $self->{substvar} = "{size_t}";
+    $self->{main_type} = "j"; # unsigned int
+    $self->{type_re} = "[jm]";
+    return $self;
+}
+
+sub get_predef_arch_params {
+    my ($self, $arch) = @_;
+
+    # Mult should be 1 on 32bit arches and 2 on 64bit arches and so on
+    my $params = { type => "j" }; # unsigned int
+    $params->{type} = "m" if ($arch =~ /amd64|ia64|alpha|s390/); # unsigned long
+    return $params;
+}
+
+1;

Added: branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/ssize_t.pm
===================================================================
--- branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/ssize_t.pm	                        (rev 0)
+++ branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handler/ssize_t.pm	2008-11-20 19:04:38 UTC (rev 12691)
@@ -0,0 +1,25 @@
+package Debian::PkgKde::SymHelper::Handler::ssize_t;
+our @ISA = qw( Debian::PkgKde::SymHelper::Handler::SimpleTypeDiff );
+
+use strict;
+use warnings;
+use Debian::PkgKde::SymHelper::Handler::SimpleTypeDiff; 
+
+sub new {
+    my $self = Debian::PkgKde::SymHelper::Handler::SimpleTypeDiff::new(@_);
+    $self->{substvar} = "{ssize_t}";
+    $self->{main_type} = "i"; # unsigned int
+    $self->{type_re} = "[il]";
+    return $self;
+}
+
+sub get_predef_arch_params {
+    my ($self, $arch) = @_;
+
+    # Mult should be 1 on 32bit arches and 2 on 64bit arches and so on
+    my $params = { type => "i" }; # int
+    $params->{type} = "l" if ($arch =~ /amd64|ia64|alpha|s390/); # unsigned long
+    return $params;
+}
+
+1;

Added: branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handlers.pm
===================================================================
--- branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handlers.pm	                        (rev 0)
+++ branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Handlers.pm	2008-11-20 19:04:38 UTC (rev 12691)
@@ -0,0 +1,368 @@
+package Debian::PkgKde::SymHelper::Handlers;
+
+use strict;
+use warnings;
+use File::Temp qw(tempfile);
+use Debian::PkgKde::SymHelper::Handler::VirtTable;
+use Debian::PkgKde::SymHelper::Handler::size_t;
+use Debian::PkgKde::SymHelper::Handler::ssize_t;
+use Debian::PkgKde::SymHelper::Handler::qreal;
+use Debian::PkgKde::SymHelper::Symbol;
+use Debian::PkgKde::SymHelper::Symbol2;
+use Debian::PkgKde::SymHelper qw(info error warning);
+
+sub new {
+    my $cls = shift;
+    my @standalone_substitution = (
+        new Debian::PkgKde::SymHelper::Handler::VirtTable,
+    );
+    my @substitution = (
+        @standalone_substitution,
+        new Debian::PkgKde::SymHelper::Handler::size_t,
+        new Debian::PkgKde::SymHelper::Handler::ssize_t,
+        new Debian::PkgKde::SymHelper::Handler::qreal,
+    );
+    return bless { subst => \@substitution,
+                   standalone_subst => \ @standalone_substitution }, $cls;
+}
+
+sub load_symbol_files {
+    my $self = shift;
+    my $files = shift;
+
+    return 0 if (exists $self->{symfiles});
+
+    while (my ($arch, $file) = each(%$files)) {
+        $self->add_symbol_file(new Debian::PkgKde::SymHelper::SymbFile($file), $arch);
+    }
+
+    # Set main architecture
+    $self->set_main_arch();
+
+    return scalar(keys %{$self->{symfiles}});
+}
+
+sub add_symbol_file {
+    my ($self, $symfile, $arch) = @_;
+    $arch = Debian::PkgKde::SymHelper::Handler::Base::get_host_arch() unless (defined $arch);
+
+    $self->{symfiles}{$arch} = $symfile;
+    $self->{main_arch} = $arch unless ($self->{main_arch});
+}
+
+sub get_main_arch {
+    my $self = shift;
+    return (exists $self->{main_arch}) ? $self->{main_arch} : undef;
+}
+
+sub set_main_arch {
+    my ($self, $arch) = @_;
+    $arch = Debian::PkgKde::SymHelper::Handler::Base::get_host_arch() unless defined $arch;
+    $self->{main_arch} = $arch if ($self->get_symfile($arch));
+}
+
+sub get_symfile {
+    my ($self, $arch) = @_;
+    if (exists $self->{symfiles}) {
+        $arch = $self->get_main_arch() unless defined $arch;
+        return (exists $self->{symfiles}{$arch}) ? $self->{symfiles}{$arch} : undef;
+    } else {
+        return undef;
+    }
+}
+
+sub cppfilt {
+    my $self = shift;
+    my @symfiles;
+
+    if (!@_) {
+        return 0 if (!exists $self->{symfiles} || exists $self->{cppfilt});
+        push @symfiles, values %{$self->{symfiles}};
+    } else {
+        push @symfiles, @_;
+    }
+
+    # Open temporary file
+    my ($fh, $filename) = File::Temp::tempfile();
+    if (defined $fh) {
+        # Dump cpp symbols to the temporary file
+        foreach my $symfile (@symfiles) {
+            $symfile->dump_cpp_symbols($fh);
+        }
+        close($fh);
+
+        # c++filt the symbols and load them
+        open(CPPFILT, "cat '$filename' | c++filt |") or main::error("Unable to run c++filt");
+        foreach my $symfile (@symfiles) {
+            $symfile->load_cppfilt_symbols(*CPPFILT);
+        }
+        close(CPPFILT);
+
+        # Remove temporary file
+        unlink($filename);
+
+        $self->{cppfilt} = 1 if (!@_);
+
+        return 1;
+    } else {
+        main::error("Unable to create a temporary file");
+    }
+}
+
+sub preprocess {
+    my $self = shift;
+    my $count = 0;
+
+    if (!@_) {
+        return 0 unless (exists $self->{symfiles});
+        $self->cppfilt();
+        push @_, values(%{$self->{symfiles}});
+    } else {
+        $self->cppfilt(@_);
+    }
+    foreach my $symfile (@_) {
+        $count += $symfile->deprecate_useless_symbols();
+    }
+    return $count;
+}
+
+sub get_group_name {
+    my ($self, $symbol, $arch) = @_;
+
+    my $osym = new Debian::PkgKde::SymHelper::Symbol($symbol, $arch);
+    foreach my $handler (@{$self->{subst}}) {
+        $handler->clean($osym);
+    }
+    return $osym->get_symbol();
+}
+
+sub create_template_standalone {
+    my $self = shift;
+
+    return undef unless (exists $self->{symfiles});
+
+    my $symfiles = $self->{symfiles};
+
+    while (my ($arch, $symfile) = each %$symfiles) {
+        while (my ($soname, $sonameobj) = each(%{$symfile->{objects}})) {
+            my @syms = keys(%{$sonameobj->{syms}});
+            for my $sym (@syms) {
+                my $symbol = new Debian::PkgKde::SymHelper::Symbol($sym, $arch);
+                my $symbol2 = new Debian::PkgKde::SymHelper::Symbol2($sym, $arch);
+                foreach my $handler (@{$self->{standalone_subst}}) {
+                    if ($handler->detect($symbol2)) {
+                        # Make symbol arch independent with regard to this handler
+                        $handler->clean($symbol);
+                    }
+                }
+                my $newsym = $symbol2->get_symbol2();
+                if ($sym ne $newsym) {
+                    # Rename symbol
+                    my $info = $sonameobj->{syms}{$sym};
+                    $sonameobj->{syms}{$newsym} = $info;
+                    delete $sonameobj->{syms}{$sym};
+                }
+            }
+        }
+    }
+    return $self->get_symfile();
+}
+
+sub create_template {
+    my $self = shift;
+
+    return undef unless (exists $self->{symfiles});
+
+    my $symfiles = $self->{symfiles};
+    my $main_arch = $self->get_main_arch();
+
+    # Collect new symbols from them by grouping them using the
+    # fully arch independent derivative name
+    my %symbols;
+    foreach my $arch1 (@Debian::PkgKde::SymHelper::ARCHES) {
+        next unless exists $symfiles->{$arch1};
+
+        foreach my $arch2 (@Debian::PkgKde::SymHelper::ARCHES) {
+            next if $arch1 eq $arch2;
+            next unless exists $symfiles->{$arch2};
+
+            my @new = $symfiles->{$arch1}->get_new_symbols($symfiles->{$arch2});
+            foreach my $n (@new) {
+                my $g = $self->get_group_name($n->{name}, $arch1);
+                my $s = $n->{soname};
+                if (exists $symbols{$s}{$g}{arches}{$arch1}) {
+                    if ($symbols{$s}{$g}{arches}{$arch1}->get_symbol() ne $n->{name}) {
+                        warning("at least two new symbols get to the same group ($g) on $s/$arch1:\n" .
+                            "  " . $symbols{$s}{$g}{arches}{$arch1}->get_symbol() . "\n" .
+                            "  " . $n->{name});
+                        # Ban group
+                        $symbols{$s}{$g}{banned} = 1;
+                    }
+                } else {
+                    $symbols{$s}{$g}{arches}{$arch1} = new Debian::PkgKde::SymHelper::Symbol($n->{name}, $arch1);
+                }
+            }
+        }
+    }
+
+    # Do substvar detection
+    my $arch_count = scalar(keys(%$symfiles));
+
+    # Missing archs check
+    my %arch_ok;
+    my $arch_ok_i = 0;
+    while (my($arch, $f) = each(%$symfiles)) {
+        $arch_ok{$arch} = $arch_ok_i;
+    }
+
+    while (my ($soname, $groups) = each(%symbols)) {
+        while (my ($name, $group) = each(%$groups)) {
+            # Check if the group is not banned 
+            next if exists $group->{banned};
+
+            # Check if the group is complete
+            my $count = scalar(keys(%{$group->{arches}}));
+            if ($count < $arch_count) {
+                $group->{banned} = 1;
+                # Additional vtables are usual on armel
+                next if ($count == 1 && exists $group->{arches}{armel} && $group->{arches}{armel}->is_vtt());
+
+                $arch_ok_i++;
+                warning("ignoring incomplete group '$name/$soname' ($count < $arch_count). Symbol dump below:");
+                foreach my $arch (sort(keys %{$group->{arches}})) {
+                    info("  " . $group->{arches}{$arch}->get_symbol() . "/" . $arch . "\n");
+                    $arch_ok{$arch} = $arch_ok_i;
+                }
+                info("  - missing on:");
+                for my $arch (sort(keys %arch_ok)) {
+                    info(" $arch") if (defined $arch_ok{$arch} && $arch_ok{$arch} != $arch_ok_i);
+                }
+                info("\n");
+                next;
+            }
+
+            # Main symbol (reference)
+            my $main_symbol = new Debian::PkgKde::SymHelper::Symbol2($group->{arches}{$main_arch}->get_symbol(), $main_arch);
+            foreach my $handler (@{$self->{subst}}) {
+                if ($handler->detect($main_symbol, $group->{arches})) {
+                    # Make archsymbols arch independent with regard to his handler
+                    while (my ($arch, $symbol) = each(%{$group->{arches}})) {
+                        $handler->clean($symbol);
+                    }
+                }
+            }
+            $group->{template} = $main_symbol;
+        }
+    }
+
+    # Finally, integrate our template into $main_arch symfile
+    my $main_symfile = $symfiles->{$main_arch};
+    while (my ($soname, $sonameobj) = each(%{$symfiles->{$main_arch}{objects}})) {
+        my @syms = keys(%{$sonameobj->{syms}});
+        for my $sym (@syms) {
+            my $g = $self->get_group_name($sym, $main_arch);
+            if (exists $symbols{$soname}{$g}) {
+                my $group = $symbols{$soname}{$g};
+                if (!exists $group->{banned}) {
+                    # Rename symbol
+                    my $info = $sonameobj->{syms}{$sym};
+                    my $newsym = $group->{template}->get_symbol2();
+                    $sonameobj->{syms}{$newsym} = $info;
+                    delete $sonameobj->{syms}{$sym};
+                } elsif (exists $sonameobj->{syms}{$sym}) {
+                    delete $sonameobj->{syms}{$sym}
+                        unless ($sonameobj->{syms}{$sym}{deprecated});
+                }
+            }
+        }
+    }
+
+    return $main_symfile;
+}
+
+sub substitute {
+    my ($self, $file, $arch) = @_;
+    my $symfile = new Debian::PkgKde::SymHelper::SymbFile($file);
+
+    foreach my $h (@{$self->{subst}}) {
+        $h->set_arch($arch);
+    }
+    if ($symfile->scan_for_substvars()) {
+        return $symfile->substitute($self->{subst});
+    } else {
+        return undef;
+    }
+}
+
+sub apply_patch_to_template {
+    my ($self, $patchfh, $infile, $arch, $newminver) = @_;
+
+    # Dump arch specific symbol file to temporary location
+    my $archsymfile = $self->substitute($infile, $arch);
+    my ($archfh, $archfn) = File::Temp::tempfile();
+    $archsymfile->dump($archfh);
+    close($archfh);
+
+    # Adopt the patch to our needs (filename)
+    my $file2patch;
+    my $is_patch;
+    while(<$patchfh>) {
+        if (defined $is_patch) {
+            if (m/^(?:[+ -]|@@ )/) {
+                # Patch continues
+                print PATCH $_;
+                $is_patch++;
+            } else {
+                # Patch ended
+                last;
+            }
+        } elsif (defined $file2patch) {
+            if (m/^[+]{3}\s+\S+/) {
+                # Found the patch portion. Write the patch header
+                $is_patch = 0;
+                open(PATCH, "| patch -p0 >/dev/null 2>&1") or die "Unable to execute `patch` program";
+                print PATCH "--- ", $archfn, "\n";
+                print PATCH "+++ ", $archfn, "\n";
+            } else {
+                $file2patch = undef;
+            }
+        } elsif (m/^[-]{3}\s+(\S+)/) {
+            $file2patch = $1;
+        }
+    }
+
+    if($file2patch && close(PATCH) && $is_patch) {
+        # Patching was successful. Reparse
+        my $insymfile = new Debian::PkgKde::SymHelper::SymbFile($infile);
+        my $newsymfile = new Debian::PkgKde::SymHelper::SymbFile($archfn);
+
+        # Resync private symbols in newsymfile with archsymfile
+        $newsymfile->resync_private_symbols($archsymfile);
+
+        # Process lost symbols
+        $insymfile->merge_lost_symbols_to_template($archsymfile, $newsymfile);
+
+        # Now process new symbols. We need to a create template from them
+        if (my $dummysymfile = $newsymfile->get_new_symbols_as_symbfile($archsymfile)) {
+            $self->add_symbol_file($dummysymfile, $arch);
+            $self->preprocess();
+
+            # Handle min version
+            $dummysymfile->handle_min_version($newminver);
+
+            # Create a symbols template for our dummy file
+            $dummysymfile = $self->create_template_standalone();
+
+            # Finally, merge it to our $insymfile
+            $insymfile->merge_symbols_from_symbfile($dummysymfile, 1);
+        }
+        unlink($archfn);
+        return return $insymfile;
+    } else {
+        # Patching failed
+        unlink($archfn);
+        return undef;
+    }
+}
+
+1;

Added: branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/SymbFile.pm
===================================================================
--- branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/SymbFile.pm	                        (rev 0)
+++ branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/SymbFile.pm	2008-11-20 19:04:38 UTC (rev 12691)
@@ -0,0 +1,314 @@
+package Debian::PkgKde::SymHelper::SymbFile;
+our @ISA = qw( Dpkg::Shlibs::SymbolFile );
+
+use warnings;
+use strict;
+use Dpkg::Shlibs::SymbolFile;
+use Debian::PkgKde::SymHelper qw(error warning);
+
+sub get_symbol_substvars {
+    my ($self, $sym) = @_;
+    my @substvars;
+    while ($sym =~ m/(\{[^}]+\})/g) {
+        push @substvars, "$1";
+    }
+    return @substvars;
+}
+
+sub scan_for_substvars {
+    my $self = shift;
+    my $count = 0;
+    delete $self->{subst_objects} if exists $self->{subst_objects};
+    while (my($soname, $sonameobj) = each(%{$self->{objects}})) {
+        while (my ($sym, $info) = each(%{$sonameobj->{syms}})) {
+            if (my @substvars = $self->get_symbol_substvars($sym)) {
+                $self->{subst_objects}{$soname}{syms}{$sym} = \@substvars;
+                $count += scalar(@substvars);
+            }
+        }
+    }
+    return $count;
+}
+
+sub substitute {
+    my $self = shift;
+    my $handlers = shift;
+
+    return undef unless defined $handlers;
+
+    my $newsymfile = new Debian::PkgKde::SymHelper::SymbFile;
+
+    # Shallow clone our symbol file as a new file object
+    while (my ($key, $val) = each(%$self)) {
+        $newsymfile->{$key} = $val;
+    }
+
+    # We are only interested in {objects}
+    $newsymfile->{objects} = {};
+    while (my ($soname, $sonameobj) = each(%{$self->{objects}})) {
+        if (exists $self->{subst_objects}{$soname}) {
+            while (my ($soname_key, $soname_val) = each(%$sonameobj)) {
+                $newsymfile->{objects}{$soname}{$soname_key} = $soname_val;
+            }
+            # Process {syms}
+            $newsymfile->{objects}{$soname}{syms} = {};
+            while (my ($sym, $info) = each(%{$sonameobj->{syms}})) {
+                if (exists $self->{subst_objects}{$soname}{syms}{$sym}) {
+                    my $substvars = $self->{subst_objects}{$soname}{syms}{$sym};
+                    foreach my $substvar (@$substvars) {
+                        my ($result, $found);
+                        foreach my $handler (@$handlers) {
+                            if ($result = $handler->replace($substvar, $sym)) {
+                                $info->{oldname} = $sym;
+                                $sym =~ s/\Q$substvar\E/$result/g;
+                                $found = 1;
+                            }
+                        }
+                        error("Substvar '$substvar' in symbol $sym/$soname was not handled by any substvar handler")
+                            unless defined $found;
+                    }
+                }
+                $newsymfile->{objects}{$soname}{syms}{$sym} = $info;
+            }
+        } else {
+            $newsymfile->{objects}{$soname} = $sonameobj;
+        }
+    }
+
+    return $newsymfile;
+}
+
+sub dump_cpp_symbols {
+    my ($self, $fh) = @_;
+
+    while (my ($soname, $sonameobj) = each(%{$self->{objects}})) {
+        while (my ($sym, $info) = each(%{$sonameobj->{syms}})) {
+                print $fh $sym, "\n" if ($sym =~ /^_Z/);
+            }
+    }
+}
+
+sub load_cppfilt_symbols {
+    my ($self, $fh) = @_;
+
+    while (my ($soname, $sonameobj) = each(%{$self->{objects}})) {
+        while (my ($sym, $info) = each(%{$sonameobj->{syms}})) {
+            next unless ($sym =~ /^_Z/);
+            if (my $cpp = <$fh>) {
+                chomp $cpp;
+                $info->{cppfilt} = $cpp;
+            } else {
+                main::error("Unexpected end at c++filt output: '$sym' not demangled");
+            }
+        }
+    }
+}
+
+sub deprecate_useless_symbols {
+    my $self = shift;
+    my $count = 0;
+    while (my ($soname, $sonameobj) = each(%{$self->{objects}})) {
+        while (my ($sym, $info) = each(%{$sonameobj->{syms}})) {
+            next if ($info->{deprecated});
+
+            if (exists $info->{cppfilt}) {
+                # Deprecate template instantiations as they are not
+                # useful public symbols
+                my $cppfilt = $info->{cppfilt};
+                # Prepare for tokenizing: wipe out unnecessary spaces
+                $cppfilt =~ s/([,<>()])\s+/$1/g;
+                $cppfilt =~ s/\s*((?:(?:un)?signed|volatile|restrict|const|long)[*&]*)\s*/$1/g;
+                if (my @tokens = split(/\s+/, $cppfilt)) {
+                    my $func;
+                    if ($tokens[0] =~ /[(]/) {
+                        $func = $tokens[0];
+                    } elsif ($#tokens >= 1 && $tokens[1] =~ /[(]/) {
+                        # The first token was return type, try the second
+                        $func = $tokens[1];
+                    }
+                    if (defined $func && $func =~ /<[^>]+>[^(]*[(]/) {
+                        # print STDERR "Deprecating $sym ", $cppfilt, "\n";
+                        # It is template instantiation. Deprecate it
+                        $info->{deprecated} = "PRIVATE: TEMPLINST";
+                        $count++;
+                    }
+                }
+            }
+        }
+    }
+    return $count;
+}
+
+sub dump {
+    my ($self, $fh, $with_deprecated) = @_;
+
+    if (!defined $with_deprecated || $with_deprecated != 2) {
+        return Dpkg::Shlibs::SymbolFile::dump(@_);
+    } else {
+        foreach my $soname (sort keys %{$self->{objects}}) {
+            my @deps = @{$self->{objects}{$soname}{deps}};
+            print $fh "$soname $deps[0]\n";
+            shift @deps;
+            print $fh "| $_\n" foreach (@deps);
+            my $f = $self->{objects}{$soname}{fields};
+            print $fh "* $_: $f->{$_}\n" foreach (sort keys %{$f});
+            foreach my $sym (sort keys %{$self->{objects}{$soname}{syms}}) {
+                my $info = $self->{objects}{$soname}{syms}{$sym};
+                print $fh "#", (($info->{deprecated} =~ m/^PRIVATE:/) ? "DEPRECATED" : "MISSING"),
+                    ": $info->{deprecated}#" if $info->{deprecated};
+                print $fh " $sym $info->{minver}";
+                print $fh " $info->{dep_id}" if $info->{dep_id};
+                print $fh "\n";
+            }
+        }
+    }
+}
+
+sub resync_private_symbols {
+    my ($self, $ref) = @_;
+
+    # Remark private symbols in ref as deprecated
+    while (my ($soname, $sonameobj) = each(%{$ref->{objects}})) {
+        my $mysyms = $self->{objects}{$soname}{syms};
+        while (my ($sym, $info) = each(%{$sonameobj->{syms}})) {
+            if (exists $mysyms->{$sym}) {
+                if ($info->{deprecated} && $info->{deprecated} =~ m/^PRIVATE/) {
+                    $mysyms->{$sym} = $info;
+                }
+            }
+        }
+    }
+}
+
+sub resync_private_symbol_versions {
+    my ($self, $ref, $syncboth) = @_;
+
+    while (my ($soname, $sonameobj) = each(%{$ref->{objects}})) {
+        my $mysyms = $self->{objects}{$soname}{syms};
+        while (my ($sym, $info) = each(%{$sonameobj->{syms}})) {
+            if (exists $mysyms->{$sym}) {
+                if ($info->{deprecated} && $info->{deprecated} =~ m/^PRIVATE/) {
+                    my $newinfo;
+                    if ($syncboth) {
+                        $info->{deprecated} = $mysyms->{$sym}{deprecated};
+                        $newinfo = $info;
+                    } else {
+                        my %newinfo;
+                        while (my ($key, $val) = each(%$info)) {
+                            $newinfo{$key} = $val;
+                        }
+                        # Keep deprecation status
+                        $newinfo{deprecated} = $mysyms->{$sym}{deprecated};
+                        $newinfo = \%newinfo;
+                    }
+                    $mysyms->{$sym} = $newinfo;
+                }
+            }
+        }
+    }
+}
+
+sub merge_lost_symbols_to_template {
+    my ($self, $origsymfile, $newsymfile) = @_;
+    # Note: origsymfile must be = $self->substitute()
+
+    # Process symbols which are missing (lost) in $newsymfile
+    for my $n ($newsymfile->get_lost_symbols($origsymfile)) {
+        my $soname = $n->{soname};
+        my $sym = $n->{name};
+        my $origsyms = $origsymfile->{objects}{$soname}{syms};
+        my $newsyms = $newsymfile->{objects}{$soname}{syms};
+
+        my $mysym = (exists $origsyms->{$sym}{oldname}) ?
+            $origsyms->{$sym}{oldname} : $sym;
+        if (exists $newsyms->{$sym}) {
+            $self->{objects}{$soname}{syms}{$mysym} = $newsyms->{$sym};
+        } else {
+            # Mark as missing
+            $self->{objects}{$soname}{syms}{$mysym}{deprecated} = "LOST UNKNOWNVER";
+        }
+    }
+}
+
+sub get_new_symbols_as_symbfile {
+    my ($self, $ref) = @_;
+    my $deps = [ 'dummy dep' ];
+
+    if (my @newsyms = $self->get_new_symbols($ref)) {
+        my $newsymfile = new Debian::PkgKde::SymHelper::SymbFile();
+        $newsymfile->clear();
+
+        for my $n (@newsyms) {
+            my $soname = $n->{soname};
+            my $sym = $n->{name};
+
+            $newsymfile->{objects}{$soname}{syms}{$sym} =
+                $self->{objects}{$soname}{syms}{$sym};
+            $newsymfile->{objects}{$soname}{deps} = $deps;
+        }
+        return $newsymfile;
+    } else {
+        return undef;
+    }
+}
+
+sub merge_symbols_from_symbfile {
+    my ($self, $symfile, $warn_about_collisions) = @_;
+
+    while (my ($soname, $sonameobj) = each(%{$symfile->{objects}})) {
+        my $mysyms = $self->{objects}{$soname}{syms};
+        $mysyms = {} unless (defined $mysyms);
+
+        while (my ($sym, $info) = each(%{$sonameobj->{syms}})) {
+            if (exists $mysyms->{$sym}) {
+                warning("$sym exists in both symfiles. Keeping the old one\n")
+                    if ($warn_about_collisions)
+            } else {
+                $mysyms->{$sym} = $info;
+            }
+        }
+        $self->{objects}{$soname}{syms} = $mysyms;
+    }
+}
+
+sub set_min_version {
+    my ($self, $version, $with_deprecated) = @_;
+
+    while (my ($soname, $sonameobj) = each(%{$self->{objects}})) {
+        while (my ($sym, $info) = each(%{$sonameobj->{syms}})) {
+            $info->{minver} = $version if ($with_deprecated || !$info->{deprecated});
+        }
+    }
+}
+
+sub fix_min_versions {
+    my ($self, $with_deprecated) = @_;
+
+    while (my ($soname, $sonameobj) = each(%{$self->{objects}})) {
+        while (my ($sym, $info) = each(%{$sonameobj->{syms}})) {
+            if ($with_deprecated || !$info->{deprecated}) {
+                my $minver = $info->{minver};
+                if ($minver =~ m/[^~]$/) {
+                    unless($minver =~ s/-[01](?:$|[^\d-][^-]*$)//) {
+                        $minver =~ s/([^~])$/$1~/;
+                    }
+                    $info->{minver} = $minver;
+                }
+            }
+        }
+    }
+}
+
+sub handle_min_version {
+    my ($self, $version, $with_deprecated) = @_;
+
+    if (defined $version) {
+        if ($version) {
+            $self->set_min_version($version, $with_deprecated);
+        } else {
+            $self->fix_min_versions($with_deprecated);
+        }
+    }
+}
+
+1;

Added: branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Symbol.pm
===================================================================
--- branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Symbol.pm	                        (rev 0)
+++ branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Symbol.pm	2008-11-20 19:04:38 UTC (rev 12691)
@@ -0,0 +1,34 @@
+package Debian::PkgKde::SymHelper::Symbol;
+
+use strict;
+use warnings;
+
+sub new {
+    my ($cls, $symbol, $arch) = @_;
+    return bless { symbol => $symbol, arch => $arch }, $cls;
+}
+
+sub substr {
+    my ($self, $offset, $length, $repl) = @_;
+    substr($self->{symbol}, $offset, $length) = $repl;
+}
+
+sub get_symbol {
+    return shift()->{symbol};
+}
+
+sub get_arch {
+    return shift()->{arch};
+}
+
+sub eq {
+    my $self = shift;
+    my $other = shift;
+    return $self->{symbol} eq $other->{symbol};
+}
+
+sub is_vtt {
+    return shift()->get_symbol() =~ /^_ZT[VT]/;
+}
+
+1;

Added: branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Symbol2.pm
===================================================================
--- branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Symbol2.pm	                        (rev 0)
+++ branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper/Symbol2.pm	2008-11-20 19:04:38 UTC (rev 12691)
@@ -0,0 +1,33 @@
+package Debian::PkgKde::SymHelper::Symbol2;
+our @ISA = qw(Debian::PkgKde::SymHelper::Symbol);
+
+use strict;
+use warnings;
+use Debian::PkgKde::SymHelper::Symbol;
+
+sub new {
+    my $symbol = $_[1];
+    my $self = Debian::PkgKde::SymHelper::Symbol::new(@_);
+    my @lvl2 = split(//, $symbol);
+    $self->{lvl2} = \@lvl2;
+    return $self;
+}
+
+sub substr {
+    my ($self, $offset, $length, $repl1, $repl2) = @_;
+    my @repl = map { undef } split(//, $repl1);
+    $repl[0] = $repl2;
+    splice @{$self->{lvl2}}, $offset, $length, @repl;
+    return Debian::PkgKde::SymHelper::Symbol::substr($self, $offset, $length, $repl1);
+}
+
+sub get_symbol2 {
+    my $self = shift;
+    my $str = "";
+    foreach my $s (@{$self->{lvl2}}) {
+        $str .= $s if defined $s;
+    }
+    return $str;
+}
+
+1;

Added: branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper.pm
===================================================================
--- branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper.pm	                        (rev 0)
+++ branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/Debian/PkgKde/SymHelper.pm	2008-11-20 19:04:38 UTC (rev 12691)
@@ -0,0 +1,42 @@
+package Debian::PkgKde::SymHelper;
+
+require Exporter;
+our @ISA = qw(Exporter);
+our @EXPORT_OK = qw(error warning info);
+use File::Basename qw(basename);
+
+our @ARCHES = (
+    'i386', 'kfreebsd-i386', 'hurd-i386',
+    'amd64', 'kfreebsd-amd64',
+    'alpha',
+    'arm',
+    'armel',
+    'hppa',
+    'ia64',
+    'mips',
+    'mipsel',
+    'powerpc',
+    's390',
+    'sparc',
+    'm68k',
+);
+
+sub get_program_name {
+    return basename($0);
+}
+
+sub error {
+    my $msg = shift;
+    print STDERR "(", get_program_name(), ") error: ", $msg, "\n";
+    exit 1;
+}
+
+sub warning {
+    my $msg = shift;
+    print STDERR "(", get_program_name(), ") warning: ", $msg, "\n";
+}
+
+sub info {
+    my $msg = shift;
+    print STDERR $msg;
+}

Added: branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/pkgkde-symbolshelper
===================================================================
--- branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/pkgkde-symbolshelper	                        (rev 0)
+++ branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/pkgkde-symbolshelper	2008-11-20 19:04:38 UTC (rev 12691)
@@ -0,0 +1,167 @@
+#!/usr/bin/perl -w
+
+# Copyright (C) 2008 Modestas Vainius <modestas at vainius.eu>
+#
+# 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/>
+
+use strict;
+use warnings;
+use File::Spec;
+use Getopt::Long;
+
+use Debian::PkgKde::SymHelper qw(info error warning);
+use Debian::PkgKde::SymHelper::Handler::Base;
+use Debian::PkgKde::SymHelper::SymbFile;
+use Debian::PkgKde::SymHelper::Handlers;
+
+my $opt_dir;
+my $opt_minversion;
+my $opt_in;
+my $opt_arch = Debian::PkgKde::SymHelper::Handler::Base::get_host_arch();
+my $opt_outfile;
+my $opt_patch;
+my $opt_fixup;
+
+sub find_package_symbolfile_path {
+    my ($package, $arch) = @_;
+    my @PATHS = (
+        "debian/$package.symbols.$arch",
+        "debian/symbols.$arch",
+        "debian/$package.symbols",
+        "debian/symbols"
+    );
+    for my $path (@PATHS) {
+        return $path if (-f $path);
+    }
+    return undef;
+}
+
+sub out_symfile {
+    my $symfile = shift;
+    return unless $symfile;
+
+    if ($opt_outfile) {
+        $symfile->save($opt_outfile, 2);
+    } else {
+        $symfile->dump(*STDOUT, 2);
+    }
+}
+
+sub print_symbol_list($$) {
+    my ($list, $prefix) = @_;
+    for my $item (@$list) {
+        info(sprintf("%s%s %s\n", $prefix, $item->{soname}, $item->{name}));
+    }
+}
+
+sub fixup {
+    my ($package, $infile, $outfile, $minver, $arch) = @_;
+
+    error("Specify either package or template and output symbol files")
+        unless ($package || $infile && $outfile);
+    unless ($infile) {
+        $infile = find_package_symbolfile_path($package, $arch);
+        return 0 unless ($infile);
+    }
+    unless ($outfile) {
+        $outfile = "debian/$package/DEBIAN/symbols";
+        return 0 unless (-f $outfile);
+    }
+
+    error("Symbol template file ($infile) not found") unless (-f $infile);
+    error("Output symbol file ($outfile) not found") unless (-f $outfile);
+
+    my $insymfile = new Debian::PkgKde::SymHelper::SymbFile($infile);
+    my $outsymfile = new Debian::PkgKde::SymHelper::SymbFile($outfile);
+
+    # Sync versions in both symfiles to get proper @new and @lost
+    # results later
+    $outsymfile->resync_private_symbol_versions($insymfile, 1);
+    $outsymfile->handle_min_version($minver);
+
+    # Save
+    $outsymfile->save($outfile, 2);
+
+    # Print some summary information since the one from dpkg-gensymbols is inaccurate
+    my @new = $outsymfile->get_new_symbols($insymfile);
+    if (@new) {
+        warning("NEW symbols in this version (" . scalar(@new) . "):");
+        print_symbol_list(\@new, "--   ");
+    }
+    my @lost = $outsymfile->get_lost_symbols($insymfile);
+    if (@lost) {
+        warning("LOST symbols in this version (" . scalar(@lost) . "):");
+        print_symbol_list(\@lost, "--   ");
+    }
+
+    return 1;
+}
+
+if (GetOptions(
+    "directory|d=s" => \$opt_dir,
+    "min-version|v:s" => \$opt_minversion,
+    "architecture|a=s" => \$opt_arch,
+    "input|i=s" => \$opt_in,
+    "output|o=s" => \$opt_outfile,
+    "patch|p:s" => \$opt_patch,
+    "fixup|f:s" => \$opt_fixup,)) {
+}
+
+my $handlers = new Debian::PkgKde::SymHelper::Handlers;
+my $str_arches = join("|", @Debian::PkgKde::SymHelper::ARCHES);
+error("Unknown architecture: $opt_arch")
+    unless grep /^$opt_arch$/, @Debian::PkgKde::SymHelper::ARCHES;
+
+if (defined $opt_dir) {
+    opendir(DIR, $opt_dir) or error("Unable to open directory: $opt_dir");
+    my %files;
+    while (my $file = readdir(DIR)) {
+        next if ($file =~ /^.{1,2}$/);
+        $file = File::Spec->catfile($opt_dir, $file);
+        if ($file =~ /.*?[_.]($str_arches)$/) {
+            $files{$1} = $file;
+        } else {
+            warning("$file is not named properly. Expected *_<arch> or *.<arch>");
+        }
+    }
+
+    if (scalar(keys %files) > 0) {
+        $handlers->load_symbol_files(\%files);
+        $handlers->preprocess();
+
+        # Create a symbols template and write it
+        $handlers->set_main_arch($opt_arch);
+        my $template = $handlers->create_template();
+        $template->handle_min_version($opt_minversion, 1);
+        out_symfile($template);
+    } else {
+        error("No properly named symbol files found in $opt_dir");
+    }
+} elsif (defined $opt_fixup) {
+    fixup($opt_fixup, $opt_in, $opt_outfile, $opt_minversion, $opt_arch);
+} elsif (defined $opt_in) {
+    error("Symbol template file ($opt_in) not found") unless (-f $opt_in);
+
+    if (defined $opt_patch) {
+        $opt_patch = "-" unless ($opt_patch);
+        # Open patch
+        open(PATCHINPUT, $opt_patch) or error("Unable to open patch '$opt_patch' for reading");
+        out_symfile($handlers->apply_patch_to_template(*PATCHINPUT, $opt_in, $opt_arch, $opt_minversion));
+        close(PATCHINPUT);
+    } else {
+        out_symfile($handlers->substitute($opt_in, $opt_arch));
+    }
+} else {
+    error("$0: insufficient number of arguments");
+}


Property changes on: branches/kde4.2/packages/pkg-kde-tools/trunk/symbolshelper/pkgkde-symbolshelper
___________________________________________________________________
Name: svn:executable
   + *




More information about the pkg-kde-commits mailing list