forked from mit-pdos/xv6-book
-
Notifications
You must be signed in to change notification settings - Fork 0
/
line
executable file
·77 lines (67 loc) · 1.34 KB
/
line
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#!/usr/bin/perl
if (@ARGV < 1) {
print STDERR "usage: line file:address[,address] ...\n" .
"\taddress is n or /regexp/[+-n]\n";
exit 1;
}
sub num($) {
my ($i) = @_;
return substr($lines[$i], 0, 4);
}
sub line($$) {
my ($p, $i) = @_;
my $delta = 0;
if($p =~ /^\d+$/) {
return $p - 1;
}
if($p =~ /(.*?)([+-]\d+)$/) {
$p = $1;
$delta = $2;
}
if($p !~ /^\/(.*)\/$/) {
print STDERR "invalid address: $p\n";
exit 1;
}
$p = $1;
for(; $i<@strip; $i++) {
if($strip[$i] =~ $p) {
return $i + $delta;
}
}
print STDERR "no match for $p\n";
exit 1;
}
sub find($) {
my $arg = $_[0];
$arg =~ s/!/\\/g; # too hard to get real \ through troff and the shell
if($arg !~ /^(.*?):(.*)$/) {
print STDERR "invaid file:address: ", $_[0];
exit 1;
}
my ($file, $pattern) = ($1, $2);
open(F, "../xv6/fmt/$file") || die "open ../xv6/fmt/$file: $!";
@lines = <F>;
close F;
@strip = @lines;
s/^[0-9]{4} // for @strip;
if ($pattern =~ /(.*?),(.*)/) {
# looking for range
($p1, $p2) = ($1, $2);
my $i = line($p1, 0);
my $j = line($p2, $i+1);
return sprintf num($i) . "-" . num($j);
} else {
# looking for line
my $i = line($pattern, 0);
return num($i);
}
}
for($i=0; $i<@ARGV; $i++) {
my $s = $ARGV[$i];
if($s =~ /:/) {
push @all, find($s);
} else {
push @all, $s;
}
}
printf ".ds LINE \"%s\n", join(', ', @all);