[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[patches] Patch: Eliminate ksh-dependency in tzselect
- To: patches@xxxxxxxxxx
- Subject: [patches] Patch: Eliminate ksh-dependency in tzselect
- From: Peter Seebach <peter.seebach@xxxxxxxxxxxxx>
- Date: Mon, 22 Jun 2009 14:01:43 -0500
This patch (which I think is right, but I haven't retested it since I
first set it up) removes the dependency on ksh from tzselect.
Looking at the code associated with ldd and xtrace, it looks like
there is already some support in the elf/Makefile code for building
ldd for plain-old-sh, by stripping the leading $. This used to have
an additional problem ("set -o pipefail" caused ash to exit rather
than merely failing), but that seems to be fixed.
We have some interest in seeing this fixed, since we like to ship tiny
filesystems without bash or ksh. (Requiring ash rather than msh is
fine by me.)
Copyright issues: The substantive thing here is func_select, which is
actually mine personally (it's from my shell book) rather than WRS's.
I don't think anyone cares about the ownership of the change from
"select" to "while func_select", but you're welcome to it. I have
given the func_select code away before and I believe I've placed it in
the public domain.
This needs more testing than I have time for right now, but the basic
trick of reimplementing select as a function is well-tested.
--- glibc-2.8.orig/timezone/tzselect.ksh 2009-06-22 11:23:11.000000000
-0700
+++ glibc-2.8/timezone/tzselect.sh 2009-06-22 11:52:26.000000000 -0700
@@ -1,27 +1,16 @@
-#! @KSH@
+#! @SH@
-# '@(#)tzselect.ksh 8.1'
+# '@(#)tzselect.sh 8.1'
# Ask the user about the time zone, and output the resulting TZ
value to stdout.
# Interact with the user via stderr and stdin.
# Contributed by Paul Eggert.
-# Porting notes:
-#
-# This script requires several features of the Korn shell.
-# If your host lacks the Korn shell,
-# you can use either of the following free programs instead:
-#
-# <a href=ftp://ftp.gnu.org/pub/gnu/>
-# Bourne-Again shell (bash)
-# </a>
-#
-# <a href=ftp://ftp.cs.mun.ca/pub/pdksh/pdksh.tar.gz>
-# Public domain ksh
-# </a>
-#
-# This script also uses several features of modern awk programs.
+# func_select allows this script to run on shells (such as busybox ash)
+# which lack the ksh "select" builtin.
+
+# This script uses several features of modern awk programs.
# If your host lacks awk, or has an old awk that does not conform to
Posix.2,
# you can use either of the following free programs instead:
#
@@ -33,6 +22,70 @@
# mawk
# </a>
+# Implement ksh-style select in POSIX shell
+
+# We need a mostly-portable echo-n.
+case `echo -n "foo\c"` in
+*n*c*) func_echo_n() { echo "$*"; } ;;
+*n*) func_echo_n() { echo "$*\c"; } ;;
+*) func_echo_n() { echo -n "$*"; } ;;
+esac
+
+# Synopsis: Replace "select foo in list" with "while func_select foo
in list"
+# and this works just like ksh, so far as I know.
+func_select () {
+ func_select_args=0
+ if expr "$1" : "^[_a-zA-Z][_a-zA-Z0-9]*$" > /dev/null; then
+ func_select_var=$1
+ else
+ echo >&2 "func_select: '$1' is not a valid variable name."
+ return 1
+ fi
+ shift 1
+ case $1 in
+ in) shift 1;;
+ *) echo >&2 "func_select: usage: func_select var in ... (you must
provide
+arguments)"; return 1;;
+ esac
+ case $# in
+ 0) echo >&2 "func_select: usage: func_select var in ..."; return 1;;
+ esac
+ for func_select_arg
+ do
+ func_select_args=`expr $func_select_args + 1`
+ eval func_select_a_$func_select_args=\$func_select_arg
+ done
+ REPLY=""
+ while :
+ do
+ if test -z "$REPLY"; then
+ func_select_i=1
+ while test $func_select_i -le $func_select_args
+ do
+ eval echo "\"\$func_select_i) \$func_select_a_$func_select_i\""
+ func_select_i=`expr $func_select_i + 1`
+ done
+ fi
+ func_echo_n "${PS3-#? }" >&2
+ if read REPLY; then
+ if test -n "${REPLY}"; then
+ if expr "$REPLY" : '^[1-9][0-9]*$' > /dev/null; then
+ if test "$REPLY" -ge 1 && test "$REPLY" -le $func_select_args;
then
+ eval $func_select_var=\$func_select_a_$REPLY
+ else
+ eval $func_select_var=
+ fi
+ else
+ eval $func_select_var=
+ fi
+ return 0
+ fi
+ else
+ eval $func_select_var=
+ return 1
+ fi
+ done
+}
# Specify default values for environment variables if they are unset.
: ${AWK=awk}
@@ -62,7 +115,7 @@
# Work around a bug in bash 1.14.7 and earlier, where $PS3 is sent
to stdout.
-case $(echo 1 | (select x in x; do break; done) 2>/dev/null) in
+case $(echo 1 | (while func_select x in x; do break; done) 2>/dev/
null) in
?*) PS3=
esac
@@ -82,7 +135,7 @@
echo >&2 'Please select a continent or ocean.'
- select continent in \
+ while func_select continent in \
Africa \
Americas \
Antarctica \
@@ -162,7 +215,7 @@
case $countries in
*"$newline"*)
echo >&2 'Please select a country.'
- select country in $countries
+ while func_select country in $countries
do
case $country in
'') echo >&2 'Please enter a number in range.';;
@@ -201,7 +254,7 @@
*"$newline"*)
echo >&2 'Please select one of the following' \
'time zone regions.'
- select region in $regions
+ while func_select region in $regions
do
case $region in
'') echo >&2 'Please enter a number in range.';;
@@ -278,7 +331,7 @@
echo >&2 "Is the above information OK?"
ok=
- select ok in Yes No
+ while func_select ok in Yes No
do
case $ok in
'') echo >&2 'Please enter 1 for Yes, or 2 for No.';;
--
Peter Seebach <peter.seebach@xxxxxxxxxxxxx>
Listen, get this. Nobody with a good compiler needs to be justified.