tzselect: eliminate ksh-dependency This is an adapted version of a patch originally by Peter Seebach found here: http://www.eglibc.org/archives/patches/msg00671.html Upstream-Status: Pending Signed-off-by: Paul Eggleton Index: libc/timezone/tzselect.ksh =================================================================== --- libc.orig/timezone/tzselect.ksh 2012-11-17 09:50:14.000000000 -0800 +++ libc/timezone/tzselect.ksh 2013-01-03 22:46:26.423844259 -0800 @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh PKGVERSION='(tzcode) ' TZVERSION=see_Makefile @@ -11,23 +11,80 @@ # Porting notes: # -# This script requires a Posix-like shell with the extension of a -# 'select' statement. The 'select' statement was introduced in the -# Korn shell and is available in Bash and other shell implementations. -# If your host lacks both Bash and the Korn shell, you can get their -# source from one of these locations: +# func_select allows this script to run on shells (such as busybox ash) +# which lack the ksh "select" builtin. # -# Bash -# Korn Shell -# Public Domain Korn Shell -# -# This script also uses several features of modern awk programs. +# 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, # you can use either of the following free programs instead: # # Gawk (GNU awk) # mawk +# 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} @@ -72,7 +129,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 @@ -92,7 +149,7 @@ echo >&2 'Please select a continent or ocean.' - select continent in \ + while func_select continent in \ Africa \ Americas \ Antarctica \ @@ -172,7 +229,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.';; @@ -211,7 +268,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.';; @@ -288,7 +345,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.';;