perl 3.0 patch #10 patch #9, continued
[p5sagit/p5-mst-13.2.git] / lib / look.pl
1 ;# Usage: &look(*FILEHANDLE,$key,$dict,$fold)
2
3 ;# Sets file position in FILEHANDLE to be first line greater than or equal
4 ;# (stringwise) to $key.  Pass flags for dictionary order and case folding.
5
6 sub look {
7     local(*FH,$key,$fold) = @_;
8     local($max,$min,$mid,$_);
9     local($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,
10        $blksize,$blocks) = stat(FH);
11     $blksize = 8192 unless $blksize;
12     $key =~ s/[^\w\s]//g if $dict;
13     $key =~ y/A-Z/a-z/ if $fold;
14     $max = $size + $blksize - 1;
15     $max -= $size % $blksize;
16     while ($max - $min > $blksize) {
17         $mid = ($max + $min) / 2;
18         die "look: internal error"  if $mid % $blksize;
19         seek(FH,$mid,0);
20         $_ = <FH>;              # probably a partial line
21         $_ = <FH>;
22         chop;
23         s/[^\w\s]//g if $dict;
24         y/A-Z/a-z/ if $fold;
25         if ($_ lt $key) {
26             $min = $mid;
27         }
28         else {
29             $max = $mid;
30         }
31     }
32     seek(FH,$min,0);
33     while (<FH>) {
34         chop;
35         s/[^\w\s]//g if $dict;
36         y/A-Z/a-z/ if $fold;
37         last if $_ ge $key;
38         $min = tell(FH);
39     }
40     seek(FH,$min,0);
41     $min;
42 }
43
44 1;