sed-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: understanding the T command


From: Assaf Gordon
Subject: Re: understanding the T command
Date: Fri, 15 May 2020 07:38:17 -0600
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.8.0

Hello,

On 2020-05-15 5:13 a.m., Nora Platiel wrote:
I'm confused about conditional branching, especially the T command. Consider 
this script:

s/x/X/; #1
T     ; #2
s/y/Y/; #3
T     ; #4
s/^/Z/; #5

Input line "x" produces output line "X", why not "ZX"?

This is what I would expect to happen for line "x":
- replacement #1 is successful
- conditional branch #2 is not taken
- replacement #3 is not successful
- conditional branch #4 is not taken
- replacement #5 is successful

Conditional branch #4 should not be taken because replacement #1 succeeded, and 
no line is read nor conditional branch taken between #1 and #4.
I hope someone here can clarify.
Thanks.

 From the docs:
T label: (test) Branch to label only if there have been no successful 
substitutions since the last input line was read or conditional branch was 
taken. The label may be omitted, in which case the next cycle is started.


Thank you for providing a clear way to reproduce the issue - makes it so much easier to answer.

Since the "T" command is a gnu extension,
it's not immediately clear to me if the code is right and the
documentation should be fixed, or the documentation is right and the
code should be fixed...

What is clear: sed behaves in the way you observed
because the code for 'T' resets the "replaced" flag
if the branch is *not* taken (line 1564):
   https://git.savannah.gnu.org/cgit/sed.git/tree/sed/execute.c#n1548

To illustrate, see:

  $ echo x | sed 's/x/X/ ; T ; aHELLO'
  X
  HELLO

  $ echo x | sed 's/x/X/ ; T ; T ; aHELLO'
  X

In the second example, the first "T" is not taken, but it resets
the state of the "replaced" flag, and then the second "T" is taken (and
HELLO is not printed).

---

Removing this line (execute.c:1564) makes sed behave in the way
you expected, and does not cause any test failures - indicating
this is quite an obscure scenario that wasn't officially tested.

But since this behavior has been in place since at least
sed 4.06 (from 2003), it might not be wise to change it
in backward-incompatible way.

I welcome others to chime in about this.


regards,
 - assaf












reply via email to

[Prev in Thread] Current Thread [Next in Thread]