Hello Eric, * Eric Blake wrote on Tue, Jun 30, 2009 at 06:13:15AM CEST: > According to Ralf Wildenhues on 6/28/2009 1:24 AM: > > * Eric Blake wrote on Sat, Jun 27, 2009 at 04:01:15PM CEST: > >> So how exactly do you describe the bug? Using 'echo \c' inside a command > >> substitution corrupts state until the next command substitution echo? > > > > Yes, I think that's what it is. > > Let's get that documented, then, before approving this patch, although I'd > like to see the fix go in before 2.64.
Thinking about it again, my patch was too lax and should have been stricter: within a command substitution, the \c causes all but the first character of the output to be removed. Let's test for that, just like Jan suggested, but just not set ECHO_C at all in this case, and set ECHO_T to a tab like is done in the other bailout case. Thus I suggest this patch. OK? Thanks, Ralf commit 658e0e958f792718ecd855c1f407873599ab8cda Author: Jan Madzik <[email protected]> Date: Tue Jun 30 08:06:24 2009 +0200 Avoid AIX 6.1 ksh88 ECHO_C command substitution bug. * lib/m4sugar/m4sh.m4 (_AS_ECHO_N_PREPARE): Ensure more than one character is output before `\c'; reset echo output state if buggy ksh was detected, and set ECHO_T instead of ECHO_C. * doc/autoconf.texi (Limitations of Builtins): Document it. * tests/m4sh.at (ECHO_C): New test. Signed-off-by: Ralf Wildenhues <[email protected]> diff --git a/ChangeLog b/ChangeLog index 5f89c1b..7913679 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2009-06-30 Jan Madzik <[email protected]> (tiny change) + Ralf Wildenhues <[email protected]> + + Avoid AIX 6.1 ksh88 ECHO_C command substitution bug. + * lib/m4sugar/m4sh.m4 (_AS_ECHO_N_PREPARE): Ensure more than + one character is output before `\c'; reset echo output state + if buggy ksh was detected, and set ECHO_T instead of ECHO_C. + * doc/autoconf.texi (Limitations of Builtins): Document it. + * tests/m4sh.at (ECHO_C): New test. + 2009-06-27 William Pursell <[email protected]> (tiny change) Fix grammaro in documenation. diff --git a/doc/autoconf.texi b/doc/autoconf.texi index 455d1c4..8c3516f 100644 --- a/doc/autoconf.texi +++ b/doc/autoconf.texi @@ -15733,7 +15733,10 @@ Limitations of Builtins Solaris outputs 2, but Bash and Zsh (in @command{sh} emulation mode) output 1. The problem is truly @command{echo}: all the shells understand @samp{'\n'} as the string composed of a backslash and an -...@samp{n}. +...@samp{n}. Within a command substitution, @samp{echo 'string\c'} will +mess up the internal state of ksh88 on AIX 6.1 so that it will print +the first character @samp{c} only, followed by a newline, and then +entirely drop the output of the next echo in a command substitution. Because of these problems, do not pass a string containing arbitrary characters to @command{echo}. For example, @samp{echo "$foo"} is safe diff --git a/lib/m4sugar/m4sh.m4 b/lib/m4sugar/m4sh.m4 index c7b0bff..611d0e1 100644 --- a/lib/m4sugar/m4sh.m4 +++ b/lib/m4sugar/m4sh.m4 @@ -780,14 +780,19 @@ m4_defun_init([_AS_ECHO_LOG], # display the checking message. In addition, caching something used once # has little interest. # Idea borrowed from dist 3.0. Use `*c*,', not `*c,' because if `\c' -# failed there is also a newline to match. +# failed there is also a newline to match. Use `xy*' because `\c' echoed +# in a command substitution prints only the first character of the output +# with ksh version M-11/16/88f on AIX 6.1; it needs to be reset by another +# backquoted echo. m4_defun([_AS_ECHO_N_PREPARE], [ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in @%:@(((( -n*) - case `echo 'x\c'` in + case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. - *) ECHO_C='\c';; + xy*) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; esac;; *) ECHO_N='-n';; diff --git a/tests/m4sh.at b/tests/m4sh.at index 065a9dd..f936a7c 100644 --- a/tests/m4sh.at +++ b/tests/m4sh.at @@ -1412,3 +1412,23 @@ AT_CHECK_M4SH AT_CHECK([./script]) AT_CLEANUP + + +## -------- ## +## ECHO_C. ## +## -------- ## + +AT_SETUP([ECHO_C]) + +AT_DATA_M4SH([script.as], [[dnl +AS_INIT +_AS_PREPARE +foo=`echo foobar` +echo "$foo" +]]) + +AT_CHECK_M4SH +AT_CHECK([./script], [], [foobar +]) + +AT_CLEANUP
