]> err.no Git - dpkg/commitdiff
Add include mechanism for symbols files.
authorRaphael Hertzog <hertzog@debian.org>
Mon, 13 Aug 2007 13:29:44 +0000 (15:29 +0200)
committerRaphael Hertzog <hertzog@debian.org>
Mon, 13 Aug 2007 13:29:44 +0000 (15:29 +0200)
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.

scripts/Dpkg/Shlibs/SymbolFile.pm
scripts/t/200_Dpkg_Shlibs.t
scripts/t/200_Dpkg_Shlibs/symbols.fake-1 [new file with mode: 0644]
scripts/t/200_Dpkg_Shlibs/symbols.fake-2 [new file with mode: 0644]
scripts/t/200_Dpkg_Shlibs/symbols.include-1 [new file with mode: 0644]
scripts/t/200_Dpkg_Shlibs/symbols.include-2 [new file with mode: 0644]

index b66c6666a825f4067e89e29a2e29b4a8ae06dd6f..6de44cf2685aa5e2faa845af0ae5b8bd46b5a8fa 100644 (file)
@@ -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($_ = <SYM_FILE>)) {
+    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 {
index 9d1d17d0c00dcb0c2748a8d1aab9d27fa8e70ff3..ac1ee67d0a79112ee374399c5b62e7b64fbd31d4 100644 (file)
@@ -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 (file)
index 0000000..59c2939
--- /dev/null
@@ -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 (file)
index 0000000..89586d1
--- /dev/null
@@ -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 (file)
index 0000000..e069029
--- /dev/null
@@ -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 (file)
index 0000000..0cc18fa
--- /dev/null
@@ -0,0 +1,3 @@
+libfake.so.1 libfake1
+ symbol1_fake2@Base 0.5
+#include "symbols.fake-2"