Skip to content

Commit 9f22ceb

Browse files
authored
ed: better relative addresses (#902)
* The initial implementation of relative addresses was too limited * GNU and OpenBSD ed allow repeated +n, mixed +n and --++, as well as basing address from dot, dollar or a marked address * tests.. ++1= invalid: ambiguous += current +1 .+= current + 1 +1= current + 1 .+1= current + 1 .+3++= current + 5: ++ follows +n $---= end - 3 $-3= end - 3 $-3+3= end: repeated +n 'x-5,'x+5nl list 5 lines of context around marked line x
1 parent 79a9162 commit 9f22ceb

File tree

1 file changed

+19
-14
lines changed

1 file changed

+19
-14
lines changed

bin/ed

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ my $NO_QUESTIONS_MODE = 0;
105105
my $PRINT_NUM = 1;
106106
my $PRINT_BIN = 2;
107107

108-
our $VERSION = '0.23';
108+
our $VERSION = '0.24';
109109

110110
my @ESC = (
111111
'\\000', '\\001', '\\002', '\\003', '\\004', '\\005', '\\006', '\\a',
@@ -974,18 +974,10 @@ sub edParse {
974974

975975
sub getAddr {
976976
my $n;
977-
if (s/\A([\-\+])([0-9]+)//) { # '+1' or '-1'
978-
my $is_neg = $1 eq '-';
979-
my $x = $2;
980-
$x = -$x if $is_neg;
981-
$n = $CurrentLineNum + $x;
982-
} elsif (s/\A([\-\^\+]+)//) { # '++--' == current+0
983-
$n = $CurrentLineNum;
984-
foreach my $c (split //, $1) {
985-
$n += $c eq '+' ? 1 : -1;
986-
}
987-
} elsif (s/\A\'([a-z])//) {
988-
$n = exists $marks{$1} ? $marks{$1} : A_NOMARK;
977+
if (s/\A\'([a-z])//) {
978+
my $letter = $1;
979+
return A_NOMARK unless exists $marks{$letter};
980+
$n = $marks{$letter};
989981
} elsif (s/\A([0-9]+)//) { # '10' == 10
990982
$n = $1;
991983
} elsif (s/\A\.//) { # '.' == current line
@@ -1001,7 +993,20 @@ sub getAddr {
1001993
$re = $SearchPat;
1002994
}
1003995
$n = edSearch($re, $delim eq '?');
1004-
$n = A_NOMATCH unless $n;
996+
return A_NOMATCH unless $n;
997+
}
998+
while (s/\A([\-\+])([0-9]+)//) { # '+1' or '-1'
999+
$n = $CurrentLineNum unless defined $n;
1000+
my $is_neg = $1 eq '-';
1001+
my $x = $2;
1002+
$x = -$x if $is_neg;
1003+
$n += $x;
1004+
}
1005+
while (s/\A([\-\^\+]+)//) { # '++--' == current+0
1006+
$n = $CurrentLineNum unless defined $n;
1007+
foreach my $c (split //, $1) {
1008+
$n += $c eq '+' ? 1 : -1;
1009+
}
10051010
}
10061011
if (defined $n) {
10071012
return A_RANGE if $n < 0 || $n > maxline();

0 commit comments

Comments
 (0)