libtool-patches
[Top][All Lists]
Advanced

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

[PATCH 6/6] use printf as $ECHO


From: Paolo Bonzini
Subject: [PATCH 6/6] use printf as $ECHO
Date: Fri, 7 Nov 2008 14:53:35 +0100

This is the bulk of the patch series, and it removes $ECHO
in favor of `some printf' that works.  This printf can be:
1) a shell builtin for the current shell; 2) a printf binary;
3) a shell builtin for another shell.

There is a lot of simplification -- and more can be done because
this patch removes the need for Xsed in general.  There is also
a little complication because case (3) above is done with the
help of a shell function, and this shell function must be defined
at the correct places.  However, this is just a matter of adding
this in two places:

    eval "\$lt_func_ECHO"

and it does not involve any of the intricate quoting and the usage of
M4sh internals that are required by the --fallback-echo implementation.

This patch bumps the requirement for *building* Libtool to
Autoconf 2.62, which provides a handy $as_echo which does
exactly the same as we need for Libtool.  However, Libtool
itself uses its own echo replacement, so it is not tied to
Autoconf 2.62.

I tested this patch for cases 1) and 3) above (2 is the same
as 1 except that there is a path in front of `printf').

* configure.ac: Bump Autoconf requirement.
* libltdl/config/general.m4: Use $as_echo as default $ECHO.
* tests/testsuite.at: Use $as_echo as default $ECHO.

* libltdl/m4/libtool.m4 (LT_INIT): Add _LT_SHELL_INIT to
work around Autoconf <2.64 bug.
(_LT_OUTPUT_LIBTOOL_COMMANDS_INIT): Create func_do_echo if
needed.  Eliminate lt_ECHO requoting.
(_LT_SHELL_INIT): Use a public M4sh diversion.
(_LT_PROG_PRINTF_BACKSLASH): New.
(_LT_PROG_ECHO_BACKSLASH): Rewrite.
(LT_CMD_MAX_LEN): Do not use --fallback-echo.
* libltdl/config/ltmain.m4sh: Create func_do_echo.  Remove
fallback echo handling.
(func_emit_wrapper_part1): Quote lt_cmd_ECHO, lt_func_ECHO,
ECHO.  Remove fallback echo handling.
(Execute mode): Do not set qecho.

---
 configure.ac                |    2 +-
 libltdl/config/general.m4sh |    2 +-
 libltdl/config/ltmain.m4sh  |   61 +++---------
 libltdl/m4/libtool.m4       |  240 ++++++++++++++-----------------------------
 tests/testsuite.at          |    3 +-
 5 files changed, 95 insertions(+), 213 deletions(-)

diff --git a/configure.ac b/configure.ac
index 9b15ccc..56325f7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -23,7 +23,7 @@
 ####
 
 
-AC_PREREQ(2.59)dnl We use AS_HELP_STRING
+AC_PREREQ(2.62)dnl Some m4sh scripts use $as_echo
 dnl Oldest automake required for bootstrap is below in AM_INIT_AUTOMAKE.
 
 
diff --git a/libltdl/config/general.m4sh b/libltdl/config/general.m4sh
index cde7354..bd740fd 100644
--- a/libltdl/config/general.m4sh
+++ b/libltdl/config/general.m4sh
@@ -45,7 +45,7 @@ progpath="$0"
 
 M4SH_VERBATIM([[
 : ${CP="cp -f"}
-: ${ECHO="echo"}
+: ${ECHO=$as_echo}
 : ${EGREP="@EGREP@"}
 : ${FGREP="@FGREP@"}
 : ${GREP="@GREP@"}
diff --git a/libltdl/config/ltmain.m4sh b/libltdl/config/ltmain.m4sh
index 5c7dd96..e3627b0 100644
--- a/libltdl/config/ltmain.m4sh
+++ b/libltdl/config/ltmain.m4sh
@@ -92,6 +92,9 @@ fi
 BIN_SH=xpg4; export BIN_SH # for Tru64
 DUALCASE=1; export DUALCASE # for MKS sh
 
+# In case there is no working printf in the path
+eval "$lt_func_ECHO"
+
 # NLS nuisances: We save the old values to restore during execute mode.
 # Only set LANG and LC_ALL to C if already set.
 # These must not be set unconditionally because not all systems understand
@@ -118,29 +121,6 @@ m4_define([M4SH_IN_HEADER], [$1])dnl
 m4_include([getopt.m4sh])
 
 M4SH_VERBATIM([[
-# Check that we have a working $ECHO.
-if test "X$1" = X--no-reexec; then
-  # Discard the --no-reexec flag, and continue.
-  shift
-elif test "X$1" = X--fallback-echo; then
-  # Avoid inline document here, it may be left over
-  :
-elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then
-  # Yippee, $ECHO works!
-  :
-else
-  # Restart under the correct shell, and then maybe $ECHO will work.
-  exec $SHELL "$progpath" --no-reexec ${1+"$@"}
-fi
-
-if test "X$1" = X--fallback-echo; then
-  # used as fallback echo
-  shift
-  cat <<EOF
-$*
-EOF
-  exit $EXIT_SUCCESS
-fi
 
 magic="%%%MAGIC variable%%%"
 magic_exe="%%%MAGIC EXE variable%%%"
@@ -2360,22 +2340,18 @@ if test \"\$libtool_install_magic\" = \"$magic\"; then
 else
   # When we are sourced in execute mode, \$file and \$ECHO are already set.
   if test \"\$libtool_execute_magic\" != \"$magic\"; then
-    ECHO=\"$qecho\"
     file=\"\$0\"
-    # Make sure echo works.
-    if test \"X\$1\" = X--no-reexec; then
-      # Discard the --no-reexec flag, and continue.
-      shift
-    elif test \"X\`{ \$ECHO '\t'; } 2>/dev/null\`\" = 'X\t'; then
-      # Yippee, \$ECHO works!
-      :
-    else
-      # Restart under the correct shell, and then maybe \$ECHO will work.
-      exec $SHELL \"\$0\" --no-reexec \${1+\"address@hidden"}
-    fi
-  fi\
-"
+    # Make sure echo works."
+
+    qlt_cmd_ECHO=`$ECHO "X$lt_cmd_ECHO" | $Xsed -e "$sed_quote_subst"`
+    qlt_func_ECHO=`$ECHO "X$lt_func_ECHO" | $Xsed -e "$sed_quote_subst"`
+    qECHO=`$ECHO "X$ECHO" | $Xsed -e "$sed_quote_subst"`
        $ECHO "\
+    lt_cmd_ECHO=\"$qlt_cmd_ECHO\"
+    lt_func_ECHO=\"$qlt_func_ECHO\"
+    eval \"\$lt_func_ECHO\"
+    ECHO=\"$qECHO\"
+  fi\
 
   # Find the directory that this script lives in.
   thisdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
@@ -7407,17 +7383,6 @@ EOF
        relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"`
       fi
 
-      # Quote $ECHO for shipping.
-      if test "X$ECHO" = "X$SHELL $progpath --fallback-echo"; then
-       case $progpath in
-       [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";;
-       *) qecho="$SHELL `pwd`/$progpath --fallback-echo";;
-       esac
-       qecho=`$ECHO "X$qecho" | $Xsed -e "$sed_quote_subst"`
-      else
-       qecho=`$ECHO "X$ECHO" | $Xsed -e "$sed_quote_subst"`
-      fi
-
       # Only actually do things if not in dry run mode.
       $opt_dry_run || {
        # win32 will think the script is a binary if it has
diff --git a/libltdl/m4/libtool.m4 b/libltdl/m4/libtool.m4
index f29504b..24546a0 100644
--- a/libltdl/m4/libtool.m4
+++ b/libltdl/m4/libtool.m4
@@ -82,6 +82,8 @@ AC_REQUIRE([LTVERSION_VERSION])dnl
 AC_REQUIRE([LTOBSOLETE_VERSION])dnl
 m4_require([_LT_PROG_LTMAIN])dnl
 
+_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])
+
 dnl Parse OPTIONS
 _LT_SET_OPTIONS([$0], [$1])
 
@@ -524,6 +526,8 @@ LTCC='$LTCC'
 LTCFLAGS='$LTCFLAGS'
 compiler='$compiler_DEFAULT'
 
+eval "\$lt_func_ECHO"
+
 # Quote evaled strings.
 for var in lt_decl_all_varnames([[ \
 ]], lt_decl_quote_varnames); do
@@ -550,13 +554,6 @@ for var in lt_decl_all_varnames([[ \
     esac
 done
 
-# Fix-up fallback echo if it was mangled by the above quoting rules.
-case \$lt_ECHO in
-*'\\\[$]0 --fallback-echo"')dnl "
-  lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 
--fallback-echo"\[$]/\[$]0 --fallback-echo"/'\`
-  ;;
-esac
-
 _LT_OUTPUT_LIBTOOL_INIT
 ])
 
@@ -1067,170 +1064,89 @@ if test -z "$aix_libpath"; then 
aix_libpath="/usr/lib:/lib"; fi
 # _LT_SHELL_INIT(ARG)
 # -------------------
 m4_define([_LT_SHELL_INIT],
-[ifdef([AC_DIVERSION_NOTICE],
-            [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
-        [AC_DIVERT_PUSH(NOTICE)])
-$1
-AC_DIVERT_POP
-])# _LT_SHELL_INIT
+[m4_divert_text([M4SH-INIT], [$1
+])])# _LT_SHELL_INIT
 
 
-# _LT_PROG_ECHO_BACKSLASH
-# -----------------------
-# Add some code to the start of the generated configure script which
-# will find an echo command which doesn't interpret backslashes.
-m4_defun([_LT_PROG_ECHO_BACKSLASH],
-[_LT_SHELL_INIT([
-# Check that we are running under the correct shell.
-SHELL=${CONFIG_SHELL-/bin/sh}
-
-case X$lt_ECHO in
-X*--fallback-echo)
-  # Remove one level of quotation (which was required for Make).
-  ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
-  ;;
-esac
+# _LT_PROG_PRINTF_BACKSLASH
+# -------------------------
+# Find a working printf (either a program or a shell builtin)
+# that can be used to print values without interpreting backslashes
+# or strings with a leading `-'.
+m4_defun([_LT_PROG_PRINTF_BACKSLASH],
+[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+AC_MSG_CHECKING([for a working printf])
+if test "X`printf %s $ECHO`" = "X$ECHO"; then
+  ECHO='printf %s\n'
 
-ECHO=${lt_ECHO-echo}
-if test "X[$]1" = X--no-reexec; then
-  # Discard the --no-reexec flag, and continue.
-  shift
-elif test "X[$]1" = X--fallback-echo; then
-  # Avoid inline document here, it may be left over
-  :
-elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then
-  # Yippee, $ECHO works!
-  :
 else
-  # Restart under the correct shell.
-  exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
-fi
-
-if test "X[$]1" = X--fallback-echo; then
-  # used as fallback echo
-  shift
-  cat <<_LT_EOF
-[$]*
-_LT_EOF
-  exit 0
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+  for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+  do
+    IFS=$as_save_IFS
+    test "x$as_dir" = x && continue
+    test -f "$as_dir/printf" || test -f "$as_dir/printf.exe" || continue
+    test "X`$as_dir/printf %s $ECHO`" = "X$ECHO" &&
+      { ECHO=$as_dir/printf' %s\n' ; break; }
+  done
+  case "$ECHO" in
+    */printf*) ;;
+    *) 
+      lt_cmd_ECHO="printf %s\\\\n \"\$[]1\""
+      as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+      for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+      do
+        IFS=$as_save_IFS
+        test "x$as_dir" = x && continue
+        for as_base in sh bash ksh zsh sh5; do
+          as_shell=$as_dir/$as_base
+          test -f "$as_shell" || test -f "$as_shell.exe" || continue
+         lt_func_ECHO='func_do_echo () { '$as_shell' -c "$lt_cmd_ECHO" x 
"$[]1";}'
+          (lt_out=`$as_shell -c "
+               PATH=/tmp/nonexistent; export PATH;
+               FPATH=/tmp/nonexistent; export FPATH;
+               printf %s \"\\$[]1\"" lt_echo "$ECHO"`
+          test "X$lt_out" = "X$ECHO") &&
+            { eval "$lt_func_ECHO"; ECHO=func_do_echo; break 2; }
+        done
+      done
+  esac
 fi
 
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-if test -z "$lt_ECHO"; then
-  if test "X${echo_test_string+set}" != Xset; then
-    # find a string as large as possible, as long as the shell can cope with it
-    for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q 
"[$]0"' 'echo test'; do
-      # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
-      if { echo_test_string=`eval $cmd`; } 2>/dev/null &&
-        { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null
-      then
-        break
-      fi
-    done
-  fi
-
-  if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
-     echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
-     test "X$echo_testing_string" = "X$echo_test_string"; then
-    :
-  else
-    # The Solaris, AIX, and Digital Unix default echo programs unquote
-    # backslashes.  This makes it impossible to quote backslashes using
-    #   echo "$something" | sed 's/\\/\\\\/g'
-    #
-    # So, first we look for a working echo in the user's PATH.
-
-    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
-    for dir in $PATH /usr/ucb; do
-      IFS="$lt_save_ifs"
-      if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
-         test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
-         echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
-         test "X$echo_testing_string" = "X$echo_test_string"; then
-        ECHO="$dir/echo"
-        break
-      fi
-    done
-    IFS="$lt_save_ifs"
-
-    if test "X$ECHO" = Xecho; then
-      # We didn't find a better echo, so look for alternatives.
-      if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' &&
-         echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` &&
-         test "X$echo_testing_string" = "X$echo_test_string"; then
-        # This shell has a builtin print -r that does the trick.
-        ECHO='print -r'
-      elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&
-          test "X$CONFIG_SHELL" != X/bin/ksh; then
-        # If we have ksh, try running configure again with it.
-        ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
-        export ORIGINAL_CONFIG_SHELL
-        CONFIG_SHELL=/bin/ksh
-        export CONFIG_SHELL
-        exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
-      else
-        # Try using printf.
-        ECHO='printf %s\n'
-        if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
-          echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
-          test "X$echo_testing_string" = "X$echo_test_string"; then
-         # Cool, printf works
-         :
-        elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" 
--fallback-echo '\t') 2>/dev/null` &&
-            test "X$echo_testing_string" = 'X\t' &&
-            echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" 
--fallback-echo "$echo_test_string") 2>/dev/null` &&
-            test "X$echo_testing_string" = "X$echo_test_string"; then
-         CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
-         export CONFIG_SHELL
-         SHELL="$CONFIG_SHELL"
-         export SHELL
-         ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
-        elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 
2>/dev/null` &&
-            test "X$echo_testing_string" = 'X\t' &&
-            echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo 
"$echo_test_string") 2>/dev/null` &&
-            test "X$echo_testing_string" = "X$echo_test_string"; then
-         ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
-        else
-         # maybe with a smaller string...
-         prev=:
-
-         for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q 
"[$]0"' 'sed 50q "[$]0"'; do
-           if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null
-           then
-             break
-           fi
-           prev="$cmd"
-         done
+case "$ECHO" in
+  printf*) AC_MSG_RESULT([shell builtin]) ;;
+  */printf*) AC_MSG_RESULT([$as_dir/printf]) ;;
+  func_do_echo) AC_MSG_RESULT([$as_shell builtin]) ;;
+  *) AC_MSG_RESULT([not found])
+    AC_MSG_ERROR([cannot find a working printf]) ;;
+esac
 
-         if test "$prev" != 'sed 50q "[$]0"'; then
-           echo_test_string=`eval $prev`
-           export echo_test_string
-           exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" 
${1+"[$]@"}
-         else
-           # Oops.  We lost completely, so just stick with echo.
-           ECHO=echo
-         fi
-        fi
-      fi
-    fi
-  fi
-fi
+_LT_DECL([], [lt_cmd_ECHO], [1], [Used if there is no working printf in the 
path])
+_LT_DECL([], [lt_func_ECHO], [1], [Used if there is no working printf in the 
path])
+])
 
-# Copy echo and quote the copy suitably for passing to libtool from
-# the Makefile, instead of quoting the original, which is used later.
-lt_ECHO=$ECHO
-if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
-   lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
-fi
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Add some code to the start of the generated configure script which
+# will find a printf which doesn't interpret backslashes, and
+# which we can use as an echo command.  If possible, find a builtin.
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_PROG_PRINTF_BACKSLASH])dnl
+m4_ifdef([_AS_DETECT_SUGGESTED],
+[_AS_DETECT_SUGGESTED([
+  
ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+  ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+  ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+  PATH=/tmp/nonexistent; export PATH;
+  FPATH=$PATH; export FPATH;
+  test "X`printf %s $ECHO`" = "X$ECHO"])])
 
-AC_SUBST(lt_ECHO)
-])
 _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
-_LT_DECL([], [ECHO], [1],
-    [An echo program that does not interpret backslashes])
+_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
 ])# _LT_PROG_ECHO_BACKSLASH
 
 
@@ -1617,7 +1533,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
       # If test is not a shell built-in, we'll probably end up computing a
       # maximum length that is only half of the actual maximum length, but
       # we can't tell.
-      while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 
2>/dev/null` \
+      while { test "X"`$ECHO "X$teststring$teststring" 2>/dev/null` \
                 = "XX$teststring$teststring"; } >/dev/null 2>&1 &&
              test $i != 17 # 1/2 MB should be enough
       do
diff --git a/tests/testsuite.at b/tests/testsuite.at
index d03b67d..e8b75c3 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -32,12 +32,13 @@ m4_divert_push([PREPARE_TESTS])dnl
 : ${AUTOCONF=autoconf}
 : ${AUTOMAKE=automake}
 : ${AUTORECONF=autoreconf}
+: ${ECHO=$as_echo}
 for tool in ACLOCAL AUTOHEADER AUTOCONF AUTOMAKE AUTORECONF; do
   if eval \$$tool --version >/dev/null 2>&1; then :; else eval $tool=no; fi
 done
 export ACLOCAL AUTOHEADER AUTOCONF AUTOMAKE AUTORECONF
 eval `$LIBTOOL --config | grep '^EGREP='`
-eval `$LIBTOOL --config | $EGREP 
'^(host|host_os|host_alias|build|build_alias|ECHO)='`
+eval `$LIBTOOL --config | $EGREP 
'^(host|host_os|host_alias|build|build_alias)='`
 configure_options=--prefix=/nonexistent
 if test -n "$host_alias"; then
   configure_options="$configure_options --host $host_alias"
-- 
1.5.5





reply via email to

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