Browse Source

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.
Raphael Hertzog 19 years ago
parent
commit
7b5a5b0a4d

+ 34 - 9
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($_ = <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 {

+ 32 - 1
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');
+

+ 4 - 0
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

+ 8 - 0
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

+ 7 - 0
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

+ 3 - 0
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"