From b05f44b4643f7d424b13d7cf1a517169659550ed Mon Sep 17 00:00:00 2001 From: Michael Mikonos <127171689+mknos@users.noreply.github.com> Date: Sat, 9 Nov 2024 12:15:41 +0800 Subject: [PATCH] ed: implement ';' addressing mode * ";" address by itself is taken to mean current address to end, i.e. ".,$" * "A1;A2" expression is the same as "A1,A2" * ";A2" expression works like ".,A2" * I tested the following combinations... ,p ---> all lines %p ---> all lines ;p ---> current line to end 1,p ---> only line 1 1%p ---> not supported 1;p ---> only line 1 1,2p ---> range 1-2 1%2p ---> not supported 1;2p ---> range 1-2 ,2p ---> range 1-2 %2n ---> range 1-2 ;20p ---> range current line to 20 (error if current>20) --- bin/ed | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/bin/ed b/bin/ed index 41412527..2bd06f29 100755 --- a/bin/ed +++ b/bin/ed @@ -62,8 +62,7 @@ use Getopt::Std qw(getopts); use constant A_NOMATCH => -1; use constant A_NOPAT => -2; -use constant A_ALL => -3; -use constant A_PATTERN => -4; +use constant A_PATTERN => -3; use constant E_ADDREXT => 'unexpected address'; use constant E_ADDRBAD => 'invalid address'; @@ -110,7 +109,7 @@ my $NO_QUESTIONS_MODE = 0; my $PRINT_NUM = 1; my $PRINT_BIN = 2; -our $VERSION = '0.13'; +our $VERSION = '0.14'; my @ESC = ( '\\000', '\\001', '\\002', '\\003', '\\004', '\\005', '\\006', '\\a', @@ -917,16 +916,14 @@ sub edParse { if (defined($adrs[0]) && ($adrs[0] == A_NOPAT || $adrs[0] == A_NOMATCH)) { return 1; } - if (defined($adrs[0]) && $adrs[0] == A_ALL) { - $adrs[0] = 1; - $adrs[1] = maxline(); - } elsif (s/\A,//) { # ',' and '%' cannot be combined + if (s/\A([,;\%])//) { + my $sep = $1; + return 0 if $sep eq '%' && defined($adrs[0]); $adrs[1] = getAddr(); - if (defined($adrs[1]) && $adrs[1] < 0) { - return 1; - } + return 1 if defined($adrs[1]) && $adrs[1] < 0; + unless (defined $adrs[0]) { - $adrs[0] = 1; + $adrs[0] = $sep eq ';' ? $CurrentLineNum : 1; $adrs[1] = maxline() unless defined $adrs[1]; } } @@ -977,8 +974,6 @@ sub getAddr { foreach my $c (split //, $1) { $n += $c eq '+' ? 1 : -1; } - } elsif (s/\A\%//) { - $n = A_ALL; } elsif (s/\A([0-9]+)//) { # '10' == 10 $n = $1; } elsif (s/\A\.//) { # '.' == current line