contents search: Give result in correct case
authorFrank Lichtenheld <frank@lichtenheld.de>
Sun, 7 Oct 2007 15:58:33 +0000 (17:58 +0200)
committerFrank Lichtenheld <frank@lichtenheld.de>
Sun, 7 Oct 2007 15:58:33 +0000 (17:58 +0200)
While we do the searches case insensitive our file systems are not
so the results should reflect the correct filename.

Noticed by Christoph Berg <myon -at- debian org>
Reported as Debian Bug#445628

bin/parse-contents
lib/Packages/DoSearchContents.pm

index 36c90b1479fd54e937d80c21601e94dcd1f87532..414dc8ac0a623c1f11e04154423881f033478cc7 100755 (executable)
@@ -18,6 +18,7 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
 use strict;
+use warnings;
 use lib './lib';
 
 $| = 1;
@@ -103,9 +104,11 @@ for my $suite (@suites) {
                        $packages_contents_lastword{$_} = "$file\0";
                    }
                    # Searches are case-insensitive
-                   $file =~ tr [A-Z] [a-z];
-                   
-                   print REVERSED (reverse $file)."\0".(join ":$arch\0", @packages).":$arch\n";
+                   (my $nocase = $file) =~ tr [A-Z] [a-z];
+                   my $case = ($nocase eq $file) ? '-' : $file;
+
+                   print REVERSED (reverse $nocase)."\0".$case."\0".
+                       (join ":$arch\0", @packages).":$arch\n";
                }
                close CONT;
                
@@ -130,7 +133,7 @@ for my $suite (@suites) {
            rename("$DBDIR/reverse.tmp", "$DBDIR/reverse_${suite}_${arch}.txt");
        
            rename("$filelist_db.new", $filelist_db);
-           system("ln -sf $filelist_db $DBDIR/filelists_${suite}_all.db") == 0
+           system("ln", "-sf", $filelist_db, "$DBDIR/filelists_${suite}_all.db") == 0
                or die "Oops";
        }
     }
@@ -145,26 +148,33 @@ for my $suite (@suites) {
 
     print "Merging reverse path lists for ${suite}...\n";
 
-    open MERGED, "sort -m $DBDIR/reverse_${suite}_*.txt |"
+    open MERGED, "-|", "sort -m $DBDIR/reverse_${suite}_*.txt"
        or die "Failed to open merged list";
-    open FILENAMES, "> $DBDIR/filenames_$suite.txt.new"
+    open FILENAMES, ">", "$DBDIR/filenames_$suite.txt.new"
        or die "Failed to open filenames list";
     tie my %reverse_path_db, "DB_File", "$DBDIR/reverse_${suite}.db.new",
     O_RDWR|O_CREAT, 0666, $DB_BTREE
        or die "Error creating DB: $!";
 
-    my $lastpath = "";
-    my $lastfile = "";
-    my @matches = ();
+    my $lastpath = my $lastcasepath = my $lastfile = "";
+    my %matches = ();
     while (<MERGED>) {
        print "Doing line ".($./1000000)."M (out of approx. 16M)\n"
            if $. % 1000000 == 0;
        chomp;
        my @line = split /\0/o, $_;
        my $revpath = shift @line;
+       my $casepath = shift @line;
        if ($revpath ne $lastpath) {
            # Wrap: Do useful stuff with this ($lastpath, @matches)
-           $reverse_path_db{$lastpath} = join "\0", @matches if $lastpath ne "";
+           if ($lastpath ne "") {
+               my @matches;
+               while (my ($k, $v) = each %matches) {
+                   push @matches, join("\0", $k, @$v);
+               }
+               $reverse_path_db{$lastpath} = join "\1", @matches;
+               %matches = ();
+           }
            $lastpath =~ s,/.*,,o;
            if ($lastfile ne $lastpath) {
                $lastfile = $lastpath;
@@ -172,15 +182,24 @@ for my $suite (@suites) {
            }
            #
            $lastpath = $revpath;
-           @matches = @line;
+           $lastcasepath = $casepath;
+           $matches{$casepath} = \@line;
            next;
+#      } elsif ($lastcasepath ne "" and $casepath ne $lastcasepath) {
+#          warn reverse($revpath)." has more than one casepath: $casepath $lastcasepath\n";
        }
-       push @matches, @line
-       }
+       push @{$matches{$casepath}}, @line;
+    }
     # Note: do useful stuff here too, for out last entry. Maybe prevent this by
     # adding a fake ultimate entry?
-    $reverse_path_db{$lastpath} = join "\0", @matches;
-    
+    {
+       my @matches;
+       while (my ($k, $v) = each %matches) {
+           push @matches, join("\0", $k, @$v);
+       }
+       $reverse_path_db{$lastpath} = join "\1", @matches;
+    }
+
     untie %reverse_path_db;
     close FILENAMES;
     close MERGED;
index 1be7d441cc90e25c6da65a0b855a2916d809e8ff..debbbb2a93e28539aef61f66556ae17871080c85 100644 (file)
@@ -173,8 +173,15 @@ sub searchfile
        last unless index($key, $kw) == 0;
        debug( "found $key", 2 ) if DEBUG;
 
-       my @hits = split /\0/o, $value;
-       push @$results, [ scalar reverse($key), @hits ];
+       my @files = split /\001/o, $value;
+       foreach my $f (@files) {
+           my @hits = split /\0/o, $f;
+           my $file = shift @hits;
+           if ($file eq '-') {
+               $file = reverse($key);
+           }
+           push @$results, [ $file, @hits ];
+       }
        last if ($$nres)++ > 100;
     }