mirror of
git://git.savannah.gnu.org/libtool.git
synced 2024-12-27 07:09:26 +08:00
51c1877e70
Dash shipped with Ubutu-11.10 as /bin/sh, among others, still has a crippled echo builtin that mis-handles backslashes. * build-aux/options-parser (bs_echo): Adopt the autoconf echo normalization code to find a suitable replacement for buggy echo commands. Adjust all uses of echo to $bs_echo. * build-aux/extract-trace (func_extract_trace, func_main): Likewise. * bootstrap: To retain some execution speed on platforms with buggy builtin echo, replace most occurrences of `echo' with `$bs_echo' - except where its arguments will obviously never contain backslashes or be overly long. Reported by Reuben Thomas. Signed-off-by: Gary V. Vaughan <gary@gnu.org>
837 lines
24 KiB
Bash
837 lines
24 KiB
Bash
#! /bin/sh
|
|
|
|
# Set a version string for this script.
|
|
scriptversion=2011-11-20.12; # UTC
|
|
|
|
# A pluggable option parser for Bourne shell.
|
|
# Written by Gary V. Vaughan, 2010
|
|
|
|
# Copyright (C) 2010, 2011 Free Software Foundation, Inc.
|
|
# This is free software; see the source for copying conditions. There is NO
|
|
# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
# Please report bugs or propose patches to bug-gnulib@gnu.org.
|
|
|
|
|
|
## ------ ##
|
|
## Usage. ##
|
|
## ------ ##
|
|
|
|
# This file is a library for parsing options in your shell scripts along
|
|
# with assorted other useful supporting features that you can make use
|
|
# of too.
|
|
#
|
|
# For the simplest scripts you might need only:
|
|
#
|
|
# #!/bin/sh
|
|
# . relative/path/to/options-parser
|
|
# scriptversion=1.0
|
|
# func_options ${1+"$@"}
|
|
# eval set dummy "$func_options_result"; shift
|
|
# ...rest of your script...
|
|
#
|
|
# In order for the `--version' option to work, you will need to have a
|
|
# suitably formatted comment like the one at the top of this file
|
|
# starting with '# Written by ' and ending with '# warranty; '.
|
|
#
|
|
# For `-h' and `--help' to work, you will also need a one line
|
|
# description of your script's purpose in a comment directly above the
|
|
# '# Written by ' line, like the one at the top of this file.
|
|
#
|
|
# The default options also support `--debug', which will turn on shell
|
|
# execution tracing (see the comment above debug_cmd below for another
|
|
# use), and `--verbose' and the func_verbose function to allow your script
|
|
# to display verbose messages only when your user has specified
|
|
# `--verbose'.
|
|
#
|
|
# After sourcing this file, you can plug processing for additional
|
|
# options by amending the variables from the `Configuration' section
|
|
# below, and following the instructions in the `Option parsing'
|
|
# section further down.
|
|
|
|
## -------------------- ##
|
|
## Shell normalisation. ##
|
|
## -------------------- ##
|
|
|
|
# Some shells need a little help to be as Bourne compatible as possible.
|
|
# Before doing anything else, make sure all that help has been provided!
|
|
|
|
DUALCASE=1; export DUALCASE # for MKS sh
|
|
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
|
|
emulate sh
|
|
NULLCMD=:
|
|
# Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
|
|
# is contrary to our usage. Disable this feature.
|
|
alias -g '${1+"$@"}'='"$@"'
|
|
setopt NO_GLOB_SUBST
|
|
else
|
|
case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac
|
|
fi
|
|
|
|
# NLS nuisances.
|
|
LANGUAGE=C
|
|
export LANGUAGE
|
|
|
|
# Ensure file names are sorted consistently across platforms.
|
|
LC_ALL=C
|
|
export LC_ALL
|
|
|
|
# CDPATH.
|
|
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
|
|
|
|
|
|
## ------------------------------- ##
|
|
## User overridable command paths. ##
|
|
## ------------------------------- ##
|
|
|
|
# All uppercase variable names are used for environment variables. These
|
|
# variables can be overridden by the user before calling a script that
|
|
# uses them if a suitable command of that name is not already available
|
|
# in the command search PATH.
|
|
|
|
: ${SED="sed"}
|
|
|
|
|
|
## -------------- ##
|
|
## Configuration. ##
|
|
## -------------- ##
|
|
|
|
# You should override these variables in your script after sourcing this
|
|
# file so that they reflect the customisations you have added to the
|
|
# option parser.
|
|
|
|
# The usage line for option parsing errors and the start of `-h' and
|
|
# `--help' output messages. You can embed shell variables for delayed
|
|
# expansion at the time the message is displayed, but you will need to
|
|
# quote other shell meta-characters carefully to prevent them being
|
|
# expanded when the contents are evaled.
|
|
usage='$progpath [OPTION]...'
|
|
|
|
# Short help message in response to `-h' and `--help'. Add to this or
|
|
# override it after sourcing this library to reflect the full set of
|
|
# options your script accepts.
|
|
usage_message="\
|
|
--debug enable verbose shell tracing
|
|
-v, --verbose verbosely report processing
|
|
--version print version information and exit
|
|
-h, --help print short or long help message and exit
|
|
"
|
|
|
|
# Additional text appended to `usage_message' in response to `--help'.
|
|
long_help_message=
|
|
|
|
# Help message printed before fatal option parsing errors.
|
|
fatal_help='Try \`$progname --help'\'' for more information.'
|
|
|
|
|
|
|
|
## ----------------- ##
|
|
## Global variables. ##
|
|
## ----------------- ##
|
|
|
|
# Except for the global variables explicitly listed below, the following
|
|
# functions in the '^func_' namespace, and the '^require_' namespace
|
|
# variables initialised in the `Resource management' section, sourcing
|
|
# this file will not pollute your global namespace with anything
|
|
# else. There's no portable way to scope variables in Bourne shell
|
|
# though, so actually running these functions will sometimes place
|
|
# results into a variable named after the function, and often use
|
|
# temporary variables in the `^_G_' namespace. If you are careful to
|
|
# avoid using those namespaces casually in your sourcing script, things
|
|
# should continue to work as you expect. And, of course, you can freely
|
|
# overwrite any of the functions or variables defined here before
|
|
# calling anything to customize them.
|
|
|
|
EXIT_SUCCESS=0
|
|
EXIT_FAILURE=1
|
|
EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing.
|
|
EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake.
|
|
|
|
# Allow overriding, eg assuming that you follow the convention of
|
|
# putting `$debug_cmd' at the start of all your functions, you can get
|
|
# bash to show function call trace with:
|
|
# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash bootstrap
|
|
debug_cmd=${debug_cmd-":"}
|
|
exit_cmd=:
|
|
|
|
dirname='s|/[^/]*$||'
|
|
basename='s|^.*/||'
|
|
|
|
nl='
|
|
'
|
|
|
|
# There are still modern systems that have problems with `echo' mis-
|
|
# handling backslashes, among others, so make sure $bs_echo is set to a
|
|
# command that correctly interprets backslashes.
|
|
# (this code from Autoconf 2.62)
|
|
|
|
# Printing a long string crashes Solaris 7 /usr/bin/printf.
|
|
bs_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
|
|
bs_echo=$bs_echo$bs_echo$bs_echo$bs_echo$bs_echo
|
|
bs_echo=$bs_echo$bs_echo$bs_echo$bs_echo$bs_echo$bs_echo
|
|
# Prefer a ksh shell builtin over an external printf program on Solaris,
|
|
# but without wasting forks for bash or zsh.
|
|
if test -z "$BASH_VERSION$ZSH_VERSION" \
|
|
&& (test "X`print -r -- $bs_echo`" = "X$bs_echo") 2>/dev/null; then
|
|
bs_echo='print -r --'
|
|
bs_echo_n='print -rn --'
|
|
elif (test "X`printf %s $bs_echo`" = "X$bs_echo") 2>/dev/null; then
|
|
bs_echo='printf %s\n'
|
|
bs_echo_n='printf %s'
|
|
else
|
|
if test "X`(/usr/ucb/echo -n -n $bs_echo) 2>/dev/null`" = "X-n $bs_echo"; then
|
|
bs_echo_body='eval /usr/ucb/echo -n "$1$nl"'
|
|
bs_echo_n='/usr/ucb/echo -n'
|
|
else
|
|
bs_echo_body='eval expr "X$1" : "X\\(.*\\)"'
|
|
bs_echo_n_body='eval
|
|
arg=$1;
|
|
case $arg in #(
|
|
*"$nl"*)
|
|
expr "X$arg" : "X\\(.*\\)$nl";
|
|
arg=`expr "X$arg" : ".*$nl\\(.*\\)"`;;
|
|
esac;
|
|
expr "X$arg" : "X\\(.*\\)" | tr -d "$nl"
|
|
'
|
|
export bs_echo_n_body
|
|
bs_echo_n='sh -c $bs_echo_n_body bs_echo'
|
|
fi
|
|
export bs_echo_body
|
|
bs_echo='sh -c $bs_echo_body bs_echo'
|
|
fi
|
|
|
|
# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
|
|
# is ksh but when the shell is invoked as "sh" and the current value of
|
|
# the _XPG environment variable is not equal to 1 (one), the special
|
|
# positional parameter $0, within a function call, is the name of the
|
|
# function.
|
|
progpath=$0
|
|
|
|
# The name of this program.
|
|
progname=`$bs_echo "$progpath" |$SED "$basename"`
|
|
|
|
|
|
## ------------------------- ##
|
|
## Hook function management. ##
|
|
## ------------------------- ##
|
|
|
|
# This section contains functions for adding, removing, and running hooks
|
|
# to the main code. A hook is just a named list of of function, that can
|
|
# be run in order later on.
|
|
|
|
|
|
# func_append VAR VALUE
|
|
# ---------------------
|
|
# Append VALUE onto the existing contents of VAR.
|
|
if (eval 'x=a; x+=" b"; test "x$x" = "xa b"') 2>/dev/null
|
|
then
|
|
# This is an XSI compatible shell, allowing a faster implementation...
|
|
eval 'func_append ()
|
|
{
|
|
$debug_cmd
|
|
|
|
eval "$1+=\$2"
|
|
}'
|
|
else
|
|
# ...otherwise fall back to using expr, which is often a shell builtin.
|
|
func_append ()
|
|
{
|
|
$debug_cmd
|
|
|
|
eval "$1=\$$1\$2"
|
|
}
|
|
fi
|
|
|
|
|
|
# func_hookable FUNC_NAME
|
|
# -----------------------
|
|
# Declare that FUNC_NAME will run hooks added with
|
|
# `func_add_hook FUNC_NAME ...'.
|
|
func_hookable ()
|
|
{
|
|
$debug_cmd
|
|
|
|
func_append hookable_fns " $1"
|
|
}
|
|
|
|
|
|
# func_add_hook FUNC_NAME HOOK_FUNC
|
|
# ---------------------------------
|
|
# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must
|
|
# first have been declared "hookable" by a call to `func_hookable'.
|
|
func_add_hook ()
|
|
{
|
|
$debug_cmd
|
|
|
|
case " $hookable_fns " in
|
|
*" $1 "*) ;;
|
|
*) func_fatal_error "\`$1' does not accept hook functions." ;;
|
|
esac
|
|
|
|
eval func_append ${1}_hooks '" $2"'
|
|
}
|
|
|
|
|
|
# func_remove_hook FUNC_NAME HOOK_FUNC
|
|
# ------------------------------------
|
|
# Remove HOOK_FUNC from the list of functions called by FUNC_NAME.
|
|
func_remove_hook ()
|
|
{
|
|
$debug_cmd
|
|
|
|
eval ${1}_hooks='`$bs_echo "\$'$1'_hooks" |$SED "s| '$2'||"`'
|
|
}
|
|
|
|
|
|
# func_run_hooks FUNC_NAME [ARG]...
|
|
# ---------------------------------
|
|
# Run all hook functions registered to FUNC_NAME.
|
|
# It is assumed that the list of hook functions contains nothing more
|
|
# than a whitespace-delimited list of legal shell function names, and
|
|
# no effort is wasted trying to catch shell meta-characters or preserve
|
|
# whitespace.
|
|
func_run_hooks ()
|
|
{
|
|
$debug_cmd
|
|
|
|
case " $hookable_fns " in
|
|
*" $1 "*) ;;
|
|
*) func_fatal_error "\`$1' does not support hook funcions.n" ;;
|
|
esac
|
|
|
|
eval _G_hook_fns=\$$1_hooks; shift
|
|
|
|
for _G_hook in $_G_hook_fns; do
|
|
eval $_G_hook '"$@"'
|
|
|
|
# store returned options list back into positional
|
|
# parameters for next `cmd' execution.
|
|
eval set dummy \$${_G_hook}_result; shift
|
|
done
|
|
|
|
func_quote_for_eval ${1+"$@"}
|
|
func_run_hooks_result=$func_quote_for_eval_result
|
|
}
|
|
|
|
|
|
|
|
## --------------- ##
|
|
## Option parsing. ##
|
|
## --------------- ##
|
|
|
|
# In order to add your own option parsing hooks, you must accept the
|
|
# full positional parameter list in your hook function, remove any
|
|
# options that you action, and then pass back the remaining unprocessed
|
|
# options in `<hooked_function_name>_result', escaped suitably for
|
|
# `eval'. Like this:
|
|
#
|
|
# my_options_prep ()
|
|
# {
|
|
# $debug_cmd
|
|
#
|
|
# # Extend the existing usage message.
|
|
# usage_message=$usage_message'
|
|
# -s, --silent don'\''t print informational messages
|
|
# '
|
|
#
|
|
# func_quote_for_eval ${1+"$@"}
|
|
# my_options_prep_result=$func_quote_for_eval_result
|
|
# }
|
|
# func_add_hook func_options_prep my_options_prep
|
|
#
|
|
#
|
|
# my_silent_option ()
|
|
# {
|
|
# $debug_cmd
|
|
#
|
|
# # Note that for efficiency, we parse as many options as we can
|
|
# # recognise in a loop before passing the remainder back to the
|
|
# # caller on the first unrecognised argument we encounter.
|
|
# while test $# -gt 0; do
|
|
# opt=$1; shift
|
|
# case $opt in
|
|
# --silent|-s) opt_silent=: ;;
|
|
# # Separate non-argument short options:
|
|
# -s*) func_split_short_opt "$_G_opt"
|
|
# set dummy "$func_split_short_opt_name" \
|
|
# "-$func_split_short_opt_arg" ${1+"$@"}
|
|
# shift
|
|
# ;;
|
|
# *) set dummy "$_G_opt" "$*"; shift; break ;;
|
|
# esac
|
|
# done
|
|
#
|
|
# func_quote_for_eval ${1+"$@"}
|
|
# my_silent_option_result=$func_quote_for_eval_result
|
|
# }
|
|
# func_add_hook func_parse_options my_silent_option
|
|
#
|
|
#
|
|
# my_option_validation ()
|
|
# {
|
|
# $debug_cmd
|
|
#
|
|
# $opt_silent && $opt_verbose && func_fatal_help "\
|
|
# \`--silent' and \`--verbose' options are mutually exclusive."
|
|
#
|
|
# func_quote_for_eval ${1+"$@"}
|
|
# my_option_validation_result=$func_quote_for_eval_result
|
|
# }
|
|
# func_add_hook func_validate_options my_option_validation
|
|
#
|
|
# You'll alse need to manually amend $usage_message to reflect the extra
|
|
# options you parse. It's preferable to append if you can, so that
|
|
# multiple option parsing hooks can be added safely.
|
|
|
|
|
|
# func_options [ARG]...
|
|
# ---------------------
|
|
# All the functions called inside func_options are hookable. See the
|
|
# individual implementations for details.
|
|
func_hookable func_options
|
|
func_options ()
|
|
{
|
|
$debug_cmd
|
|
|
|
func_options_prep ${1+"$@"}
|
|
eval func_parse_options \
|
|
${func_options_prep_result+"$func_options_prep_result"}
|
|
eval func_validate_options \
|
|
${func_parse_options_result+"$func_parse_options_result"}
|
|
|
|
eval func_run_hooks func_options \
|
|
${func_validate_options_result+"$func_validate_options_result"}
|
|
|
|
# save modified positional parameters for caller
|
|
func_options_result=$func_run_hooks_result
|
|
}
|
|
|
|
|
|
# func_options_prep [ARG]...
|
|
# --------------------------
|
|
# All initialisations required before starting the option parse loop.
|
|
# Note that when calling hook functions, we pass through the list of
|
|
# positional parameters. If a hook function modifies that list, and
|
|
# needs to propogate that back to rest of this script, then the complete
|
|
# modified list must be put in `func_run_hooks_result' before
|
|
# returning.
|
|
func_hookable func_options_prep
|
|
func_options_prep ()
|
|
{
|
|
$debug_cmd
|
|
|
|
# Option defaults:
|
|
opt_verbose=false
|
|
|
|
func_run_hooks func_options_prep ${1+"$@"}
|
|
|
|
# save modified positional parameters for caller
|
|
func_options_prep_result=$func_run_hooks_result
|
|
}
|
|
|
|
|
|
# func_parse_options [ARG]...
|
|
# ---------------------------
|
|
# The main option parsing loop.
|
|
func_hookable func_parse_options
|
|
func_parse_options ()
|
|
{
|
|
$debug_cmd
|
|
|
|
func_parse_options_result=
|
|
|
|
# this just eases exit handling
|
|
while test $# -gt 0; do
|
|
# Defer to hook functions for initial option parsing, so they
|
|
# get priority in the event of reusing an option name.
|
|
func_run_hooks func_parse_options ${1+"$@"}
|
|
|
|
# Adjust func_parse_options positional parameters to match
|
|
eval set dummy $func_run_hooks_result; shift
|
|
|
|
_G_opt=$1
|
|
shift
|
|
case $_G_opt in
|
|
--debug|-x) debug_cmd='set -x'
|
|
func_echo "enabling shell trace mode"
|
|
$debug_cmd
|
|
;;
|
|
|
|
--verbose|-v) opt_verbose=: ;;
|
|
--version) func_version ;;
|
|
-\?|-h) func_usage ;;
|
|
--help) func_help ;;
|
|
|
|
# Separate optargs to long options (plugins may need this):
|
|
--*=*) func_split_equals "$opt"
|
|
set dummy "$func_split_equals_lhs" \
|
|
"$func_split_equals_rhs" ${1+"$@"}
|
|
shift
|
|
;;
|
|
|
|
# Separate non-argument short options:
|
|
-\?*|-h*|-v*|-x*)
|
|
func_split_short_opt "$_G_opt"
|
|
set dummy "$func_split_short_opt_name" \
|
|
"-$func_split_short_opt_arg" ${1+"$@"}
|
|
shift
|
|
;;
|
|
|
|
--) set dummy "$_G_opt" "*"; shift; break ;;
|
|
-*) func_fatal_help "unrecognised option: \`$_G_opt'" ;;
|
|
*) set dummy "$_G_opt" "$*"; shift; break ;;
|
|
esac
|
|
done
|
|
|
|
# save modified positional parameters for caller
|
|
func_quote_for_eval ${1+"$@"}
|
|
func_parse_options_result=$func_quote_for_eval_result
|
|
}
|
|
|
|
|
|
# func_validate_options [ARG]...
|
|
# ------------------------------
|
|
# Perform any sanity checks on option settings and/or unconsumed
|
|
# arguments.
|
|
func_hookable func_validate_options
|
|
func_validate_options ()
|
|
{
|
|
$debug_cmd
|
|
|
|
func_run_hooks func_validate_options ${1+"$@"}
|
|
|
|
# Bail if the options were screwed!
|
|
$exit_cmd $EXIT_FAILURE
|
|
|
|
# save modified positional parameters for caller
|
|
func_validate_options_result=$func_run_hooks_result
|
|
}
|
|
|
|
|
|
|
|
## -------------------- ##
|
|
## Resource management. ##
|
|
## -------------------- ##
|
|
|
|
# This section contains definitions for functions that each ensure a
|
|
# particular resource (a file, or a non-empty configuration variable for
|
|
# example) is available, and if appropriate to extract default values
|
|
# from pertinent package files. Call them using their associated
|
|
# `require_*' variable to ensure that they are executed, at most, once.
|
|
#
|
|
# It's entirely deliberate that calling these functions can set
|
|
# variables that don't obey the namespace limitations obeyed by the rest
|
|
# of this file, in order that that they be as useful as possible to
|
|
# callers.
|
|
|
|
|
|
# require_term_colors
|
|
# -------------------
|
|
# Allow display of bold text on terminals that support it.
|
|
require_term_colors=func_require_term_colors
|
|
func_require_term_colors ()
|
|
{
|
|
$debug_cmd
|
|
|
|
test -t 1 && {
|
|
test -n "`tput sgr0 2>/dev/null`" && {
|
|
tc_reset=`tput sgr0`
|
|
test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold`
|
|
tc_standout=$tc_bold
|
|
test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso`
|
|
test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1`
|
|
test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2`
|
|
test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4`
|
|
test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5`
|
|
}
|
|
}
|
|
|
|
require_term_colors=:
|
|
}
|
|
|
|
|
|
## ------------------##
|
|
## Helper functions. ##
|
|
## ------------------##
|
|
|
|
# This section contains the helper functions used by the rest of the
|
|
# hookable option parser framework in ascii-betical order.
|
|
|
|
# func_echo ARG...
|
|
# ----------------
|
|
# Echo program name prefixed message, taking newlines into account.
|
|
func_echo ()
|
|
{
|
|
_G_message=$*
|
|
|
|
save_IFS=$IFS
|
|
IFS=$nl
|
|
for _G_line in $_G_message; do
|
|
IFS=$save_IFS
|
|
$bs_echo "$progname: $_G_line"
|
|
done
|
|
IFS=$save_IFS
|
|
}
|
|
|
|
|
|
# func_error ARG...
|
|
# -----------------
|
|
# Echo program name prefixed message to standard error.
|
|
func_error ()
|
|
{
|
|
$require_term_colors
|
|
|
|
_G_message=$*
|
|
_G_prefix="$progname: $tc_standout${tc_red}error$tc_reset: "
|
|
|
|
save_IFS=$IFS
|
|
IFS=$nl
|
|
for _G_line in $_G_message; do
|
|
IFS=$save_IFS
|
|
$bs_echo "$_G_prefix$tc_bold$_G_line$tc_reset" 1>&2
|
|
_G_prefix="$progname: "
|
|
done
|
|
IFS=$save_IFS
|
|
}
|
|
|
|
|
|
# func_fatal_error ARG...
|
|
# -----------------------
|
|
# Echo program name prefixed message to standard error, and exit.
|
|
func_fatal_error ()
|
|
{
|
|
func_error ${1+"$@"}
|
|
exit $EXIT_FAILURE
|
|
}
|
|
|
|
|
|
# func_fatal_help ARG...
|
|
# ----------------------
|
|
# Echo program name prefixed message to standard error, followed by
|
|
# a help hint, and exit.
|
|
func_fatal_help ()
|
|
{
|
|
$debug_cmd
|
|
|
|
eval $bs_echo \""Usage: $usage"\"
|
|
eval $bs_echo \""$fatal_help"\"
|
|
func_error ${1+"$@"}
|
|
exit $EXIT_FAILURE
|
|
}
|
|
|
|
|
|
# func_help
|
|
# ---------
|
|
# Echo long help message to standard output and exit.
|
|
func_help ()
|
|
{
|
|
$debug_cmd
|
|
|
|
func_usage_message
|
|
$bs_echo "$long_help_message"
|
|
exit 0
|
|
}
|
|
|
|
|
|
# func_missing_arg ARGNAME
|
|
# ------------------------
|
|
# Echo program name prefixed message to standard error and set global
|
|
# exit_cmd.
|
|
func_missing_arg ()
|
|
{
|
|
$debug_cmd
|
|
|
|
func_error "Missing argument for \`$1'."
|
|
exit_cmd=exit
|
|
}
|
|
|
|
|
|
# func_quote_for_eval ARG...
|
|
# --------------------------
|
|
# Aesthetically quote ARGs to be evaled later.
|
|
# This function returns two values: FN_QUOTE_FOR_EVAL_RESULT
|
|
# is double-quoted, suitable for a subsequent eval, whereas
|
|
# FN_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
|
|
# which are still active within double quotes backslashified.
|
|
func_quote_for_eval ()
|
|
{
|
|
$debug_cmd
|
|
|
|
_G_sed_quote_subst='s|\([`"$\\]\)|\\\1|g'
|
|
|
|
func_quote_for_eval_result=
|
|
while test $# -gt 0; do
|
|
case $1 in
|
|
*[\\\`\"\$]*)
|
|
_G_unquoted_arg=`printf '%s\n' "$1" |$SED "$_G_sed_quote_subst"` ;;
|
|
*)
|
|
_G_unquoted_arg=$1 ;;
|
|
esac
|
|
|
|
case $_G_unquoted_arg in
|
|
# Double-quote args containing shell metacharacters to delay
|
|
# word splitting, command substitution and variable expansion
|
|
# for a subsequent eval.
|
|
# Many Bourne shells cannot handle close brackets correctly
|
|
# in scan sets, so we specify it separately.
|
|
*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
|
|
_G_quoted_arg=\"$_G_unquoted_arg\"
|
|
;;
|
|
*)
|
|
_G_quoted_arg=$_G_unquoted_arg ;;
|
|
esac
|
|
test -n "$func_quote_for_eval_result" \
|
|
&& func_append func_quote_for_eval_result " "
|
|
func_append func_quote_for_eval_result "$_G_quoted_arg"
|
|
shift
|
|
done
|
|
}
|
|
|
|
|
|
# func_split_equals STRING
|
|
# ------------------------
|
|
# Set func_split_equals_lhs and func_split_equals_rhs shell variables after
|
|
# splitting STRING at the `=' sign.
|
|
if (eval 'x='--ab=cd'; y=${x#*=}; z=${x%%=*}; test x$y$z = xcd--ab') 2>/dev/null
|
|
then
|
|
# This is an XSI compatible shell, allowing a faster implementation...
|
|
eval 'func_split_equals ()
|
|
{
|
|
$debug_cmd
|
|
|
|
func_split_equals_lhs=${1%%=*}
|
|
func_split_equals_rhs=${1#*=}
|
|
test "x$func_split_equals_lhs" = "x$1" \
|
|
&& func_split_equals_rhs=
|
|
}'
|
|
else
|
|
# ...otherwise fall back to using expr, which is often a shell builtin.
|
|
func_split_equals ()
|
|
{
|
|
$debug_cmd
|
|
|
|
func_split_equals_lhs=`expr "x$1" : 'x\([^=]*)'`
|
|
func_split_equals_rhs=
|
|
test "x$func_split_equals_lhs" = "x$1" \
|
|
|| func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'`
|
|
}
|
|
fi #func_split_equals
|
|
|
|
|
|
# func_split_short_opt SHORTOPT
|
|
# -----------------------------
|
|
# Set func_split_short_opt_name and func_split_short_opt_arg shell
|
|
# variables after splitting SHORTOPT after the 2nd character.
|
|
if (eval 'x=-abc; y=${x#??}; z=${x%$y}; test x$y$z = xbc-a') 2>/dev/null
|
|
then
|
|
# This is an XSI compatible shell, allowing a faster implementation...
|
|
eval 'func_split_short_opt ()
|
|
{
|
|
$debug_cmd
|
|
|
|
func_split_short_opt_arg=${1#??}
|
|
func_split_short_opt_name=${1%"$func_split_short_opt_arg"}
|
|
}'
|
|
else
|
|
# ...otherwise fall back to using expr, which is often a shell builtin.
|
|
func_split_short_opt ()
|
|
{
|
|
$debug_cmd
|
|
|
|
func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'`
|
|
func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'`
|
|
}
|
|
fi #func_split_short_opt
|
|
|
|
|
|
# func_usage
|
|
# ----------
|
|
# Echo short help message to standard output and exit.
|
|
func_usage ()
|
|
{
|
|
$debug_cmd
|
|
|
|
func_usage_message
|
|
$bs_echo "Run \`$progname --help |${PAGER-more}' for full usage"
|
|
exit 0
|
|
}
|
|
|
|
|
|
# func_usage_message
|
|
# ------------------
|
|
# Echo short help message to standard output.
|
|
func_usage_message ()
|
|
{
|
|
$debug_cmd
|
|
|
|
eval $bs_echo \""$usage"\"
|
|
echo
|
|
$SED -n 's|^# ||;/^Written by/{x;p;x;};h' < "$progpath"
|
|
echo
|
|
eval $bs_echo \""$usage_message"\"
|
|
}
|
|
|
|
|
|
# func_verbose ARG...
|
|
# -------------------
|
|
# Echo program name prefixed message in verbose mode only.
|
|
func_verbose ()
|
|
{
|
|
$opt_verbose && func_echo ${1+"$@"}
|
|
}
|
|
|
|
|
|
# func_version
|
|
# ------------
|
|
# Echo version message to standard output and exit.
|
|
func_version ()
|
|
{
|
|
$debug_cmd
|
|
|
|
printf '%s\n' "$progname $scriptversion"
|
|
$SED -n '/(C)/!b go
|
|
:more
|
|
/\./!{
|
|
N
|
|
s|\n# | |
|
|
b more
|
|
}
|
|
:go
|
|
/^# Written by /,/# warranty; / {
|
|
s|^# ||
|
|
s|^# *$||
|
|
s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
|
|
p
|
|
}
|
|
/^# Written by / {
|
|
s|^# ||
|
|
p
|
|
}' < "$progpath"
|
|
|
|
exit $?
|
|
}
|
|
|
|
|
|
# Local variables:
|
|
# mode: shell-script
|
|
# sh-indentation: 2
|
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
|
# time-stamp-start: "scriptversion="
|
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
|
# time-stamp-time-zone: "UTC"
|
|
# time-stamp-end: "; # UTC"
|
|
# End:
|