1#! /bin/sh
2
3# func_exit STATUS
4# exit with status
5func_exit ()
6{
7  (exit $1); exit $1
8}
9
10# func_fatal_error message
11# outputs to stderr a fatal error message, and terminates the program.
12func_fatal_error ()
13{
14  echo "test-echo.sh: *** $1" 1>&2
15  echo "test-echo.sh: *** Stop." 1>&2
16  func_exit 1
17}
18
19# Ensure an 'echo' command that does not interpret backslashes.
20# Test cases:
21#   echo '\n' | wc -l                 prints 1 when OK, 2 when KO
22#   echo '\t' | grep t > /dev/null    has return code 0 when OK, 1 when KO
23# This problem is a weird heritage from SVR4. BSD got it right (except that
24# BSD echo interprets '-n' as an option, which is also not desirable).
25# Nowadays the problem occurs in 4 situations:
26# - in bash, when the shell option xpg_echo is set (bash >= 2.04)
27#            or when it was built with --enable-usg-echo-default (bash >= 2.0)
28#            or when it was built with DEFAULT_ECHO_TO_USG (bash < 2.0),
29# - in zsh, when sh-emulation is not set,
30# - in ksh (e.g. AIX /bin/sh and Solaris /usr/xpg4/bin/sh are ksh instances,
31#           and HP-UX /bin/sh and IRIX /bin/sh behave similarly),
32# - in Solaris /bin/sh and OSF/1 /bin/sh.
33# We try the following workarounds:
34# - for all: respawn using $CONFIG_SHELL if that is set and works.
35# - for bash >= 2.04: unset the shell option xpg_echo.
36# - for bash >= 2.0: define echo to a function that uses the printf built-in.
37# - for bash < 2.0: define echo to a function that uses cat of a here document.
38# - for zsh: turn sh-emulation on.
39# - for ksh: alias echo to 'print -r'.
40# - for ksh: alias echo to a function that uses cat of a here document.
41# - for Solaris /bin/sh and OSF/1 /bin/sh: respawn using /bin/ksh and rely on
42#   the ksh workaround.
43# - otherwise: respawn using /bin/sh and rely on the workarounds.
44# When respawning, we pass --no-reexec as first argument, so as to avoid
45# turning this script into a fork bomb in unlucky situations.
46have_echo=
47if echo '\t' | grep t > /dev/null; then
48  have_echo=yes # Lucky!
49fi
50# Try the workarounds.
51# Respawn using $CONFIG_SHELL if that is set and works.
52if test -z "$have_echo" \
53   && test "X$1" != "X--no-reexec" \
54   && test -n "$CONFIG_SHELL" \
55   && test -f "$CONFIG_SHELL" \
56   && $CONFIG_SHELL -c 'echo '\t' | grep t > /dev/null'; then
57  exec $CONFIG_SHELL "$0" --no-reexec "$@"
58  exit 127
59fi
60# For bash >= 2.04: unset the shell option xpg_echo.
61if test -z "$have_echo" \
62   && test -n "$BASH_VERSION" \
63   && (shopt -o xpg_echo; echo '\t' | grep t > /dev/null) 2>/dev/null; then
64  shopt -o xpg_echo
65  have_echo=yes
66fi
67# For bash >= 2.0: define echo to a function that uses the printf built-in.
68# For bash < 2.0: define echo to a function that uses cat of a here document.
69# (There is no win in using 'printf' over 'cat' if it is not a shell built-in.)
70if test -z "$have_echo" \
71   && test -n "$BASH_VERSION"; then \
72  if type printf 2>/dev/null | grep / > /dev/null; then
73    # 'printf' is not a shell built-in.
74echo ()
75{
76cat <<EOF
77$*
78EOF
79}
80  else
81    # 'printf' is a shell built-in.
82echo ()
83{
84  printf '%s\n' "$*"
85}
86  fi
87  if echo '\t' | grep t > /dev/null; then
88    have_echo=yes
89  fi
90fi
91# For zsh: turn sh-emulation on.
92if test -z "$have_echo" \
93   && test -n "$ZSH_VERSION" \
94   && (emulate sh) >/dev/null 2>&1; then
95  emulate sh
96fi
97# For ksh: alias echo to 'print -r'.
98if test -z "$have_echo" \
99   && (type print) >/dev/null 2>&1; then
100  # A 'print' command exists.
101  if type print 2>/dev/null | grep / > /dev/null; then
102    :
103  else
104    # 'print' is a shell built-in.
105    if (print -r '\told' | grep told > /dev/null) 2>/dev/null; then
106      # 'print' is the ksh shell built-in.
107      alias echo='print -r'
108    fi
109  fi
110fi
111if test -z "$have_echo" \
112   && echo '\t' | grep t > /dev/null; then
113  have_echo=yes
114fi
115# For ksh: alias echo to a function that uses cat of a here document.
116# The ksh manual page says:
117#   "Aliasing is performed when scripts are read, not while they are executed.
118#    Therefore, for an alias to take effect, the alias definition command has
119#    to be executed before the command which references the alias is read."
120# Because of this, we have to play strange tricks with have_echo, to ensure
121# that the top-level statement containing the test starts after the 'alias'
122# command.
123if test -z "$have_echo"; then
124bsd_echo ()
125{
126cat <<EOF
127$*
128EOF
129}
130alias echo=bsd_echo 2>/dev/null
131fi
132if test -z "$have_echo" \
133   && echo '\t' | grep t > /dev/null; then
134  have_echo=yes
135fi
136if test -z "$have_echo"; then
137  unalias echo 2>/dev/null
138fi
139# For Solaris /bin/sh and OSF/1 /bin/sh: respawn using /bin/ksh.
140if test -z "$have_echo" \
141   && test "X$1" != "X--no-reexec" \
142   && test -f /bin/ksh; then
143  exec /bin/ksh "$0" --no-reexec "$@"
144  exit 127
145fi
146# Otherwise: respawn using /bin/sh.
147if test -z "$have_echo" \
148   && test "X$1" != "X--no-reexec" \
149   && test -f /bin/sh; then
150  exec /bin/sh "$0" --no-reexec "$@"
151  exit 127
152fi
153if test -z "$have_echo"; then
154  func_fatal_error "Shell does not support 'echo' correctly. Please install GNU bash and set the environment variable CONFIG_SHELL to point to it."
155fi
156if echo '\t' | grep t > /dev/null; then
157  : # Works fine now.
158else
159  func_fatal_error "Shell does not support 'echo' correctly. Workaround does not work. Please report this as a bug to bug-gnulib@gnu.org."
160fi
161if test "X$1" = "X--no-reexec"; then
162  shift
163fi
164
165# This command determines the exit code.
166echo '\t' | grep t > /dev/null
167