Re: GNU sed manual describes t/T a little wrong?

"Jim Hill [email protected] [sed-users]" <[email protected]>
Newsgroups gmane.editors.sed.user
Message-ID <CAEE75_3W0uLY9Kh93UJTbEU9QnBqF+hHoScuAY-8Fkx+2JDntQ@mail.gmail.com>
> "Branch to label only if there has been a successful substitution since
the last input line was read or conditional branch was taken." is the
current wording in the GNU sed manual for t.

>  "Branch to label only if there has been a successful substitution since
the last input line was read or conditional branch was run." seems to me a
more correct wording.

I can see "run" acknowledges there might be a `t` that wasn't taken between
the last taken `t` and the current one -- i.e. there's an interval "since
the last conditional branch was taken" doesn't seem to talk about..

The distinction makes no difference to sed's behavior -- if a subst took
place in that interval, then that `t` was taken, so the doc's correct in
every case.

All the same, I prefer your version.  The current one, "taken", clearly
says how far back any previous subst has to have been and leaves the reader
to work out how recent it has to have been, while "run" clearly says how
recent it has to have been.


On Wed, May 27, 2015 at 6:42 PM, [email protected] [sed-users] <
[email protected]> wrote:

>
>
> I received an email from Anders Granlund (in Sweden) pointing out a subtle
> error in the GNU sed manual definitions of t and T (T is a GNU extension).
> I've explored this and think Anders is right.
>
> "Branch to label only if there has been a successful substitution since
> the last input line was read or conditional branch was taken." is the
> current wording in the GNU sed manual for t.
>
> "Branch to label only if there has been a successful substitution since
> the last input line was read or conditional branch was run." seems to me a
> more correct wording.
>
> The current definition for t and T ends with "taken" (ie, branch taken).
> The suggested change ends with "run" (ie, t or T run). By "conditional
> branch", it means t or T, and "branch was taken" means t or T branched.
>
> The original description of sed (from 1970's) says: "The t function tests
> whether any successful substitutions have been made on the current input
> line; if so, it branches to 'label'; if not, it does nothing. The flag
> which indicates that a successful substitution has been executed is reset
> by: 1) reading a new input line, or 2) executing a t function." The phrase
> "executing a t function" seems consistent to me with "t was run", not
> "branch was taken". So that is one line of reasoning that the GNU sed
> manual seems in error.
>
> The other line of reasoning is to look at what sed does. Here is a test
> script I made up to look at cases that might arise:
>
> $ cat test1.sh
> echo "Input to sed is always the string 'old'"
> echo "----------------------------------------------------------"
> echo "Cases 1-4 are easy, as flag does not get reset"
> echo "----------------------------------------------------------"
> echo "Case 1. s works, sets flag, so t branches past d"
> echo "Case 1. Point is that t branches if flag is set"
> echo old | sed "s/old/new/; t; d"
> echo "----------------------------------------------------------"
> echo "Case 2. s fails, flag not set, so T branches past d"
> echo "Case 2. Point is that T branches if flag not set"
> echo old | sed "s/---/new/; T; d"
> echo "----------------------------------------------------------"
> echo "Case 3. s fails, flag not set, so t does not branch"
> echo "Case 3. Point is that t does not branch if flag not set"
> echo old | sed "s/---/new/; t; d"
> echo "----------------------------------------------------------"
> echo "Case 4. s works, sets flag, so T does not branch"
> echo "Case 4. Point is that T does not branch if flag set"
> echo old | sed "s/old/new/; T; d"
> echo "----------------------------------------------------------"
> echo "Cases 5-8 see if flag gets reset after s works"
> echo "----------------------------------------------------------"
> echo "Case 6. s works, tx branches, flag reset, t fails"
> echo "Case 6. Point is that t flag is reset if t branches"
> echo old | sed "s/old/new/; tx; d; :x t; l"
> echo "----------------------------------------------------------"
> echo "Case 6. s works, tx branches, flag reset, T branches"
> echo "Case 6. Point is that T flag is reset if t branches"
> echo old | sed "s/old/new/; tx; d; :x T; l"
> echo "----------------------------------------------------------"
> echo "Case 7. s works, Tx fails, flag reset, T branches"
> echo "Case 7. Point is that T flag is reset if T fails"
> echo old | sed "s/old/new/; Tx; l; :x T; d"
> echo "----------------------------------------------------------"
> echo "Case 8. s works, Tx fails, flag reset, t fails"
> echo "Case 8. Point is that t flag is reset if T fails"
> echo old | sed "s/old/new/; Tx; l; :x t; d"
> echo "----------------------------------------------------------"
> echo "Cases 9-10 see if flag gets reset by s just running"
> echo "----------------------------------------------------------"
> echo "Case 9. s1 works, s2 fails, but t still branches due to s1"
> echo "Case 9. Point is that flag is not reset by s just running"
> echo old | sed "s/old/new/; s/---/new/; t; d"
> echo "----------------------------------------------------------"
> echo "Case 10. s1 works, s2 fails, but T still fails due to s1"
> echo "Case 10. Point is that flag is not reset by s just running"
> echo old | sed "s/old/new/; s/---/new/; T; d"
> echo "----------------------------------------------------------"
>
> Here is what results:
>
> $ ./test1.sh
> Input to sed is always the string 'old'
> ----------------------------------------------------------
> Cases 1-4 are easy, as flag does not get reset
> ----------------------------------------------------------
> Case 1. s works, sets flag, so t branches past d
> Case 1. Point is that t branches if flag is set
> new
> ----------------------------------------------------------
> Case 2. s fails, flag not set, so T branches past d
> Case 2. Point is that T branches if flag not set
> old
> ----------------------------------------------------------
> Case 3. s fails, flag not set, so t does not branch
> Case 3. Point is that t does not branch if flag not set
> ----------------------------------------------------------
> Case 4. s works, sets flag, so T does not branch
> Case 4. Point is that T does not branch if flag set
> ----------------------------------------------------------
> Cases 5-8 see if flag gets reset after s works
> ----------------------------------------------------------
> Case 6. s works, tx branches, flag reset, t fails
> Case 6. Point is that t flag is reset if t branches
> new$
> new
> ----------------------------------------------------------
> Case 6. s works, tx branches, flag reset, T branches
> Case 6. Point is that T flag is reset if t branches
> new
> ----------------------------------------------------------
> Case 7. s works, Tx fails, flag reset, T branches
> Case 7. Point is that T flag is reset if T fails
> new$
> new
> ----------------------------------------------------------
> Case 8. s works, Tx fails, flag reset, t fails
> Case 8. Point is that t flag is reset if T fails
> new$
> ----------------------------------------------------------
> Cases 9-10 see if flag gets reset by s just running
> ----------------------------------------------------------
> Case 9. s1 works, s2 fails, but t still branches due to s1
> Case 9. Point is that flag is not reset by s just running
> new
> ----------------------------------------------------------
> Case 10. s1 works, s2 fails, but T still fails due to s1
> Case 10. Point is that flag is not reset by s just running
> ----------------------------------------------------------
>
> The key cases are #7 and #8. In both cases, s substituted, so T did not
> branch. According to the current GNU sed manual, branching is required to
> reset the flag. But the flag was reset, so T branches next time it appears,
> and t does not branch next time it appears. Merely running t or T, even if
> no branch, is enough to reset the flag.
>
> I don't think this is a big deal. It seems rather obscure, something that
> had never crossed my mind until Anders found it. I would always put t or T
> immediately after the s command, so cases 7 and 8 would rarely or never
> occur in practice. It seems like asking for trouble to have multiple t/T
> commands scattered about. But who knows? Maybe this might come up in some
> games that get programmed in complex sed scripts.
>
> Whether this is good style or not, the point is the current wording seems
> incorrect. If the manual is incorrect, I hope it can get fixed. If the
> current wording is OK, I'd be interested to hear what Anders and I missed.
>
> Thanks,
> Daniel
>  
>


[Non-text portions of this message have been removed]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.