mirror of
git://git.savannah.gnu.org/libtool.git
synced 2024-11-21 01:40:57 +08:00
bootstrap: split into reusable parts.
* bootstrap: Bourne shell has no scoping, so be extremely careful with namespaces, functions in `^func_' and `^require_'; private variables in `^_G_', and public variables all well documented by comments. * libltdl/config/extract-trace: New file, containing the minimum of code previously in bootstrap plus a little glue to make the GNU M4 based autotools tracing function (as opposed to the kludgy sed extraction currently used everywhere else) a standalone script that can be executed or sourced. * libltdl/config/options-parser: New file, containing the pluggable options parser code shared between the other two. * bootstrap.conf: Adjust. * Makefile.am (EXTRA_DIST): Be sure to distribute the new extract-trace and options-parser scripts. (install-data-local): And install them where libtoolize can find them. Signed-off-by: Gary V. Vaughan <gary@gnu.org>
This commit is contained in:
parent
0569ec6cd2
commit
d5393524f6
10
Makefile.am
10
Makefile.am
@ -92,14 +92,17 @@ CLEANFILES += libtool libtoolize
|
||||
## and dependencies with `$(srcdir)' consistently.
|
||||
configure_ac = $(srcdir)/configure.ac
|
||||
config_status = $(top_builddir)/config.status
|
||||
extract_trace = $(srcdir)/$(aux_dir)/extract-trace
|
||||
libtoolize_in = $(srcdir)/libtoolize.in
|
||||
ltmain_sh = $(srcdir)/$(aux_dir)/ltmain.sh
|
||||
libtool_m4 = $(srcdir)/$(macro_dir)/libtool.m4
|
||||
ltversion_in = $(srcdir)/$(macro_dir)/ltversion.in
|
||||
ltversion_m4 = $(srcdir)/$(macro_dir)/ltversion.m4
|
||||
options_parser = $(srcdir)/$(aux_dir)/options-parser
|
||||
|
||||
EXTRA_DIST += $(libtoolize_in) $(libtoolize_m4sh) $(ltmain_m4sh) \
|
||||
$(ltmain_sh) $(ltversion_in) $(ltversion_m4)
|
||||
EXTRA_DIST += $(extract_trace) $(libtoolize_in) $(libtoolize_m4sh) \
|
||||
$(ltmain_m4sh) $(ltmain_sh) $(ltversion_in) \
|
||||
$(ltversion_m4) $(options_parser)
|
||||
|
||||
## These are the replacements that need to be made at bootstrap time,
|
||||
## because they must be static in distributed files, and not accidentally
|
||||
@ -479,7 +482,8 @@ install-data-local: $(lt_Makefile_in)
|
||||
$(INSTALL_DATA) "$(srcdir)/$(macro_dir)/$$f" "$(DESTDIR)$(aclocaldir)/$$f"; \
|
||||
done
|
||||
## install the helper scripts
|
||||
@list='$(pkgaux_scripts)' && for p in $$list; do \
|
||||
@list='config/extract-trace config/options-parser $(pkgaux_scripts)' && \
|
||||
for p in $$list; do \
|
||||
d=`echo "$(DESTDIR)$(pkgdatadir)/$$p" |$(SED) 's,[^/]*$$,,'`; \
|
||||
test -d "$$d" || $(mkinstalldirs) "$$d"; \
|
||||
echo " $(INSTALL_SCRIPT) '$(srcdir)/$(ltdl_dir)/$$p' '$(DESTDIR)$(pkgdatadir)/$$p'"; \
|
||||
|
@ -1,4 +1,4 @@
|
||||
# bootstrap.conf (GNU Libtool) version 2011-10-20
|
||||
# bootstrap.conf (GNU Libtool) version 2011-11-02
|
||||
#
|
||||
# Copyright (C) 2010, 2011 Free Software Foundation, Inc.
|
||||
# Written by Gary V. Vaughan, 2010
|
||||
@ -108,7 +108,7 @@ require_bootstrap_uptodate=:
|
||||
## ------------------- ##
|
||||
|
||||
# func_reconfigure
|
||||
# ----------------
|
||||
# ------------------
|
||||
# In addition to needing to autoreconf several directories, Libtool
|
||||
# provides `libtoolize' and doesn't use `autopoint', so we can use a
|
||||
# somewhat simpler `func_reconfigure' implementation.
|
||||
|
407
libltdl/config/extract-trace
Executable file
407
libltdl/config/extract-trace
Executable file
@ -0,0 +1,407 @@
|
||||
#! /bin/sh
|
||||
|
||||
# Make sure we've evaluated the option-parser library.
|
||||
test -n "$progpath" || . `echo "$0" |${SED-sed} 's,[^/]*$,,'`"/options-parser"
|
||||
|
||||
# Set a version string.
|
||||
scriptversion=2011-11-04.09; # UTC
|
||||
|
||||
# Extract macro arguments from autotools input with GNU M4.
|
||||
# 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.
|
||||
#
|
||||
##### PLEASE CHECK `--version' WORKS AFTER EDITING THE ABOVE COPYRIGHT #####
|
||||
|
||||
# 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/>.
|
||||
|
||||
|
||||
## ------ ##
|
||||
## Usage. ##
|
||||
## ------ ##
|
||||
|
||||
# Run `./extract-trace --help' for help with using this script from the
|
||||
# command line.
|
||||
#
|
||||
# Or source first `options-parser' and then this file into your own
|
||||
# scripts in order to make use of the function and variable framework
|
||||
# they define, and also to avoid the overhead of forking to run this
|
||||
# script in its own process on every call.
|
||||
|
||||
|
||||
## -------------- ##
|
||||
## Configuration. ##
|
||||
## -------------- ##
|
||||
|
||||
usage='$progname MACRO_NAME FILE [...]'
|
||||
|
||||
long_help_message='
|
||||
The first argument to this program is the name of an autotools macro
|
||||
whose arguments you want to extract by examining the files listed in the
|
||||
remaining arguments using the same tool that Autoconf and Automake use,
|
||||
GNU M4.
|
||||
|
||||
The arguments are returned separated by colons, with each traced call
|
||||
on a separate line.'
|
||||
|
||||
|
||||
|
||||
## ------------------##
|
||||
## Helper functions. ##
|
||||
## ------------------##
|
||||
|
||||
# This section contains the helper functions used by the rest of
|
||||
# `extract-trace'.
|
||||
|
||||
|
||||
# func_autoconf_configure MAYBE-CONFIGURE-FILE
|
||||
# --------------------------------------------
|
||||
# Ensure that MAYBE-CONFIGURE-FILE is the name of a file in the current
|
||||
# directory which contains an uncommented call to AC_INIT.
|
||||
func_autoconf_configure ()
|
||||
{
|
||||
$debug_cmd
|
||||
|
||||
_G_sed_no_comment='s,#.*$,,; s,^dnl .*$,,; s, dnl .*$,,;'
|
||||
_G_ac_init=
|
||||
|
||||
# If we were passed a genuine file, make sure it calls AC_INIT.
|
||||
test -f "$1" \
|
||||
&& _G_ac_init=`$SED "$_G_sed_no_comment" "$1" |grep AC_INIT`
|
||||
|
||||
# Otherwise it is not a genuine Autoconf input file.
|
||||
test -n "$_G_ac_init"
|
||||
_G_status=$?
|
||||
|
||||
test $_G_status -ne 0 \
|
||||
&& func_verbose "\`$1' not using Autoconf"
|
||||
|
||||
(exit $_G_status)
|
||||
}
|
||||
|
||||
|
||||
# func_find_tool ENVVAR NAMES...
|
||||
# ------------------------------
|
||||
# Search for a required program. Use the value of ENVVAR, if set,
|
||||
# otherwise find the first of the NAMES that can be run (i.e.,
|
||||
# supports --version). If found, set ENVVAR to the program name,
|
||||
# die otherwise.
|
||||
func_find_tool ()
|
||||
{
|
||||
$debug_cmd
|
||||
|
||||
_G_find_tool_envvar=$1
|
||||
shift
|
||||
_G_find_tool_names=$@
|
||||
eval "_G_find_tool_res=\$$_G_find_tool_envvar"
|
||||
if test -n "$_G_find_tool_res"; then
|
||||
_G_find_tool_error_prefix="\$$find_tool_envvar: "
|
||||
else
|
||||
for _G_prog
|
||||
do
|
||||
if func_tool_version_output $_G_prog >/dev/null; then
|
||||
_G_find_tool_res=$_G_prog
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if test -n "$_G_find_tool_res"; then
|
||||
func_tool_version_output >/dev/null $_G_find_tool_res "\
|
||||
${_G_find_tool_error_prefix}Cannot run \`$_G_find_tool_res --version'"
|
||||
|
||||
# Make sure the result is exported to the environment for children
|
||||
# to use.
|
||||
eval "$_G_find_tool_envvar=\$_G_find_tool_res"
|
||||
eval "export $_G_find_tool_envvar"
|
||||
else
|
||||
func_error "\
|
||||
One of these is required:
|
||||
$_G_find_tool_names"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# func_tool_version_output CMD [FATAL-ERROR-MSG]
|
||||
# ----------------------------------------------
|
||||
# Attempt to run `CMD --version', discarding errors. The output can be
|
||||
# ignored by redirecting stdout, and this function used simply to test
|
||||
# whether the command exists and exits normally when passed a
|
||||
# `--version' argument.
|
||||
# When FATAL-ERROR-MSG is given, then this function will display the
|
||||
# message and exit if running `CMD --version' returns a non-zero exit
|
||||
# status.
|
||||
func_tool_version_output ()
|
||||
{
|
||||
$debug_cmd
|
||||
|
||||
_G_cmd=$1
|
||||
_G_fatal_error_msg=$2
|
||||
|
||||
# Some tools, like `git2cl' produce thousands of lines of output
|
||||
# unless stdin is /dev/null - in that case we want to return
|
||||
# successfully without saving all of that output. Other tools,
|
||||
# such as `help2man' exit with a non-zero status when stdin comes
|
||||
# from /dev/null, so we re-execute without /dev/null if that
|
||||
# happens. This means that occasionally, the output from both calls
|
||||
# ends up in the result, but the alternative would be to discard the
|
||||
# output from one call, and hope the other produces something useful.
|
||||
{ $_G_cmd --version </dev/null || $_G_cmd --version; } 2>/dev/null
|
||||
_G_status=$?
|
||||
|
||||
test $_G_status -ne 0 && test -n "$_G_fatal_error_msg" \
|
||||
&& func_fatal_error "$_G_fatal_error_msg"
|
||||
|
||||
(exit $_G_status)
|
||||
}
|
||||
|
||||
|
||||
## -------------------- ##
|
||||
## 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. Where a variable already has a non-
|
||||
# empty value (as set by the package's `bootstrap.conf'), that value is
|
||||
# used in preference to deriving the default. 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_configure_ac
|
||||
# --------------------
|
||||
# Ensure that there is a `configure.ac' or `configure.in' file in the
|
||||
# current directory which contains an uncommented call to AC_INIT, and
|
||||
# that `$configure_ac' contains its name.
|
||||
require_configure_ac=func_require_configure_ac
|
||||
func_require_configure_ac ()
|
||||
{
|
||||
$debug_cmd
|
||||
|
||||
test -z "$configure_ac" \
|
||||
&& func_autoconf_configure configure.ac && configure_ac=configure.ac
|
||||
test -z "$configure_ac" \
|
||||
&& func_autoconf_configure configure.in && configure_ac=configure.in
|
||||
test -z "$configure_ac" \
|
||||
|| func_verbose "found \`$configure_ac'"
|
||||
|
||||
require_configure_ac=:
|
||||
}
|
||||
|
||||
|
||||
# require_gnu_m4
|
||||
# --------------
|
||||
# Search for GNU M4, and export it in $M4.
|
||||
require_gnu_m4=func_require_gnu_m4
|
||||
func_require_gnu_m4 ()
|
||||
{
|
||||
$debug_cmd
|
||||
|
||||
test -n "$M4" || {
|
||||
# Find the first m4 binary that responds to --version.
|
||||
func_find_tool M4 gm4 gnum4 m4
|
||||
}
|
||||
|
||||
test -n "$M4" || func_fatal_error "\
|
||||
Please install GNU M4, or \`export M4=/path/to/gnu/m4'."
|
||||
|
||||
func_verbose "export M4='$M4'"
|
||||
|
||||
# Make sure the search result is visible to subshells
|
||||
export M4
|
||||
|
||||
require_gnu_m4=:
|
||||
}
|
||||
|
||||
|
||||
## --------------- ##
|
||||
## Core functions. ##
|
||||
## --------------- ##
|
||||
|
||||
# This section contains the high level functions used when calling this
|
||||
# file as a script. `func_extract_trace' is probably the only one that you
|
||||
# won't want to replace if you source this file into your own script.
|
||||
|
||||
|
||||
# func_extract_trace MACRO_NAMES [FILENAME]...
|
||||
# --------------------------------------------
|
||||
# set `$func_extract_trace_result' to a colon delimited list of arguments
|
||||
# to any of the comma separated list of MACRO_NAMES in FILENAME. If no
|
||||
# FILENAME is given, then `$configure_ac' is assumed.
|
||||
func_extract_trace ()
|
||||
{
|
||||
$debug_cmd
|
||||
|
||||
$require_configure_ac
|
||||
$require_gnu_m4
|
||||
|
||||
_G_m4_traces=`echo "--trace=$1" |$SED 's%,% --trace=%g'`
|
||||
_G_re_macros=`echo "($1)" |$SED 's%,%|%g'`
|
||||
_G_macros="$1"; shift
|
||||
test $# -gt 0 || {
|
||||
set dummy $configure_ac
|
||||
shift
|
||||
}
|
||||
|
||||
# Generate an error if the first file is missing
|
||||
<"$1"
|
||||
|
||||
# Sadly, we can't use `autom4te' tracing to extract macro arguments,
|
||||
# because it complains about things we want to ignore at bootstrap
|
||||
# time - like missing m4_include files; AC_PREREQ being newer than
|
||||
# the installed autoconf; and returns nothing when tracing
|
||||
# `AM_INIT_AUTOMAKE' when aclocal hasn't been generated yet.
|
||||
#
|
||||
# The following tries to emulate a less persnickety version of (and
|
||||
# due to not having to wait for Perl startup on every invocation,
|
||||
# it's probably faster too):
|
||||
#
|
||||
# autom4te --language=Autoconf --trace=$my_macro:\$% "$@"
|
||||
#
|
||||
# First we give a minimal set of macro declarations to M4 to prime
|
||||
# it for reading Autoconf macros, while still providing some of the
|
||||
# functionality generally used at m4-time to supply dynamic
|
||||
# arguments to Autocof functions, but without following
|
||||
# `m4_s?include' files.
|
||||
_G_mini='
|
||||
# Initialisation.
|
||||
m4_changequote([,])
|
||||
m4_define([m4_copy], [m4_define([$2], m4_defn([$1]))])
|
||||
m4_define([m4_rename], [m4_copy([$1], [$2])m4_undefine([$1])])
|
||||
|
||||
# Disable these macros.
|
||||
m4_undefine([m4_dnl])
|
||||
m4_undefine([m4_include])
|
||||
m4_undefine([m4_m4exit])
|
||||
m4_undefine([m4_m4wrap])
|
||||
m4_undefine([m4_maketemp])
|
||||
|
||||
# Copy and rename macros not handled by "m4 --prefix".
|
||||
m4_define([dnl], [m4_builtin([dnl])])
|
||||
m4_copy([m4_define], [m4_defun])
|
||||
m4_rename([m4_ifelse], [m4_if])
|
||||
m4_ifdef([m4_mkstemp], [m4_undefine([m4_mkstemp])])
|
||||
m4_rename([m4_patsubst], [m4_bpatsubst])
|
||||
m4_rename([m4_regexp], [m4_bregexp])
|
||||
|
||||
# "m4sugar.mini" - useful m4-time macros for dynamic arguments.
|
||||
# If we discover packages that need more m4 macros defined in
|
||||
# order to bootstrap correctly, add them here:
|
||||
m4_define([m4_bmatch],
|
||||
[m4_if([$#], 0, [], [$#], 1, [], [$#], 2, [$2],
|
||||
[m4_if(m4_bregexp([$1], [$2]), -1,
|
||||
[$0([$1], m4_shift3($@))], [$3])])])
|
||||
m4_define([m4_ifndef], [m4_ifdef([$1], [$3], [$2])])
|
||||
m4_define([m4_ifset],
|
||||
[m4_ifdef([$1], [m4_ifval(m4_defn([$1]), [$2], [$3])], [$3])])
|
||||
m4_define([m4_require], [$1])
|
||||
m4_define([m4_shift3], [m4_shift(m4shift(m4shift($@)))])
|
||||
|
||||
# "autoconf.mini" - things from autoconf macros we care about.
|
||||
m4_copy([m4_defun], [AC_DEFUN])
|
||||
|
||||
# Dummy definitions for the macros we want to trace.
|
||||
# AM_INIT_AUTOMAKE at least produces no trace without this.
|
||||
'
|
||||
|
||||
_G_save=$IFS
|
||||
IFS=,
|
||||
for _G_macro in $_G_macros; do
|
||||
IFS=$_G_save
|
||||
func_append _G_mini "AC_DEFUN([$_G_macro])$nl"
|
||||
done
|
||||
IFS=$_G_save
|
||||
|
||||
# We discard M4's stdout, but the M4 trace output from reading our
|
||||
# "autoconf.mini" followed by any other files passed to this
|
||||
# function is then scanned by sed to transform it into a colon
|
||||
# delimited argument list assigned to a shell variable.
|
||||
_G_transform='s,#.*$,,; s,^dnl .*$,,; s, dnl .*$,,;'
|
||||
|
||||
# Unfortunately, alternation in regexp addresses doesn't work in at
|
||||
# least BSD (and hence Mac OS X) sed, so we have to append a capture
|
||||
# and print block for each traced macro to the sed transform script.
|
||||
_G_save=$IFS
|
||||
IFS=,
|
||||
for _G_macro in $_G_macros; do
|
||||
IFS=$_G_save
|
||||
func_append _G_transform '
|
||||
/^m4trace: -1- '"$_G_macro"'/ {
|
||||
s,^m4trace: -1- '"$_G_macro"'[([]*,,
|
||||
s|], [[]|:|g
|
||||
s|[])]*$|:|
|
||||
s|\(.\):$|\1|
|
||||
p
|
||||
}'
|
||||
done
|
||||
IFS=$_G_save
|
||||
|
||||
# Save the command pipeline results for further use by callers of
|
||||
# this function.
|
||||
func_extract_trace_result=`echo "$_G_mini" \
|
||||
|$M4 -daq --prefix $_G_m4_traces - "$@" 2>&1 1>/dev/null \
|
||||
|$SED -n -e "$_G_transform"`
|
||||
}
|
||||
|
||||
|
||||
# func_main [ARG]...
|
||||
# ------------------
|
||||
func_main ()
|
||||
{
|
||||
$debug_cmd
|
||||
|
||||
# Option processing.
|
||||
func_options "$@"
|
||||
eval set dummy "$func_options_result"; shift
|
||||
|
||||
# Validate remaining non-option arguments.
|
||||
test $# -gt 1 \
|
||||
|| func_fatal_help "not enough arguments"
|
||||
|
||||
# Pass non-option arguments to extraction function.
|
||||
func_extract_trace "$@"
|
||||
|
||||
# Display results.
|
||||
test -n "$func_extract_trace_result" \
|
||||
&& echo "$func_extract_trace_result"
|
||||
|
||||
# The End.
|
||||
exit $EXIT_SUCCESS
|
||||
}
|
||||
|
||||
|
||||
## --------------------------- ##
|
||||
## Actually perform the trace. ##
|
||||
## --------------------------- ##
|
||||
|
||||
# Only call `func_main' if this script was called directly.
|
||||
test extract-trace = "$progname" && func_main "$@"
|
||||
|
||||
# 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:
|
790
libltdl/config/options-parser
Normal file
790
libltdl/config/options-parser
Normal file
@ -0,0 +1,790 @@
|
||||
#! /bin/sh
|
||||
|
||||
# Set a version string for this script.
|
||||
scriptversion=2011-11-04.03; # 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="$SED -e "'s|/[^/]*$||'
|
||||
basename="$SED -e "'s|^.*/||'
|
||||
|
||||
nl='
|
||||
'
|
||||
|
||||
# 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=`echo "$progpath" |$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='`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 away the first argument (FUNC_NAME)
|
||||
shift
|
||||
func_quote_for_eval ${1+"$@"}
|
||||
func_run_hooks_result=$func_quote_for_eval_result
|
||||
|
||||
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 $func_run_hooks_result; shift
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
|
||||
## --------------- ##
|
||||
## 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 `func_run_hooks_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+"$@"}
|
||||
# func_run_hooks_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+"$@"}
|
||||
# func_run_hooks_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+"$@"}
|
||||
# func_run_hooks_result=$func_quote_for_eval_result
|
||||
# }
|
||||
#
|
||||
# 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 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
|
||||
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
|
||||
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 echo \""Usage: $usage"\"
|
||||
eval 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
|
||||
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
|
||||
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 echo \""$usage"\"
|
||||
echo
|
||||
$SED -n 's|^# ||;/^Written by/{x;p;x;};h' < "$progpath"
|
||||
echo
|
||||
eval 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:
|
Loading…
Reference in New Issue
Block a user