Enhancement: Make tzselect work in tiny shells

Peter Seebach peter.seebach at windriver.com
Thu Oct 2 16:01:40 UTC 2008


We occasionally want to install glibc (and with it, tzselect) on tiny  
little systems where "install ksh or bash" is not a viable choice.   
The following patch to the tzselect source makes the select loops work  
in any SVR3 or later shell (including BusyBox ash, which is the big  
one I care about).

--- tzselect.ksh
+++ tzselect.sh
@@ -1,6 +1,6 @@
-#! @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.
@@ -9,18 +9,6 @@

  # 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.
  # 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 +21,71 @@
  #	mawk
  #	</a>

+# Distilled from autoconf.
+case `echo -n foo\c` in
+*n*c*)	echo_n() { echo "$@"; };;
+*n*)	echo_n() { echo "$@\c"; };;
+*)	echo_n() { echo -n "$@"; };;
+esac
+
+func_select () {
+    func_select_args=0
+    case $1 in
+    [!_a-zA-Z]* | *[!_a-zA-Z0-9]* )
+        echo >&2 "func_select: '$1' is not a valid variable name."
+        return 1
+        ;;
+    esac
+    func_select_var=$1
+    shift
+
+    case $1 in
+    in) shift;;
+    *) echo >&2 "func_select: usage: func_select var in ..."; 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
+        echo_n >&2 "${PS3:-#? }"
+        if read REPLY; then
+            if test -n "${REPLY}"; then
+                case $REPLY in
+                0* | *[!0-9]* )
+                    eval $func_select_var=
+                    ;;
+                *)
+                    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
+                    ;;
+                esac
+                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 at windriver.com>
Listen, get this.  Nobody with a good compiler needs to be justified.




More information about the tz mailing list