On 01/08/2015 03:38 PM, Felix Janda wrote:
> sed doesn't allow embedded newlines in the replacement for s///, e.g.
> 
> s/walrus/wal\
> rus/
> 
> It is not obvious to me how to fix this. There is some code for dealing
> with line continuations but I don't see how to use it.
> 
> Felix

Ok, _now_ sed should have been promoted. I fixed the bugs in all the
saved invocations from the aboriginal linux build, and aboriginal is
building with the new sed. (I still need to run LFS through the same
meat grinder, but hopefully the earlier packages caught the important bugs.)

Actually e2fsprogs had most of the truly weird stuff. I don't think
that's ever been built with anything _but_ gnu sed. (Or busybox. :)
No pretensions of portability...

The 4 remaining failing test cases were:

1) Two versions of the one you caught, except that it's not just an
escaped newline but _any_ newline. In -f files newline in a delimited
string was treated as a literal because the entire file was read and
processed as a single line with newlines similar to semicolons. So I
hooked up the "fetch next line" callback logic to branch to 's' or 'a'
cases, and saved the current delimiter we were looking for in the 'hit'
variable I was shamelessly repurposing to store status already.

So my version should work for sed -e 's/blah/one' -e 'two/' as well,
which the gnu one doesn't handle but LOGICALLY if you're going to accept
one you should accept both...

I also added a check for "we hit the end of the script and we were still
looking for a delimiter", with error message. Because that's a potential
failure mode now. (Sort of explains that weird "a\" and then no line
after it thing that gnu happily accepts. You had a line continuation
with no next line! How is that not an error?)

2) Busybox and gnu put an extra newline at the end of a file in one test
because posix says N should abort and NOT produce default output when
there's no more line to read, and that's not what posix does. (Busybox
copies gnu. I followed posix. I'm ok with that test staying different
because posix is clear on the correct behavior here and it doesn't
actually affect anything in this instance.)

3) There was a test that was just '/thingy/!d;N' so only the line with
the regex match and the following line got output. This was failing
because when N was the last line of the script the pointer we saved to
where to resume in the script was the next command after N, I.E. the
null pointer terminating the linked list, and when it called back into
the function and saw that TT.resume was NULL it started the script over
from the beginning. Oops.

I fixed that by adding 1 to the saved pointer and subtracting 1 from
resume when we used it, so the saved value was never null. (This
involved a typecast on the way back in because TT.resume is null so I
don't have to put my structure type into a global header, but
subtracting 1 to a void pointer is treated as a char * and it didn't go
back to the same original value without the typecast.)

(No it can't overflow back to NULL because it would have been pointing
into kernel space. Into the VDSO page, I think. Certainly not part of
the heap.)

Anyway: Sed! Done! I think!

That was fiddly.

Rob
_______________________________________________
Toybox mailing list
[email protected]
http://lists.landley.net/listinfo.cgi/toybox-landley.net

Reply via email to