From: Raphael Hertzog Date: Mon, 13 Aug 2007 13:29:44 +0000 (+0200) Subject: Add include mechanism for symbols files. X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7b5a5b0a4dc034506c8c604bb6b48775d5965f99;p=dpkg Add include mechanism for symbols files. It's now possible to include external files in a "symbols" file using a cpp-like syntax (#include "filetoinclude"). Provisions for recursive includes are done. Also add some regression tests. This is meant to be used by complex packages which have differences between various architectures and which still want to factorize some common list of symbols. --- diff --git a/scripts/Dpkg/Shlibs/SymbolFile.pm b/scripts/Dpkg/Shlibs/SymbolFile.pm index b66c6666..6de44cf2 100644 --- a/scripts/Dpkg/Shlibs/SymbolFile.pm +++ b/scripts/Dpkg/Shlibs/SymbolFile.pm @@ -48,15 +48,27 @@ sub clear_except { } } +# Parameter seen is only used for recursive calls sub load { - my ($self, $file) = @_; - $self->{file} = $file; - open(SYM_FILE, "<", $file) + my ($self, $file, $seen) = @_; + + if (defined($seen)) { + return if exists $seen->{$file}; # Avoid include loops + } else { + $self->{file} = $file; + $seen = {}; + } + $seen->{$file} = 1; + + open(my $sym_file, "<", $file) || syserr(sprintf(_g("Can't open %s: %s"), $file)); my ($object); - while (defined($_ = )) { + while (defined($_ = <$sym_file>)) { chomp($_); if (/^\s+(\S+)\s(\S+)(?:\s(\d+))?/) { + if (not defined ($object)) { + error(sprintf(_g("Symbol information must be preceded by a header (file %s, line %s).", $file, $.))); + } # New symbol my $sym = { minver => $2, @@ -64,6 +76,11 @@ sub load { deprecated => 0 }; $self->{objects}{$object}{syms}{$1} = $sym; + } elsif (/^#include\s+"([^"]+)"/) { + my $filename = $1; + my $dir = $file; + $dir =~ s{[^/]+$}{}; # Strip filename + $self->load("$dir$filename", $seen); } elsif (/^#DEPRECATED: ([^#]+)#\s*(\S+)\s(\S+)(?:\s(\d+))?/) { my $sym = { minver => $3, @@ -71,21 +88,29 @@ sub load { deprecated => $1 }; $self->{objects}{$object}{syms}{$2} = $sym; + } elsif (/^#/) { + # Skip possible comments } elsif (/^\|\s*(.*)$/) { # Alternative dependency template push @{$self->{objects}{$object}{deps}}, "$1"; } elsif (/^(\S+)\s+(.*)$/) { # New object and dependency template $object = $1; - $self->{objects}{$object} = { - syms => {}, - deps => [ "$2" ] - }; + if (exists $self->{objects}{$object}) { + # Update/override infos only + $self->{objects}{$object}{deps} = [ "$2" ]; + } else { + # Create a new object + $self->{objects}{$object} = { + syms => {}, + deps => [ "$2" ] + }; + } } else { warning(sprintf(_g("Failed to parse a line in %s: %s"), $file, $_)); } } - close(SYM_FILE); + close($sym_file); } sub save { diff --git a/scripts/t/200_Dpkg_Shlibs.t b/scripts/t/200_Dpkg_Shlibs.t index 9d1d17d0..ac1ee67d 100644 --- a/scripts/t/200_Dpkg_Shlibs.t +++ b/scripts/t/200_Dpkg_Shlibs.t @@ -1,6 +1,6 @@ # -*- mode: cperl;-*- -use Test::More tests => 18; +use Test::More tests => 23; use strict; use warnings; @@ -84,3 +84,34 @@ $sym_file_dup->load($save_file->filename); $sym_file_dup->{file} = "t/200_Dpkg_Shlibs/symbol_file.tmp"; is_deeply($sym_file_dup, $sym_file, 'save -> load' ); + +# Test include mechanism of SymbolFile +$sym_file = Dpkg::Shlibs::SymbolFile->new("t/200_Dpkg_Shlibs/symbols.include-1"); + +$sym = $sym_file->lookup_symbol('symbol_before@Base', ['libfake.so.1']); +is_deeply($sym, { 'minver' => '0.9', 'dep_id' => 0, 'deprecated' => 0, + 'depends' => 'libfake1 #MINVER#', 'soname' => 'libfake.so.1' }, + 'symbol before include not lost'); + +$sym = $sym_file->lookup_symbol('symbol_after@Base', ['libfake.so.1']); +is_deeply($sym, {'minver' => '1.1', 'dep_id' => 0, 'deprecated' => 0, + 'depends' => 'libfake1 #MINVER#', 'soname' => 'libfake.so.1' }, + 'symbol after include not lost'); + +$sym = $sym_file->lookup_symbol('symbol1_fake1@Base', ['libfake.so.1']); +is_deeply($sym, {'minver' => '1.0', 'dep_id' => 0, 'deprecated' => 0, + 'depends' => 'libfake1 #MINVER#', 'soname' => 'libfake.so.1' }, + 'overrides order with #include'); + +$sym = $sym_file->lookup_symbol('symbol3_fake1@Base', ['libfake.so.1']); +is_deeply($sym, { 'minver' => '1.1', 'dep_id' => 0, 'deprecated' => 0, + 'depends' => 'libfake1 #MINVER#', 'soname' => 'libfake.so.1' }, + 'overrides order with #include'); + +$sym_file = Dpkg::Shlibs::SymbolFile->new("t/200_Dpkg_Shlibs/symbols.include-2"); + +$sym = $sym_file->lookup_symbol('symbol1_fake2@Base', ['libfake.so.1']); +is_deeply($sym, { 'minver' => '1.0', 'dep_id' => 1, 'deprecated' => 0, + 'depends' => 'libvirtualfake', 'soname' => 'libfake.so.1' }, + 'overrides order with circular #include'); + diff --git a/scripts/t/200_Dpkg_Shlibs/symbols.fake-1 b/scripts/t/200_Dpkg_Shlibs/symbols.fake-1 new file mode 100644 index 00000000..59c29392 --- /dev/null +++ b/scripts/t/200_Dpkg_Shlibs/symbols.fake-1 @@ -0,0 +1,4 @@ +libfake.so.1 libfake1 #MINVER# + symbol1_fake1@Base 1.0 + symbol2_fake1@Base 1.0 + symbol3_fake1@Base 1.0 diff --git a/scripts/t/200_Dpkg_Shlibs/symbols.fake-2 b/scripts/t/200_Dpkg_Shlibs/symbols.fake-2 new file mode 100644 index 00000000..89586d1e --- /dev/null +++ b/scripts/t/200_Dpkg_Shlibs/symbols.fake-2 @@ -0,0 +1,8 @@ +#include "symbols.include-2" +# This is just a comment +libfake.so.1 libfake1 #MINVER# +# The alternate dependency is below +| libvirtualfake + symbol1_fake2@Base 1.0 1 + symbol2_fake2@Base 1.0 + symbol3_fake2@Base 1.0 diff --git a/scripts/t/200_Dpkg_Shlibs/symbols.include-1 b/scripts/t/200_Dpkg_Shlibs/symbols.include-1 new file mode 100644 index 00000000..e069029c --- /dev/null +++ b/scripts/t/200_Dpkg_Shlibs/symbols.include-1 @@ -0,0 +1,7 @@ +libfake.so.1 libfake1 + symbol1_fake1@Base 0.9 + symbol2_fake1@Base 0.9 + symbol_before@Base 0.9 +#include "symbols.fake-1" + symbol3_fake1@Base 1.1 + symbol_after@Base 1.1 diff --git a/scripts/t/200_Dpkg_Shlibs/symbols.include-2 b/scripts/t/200_Dpkg_Shlibs/symbols.include-2 new file mode 100644 index 00000000..0cc18fac --- /dev/null +++ b/scripts/t/200_Dpkg_Shlibs/symbols.include-2 @@ -0,0 +1,3 @@ +libfake.so.1 libfake1 + symbol1_fake2@Base 0.5 +#include "symbols.fake-2"