diff options
author | jlam <jlam@pkgsrc.org> | 2004-09-06 18:33:23 +0000 |
---|---|---|
committer | jlam <jlam@pkgsrc.org> | 2004-09-06 18:33:23 +0000 |
commit | b9a3fde88cd8c6b27817525f5c4f4063fa4e5781 (patch) | |
tree | 252bf64c7a0e7bac1e8d0dd9ff67ef02495ba608 /mk | |
parent | cb9fae2201ba0a184d0f6d6837a9646333d07fea (diff) | |
download | pkgsrc-b9a3fde88cd8c6b27817525f5c4f4063fa4e5781.tar.gz |
Add a library of useful shell functions. There are functions for
logging, backslash quoting, and two queue implementations: one entirely
in memory and one using a file.
Diffstat (limited to 'mk')
-rw-r--r-- | mk/scripts/shell-lib | 329 |
1 files changed, 329 insertions, 0 deletions
diff --git a/mk/scripts/shell-lib b/mk/scripts/shell-lib new file mode 100644 index 00000000000..6a7f53aaef4 --- /dev/null +++ b/mk/scripts/shell-lib @@ -0,0 +1,329 @@ +# $NetBSD: shell-lib,v 1.1 2004/09/06 18:33:23 jlam Exp $ +# +# Copyright (c) 2004 The NetBSD Foundation, Inc. +# All rights reserved. +# +# This code is derived from software contributed to The NetBSD Foundation +# by Johnny C. Lam. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the NetBSD +# Foundation, Inc. and its contributors. +# 4. Neither the name of The NetBSD Foundation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +###################################################################### +# msg_log logfile msg +# Output msg to logfile. If logfile is "stdout" or "stderr" +# then output to there instead. +###################################################################### +msg_log() +{ + : ${echo=echo} + + _msg_log="$1"; shift + case $_msg_log in + stdout) $echo "$@" ;; + stderr) $echo "$@" 1>&2 ;; + *) $echo "$@" >> $_msg_log ;; + esac +} + +###################################################################### +# die msg +# Output $msg to stderr, and exit with a positive error code. +###################################################################### +die() +{ + msg_log stderr "$@" + exit 1 +} + +###################################################################### +# check_prog var prog ... +# If $var is empty or unset, then set it to the path of one of +# the program names in the list. +###################################################################### +check_prog() +{ + : ${test=test} + + _ckp_var="$1"; shift + + eval _ckp_tmp=\"\$$_ckp_var\" + if $test "x$_ckp_tmp" != "x"; then + return 0 + fi + + for _ckp_prog do + _ckp_IFS="${IFS}"; IFS=":" + for _ckp_dir in ${PATH}; do + if $test -x "$_ckp_dir/$_ckp_prog"; then + eval $_ckp_var=\""$_ckp_dir/$_ckp_prog"\" + return 1 + fi + done + IFS="${_ckp_IFS}" + done + + die "$_ckp_var could not be set." +} + +###################################################################### +# shquote arg +# Returns a backslashed and quoted version of arg in $shquoted. +###################################################################### +shquote() +{ + : ${echo=echo} + : ${sed=sed} + + _shq_arg=$1 + _shq_sed="$sed -e 1s/^X//" + _shq_sed_quote_subst='s/\([\`\"$\\]\)/\\\1/g' + case $_shq_arg in + *[\`\"\$\\]*) + shquoted=`$echo "X$_shq_arg" | $_shq_sed -e "$_shq_sed_quote_subst"` + ;; + *) + shquoted="$_shq_arg" + ;; + esac + case $shquoted in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + shquoted="\"$shquoted\"" + ;; + esac +} + +###################################################################### +###################################################################### +### +### Queue routines. The queue is implemented as a set of variables +### that is unique to each queue name, thus the use of multiple queues +### is allowed. +### +###################################################################### +###################################################################### + +###################################################################### +# init_queue name +# Initialize the named queue. +###################################################################### +init_queue() +{ + _qname="$1" + eval "_q${_qname}head=1111111111" + eval "_q${_qname}tail=1111111111" +} + +###################################################################### +# append_queue name item ... +# Append items onto the end of the named queue in FIFO order. +###################################################################### +append_queue() +{ + : ${test=test} + + _qname="$1"; shift + while $test $# -gt 0; do + eval "_qtail=\"\$_q${_qname}tail\"" + eval "_q${_qname}${_qtail}=\"\${1}\"" + case $_qtail in + *000000000) _qtail=${_qtail%000000000}1 ;; + *) _qtail=${_qtail}0 ;; + esac + eval "_q${_qname}tail=\"\${_qtail}\"" + shift + done +} + +###################################################################### +# prepend_queue name item ... +# Prepend items to the head of the named queue in LIFO order. +###################################################################### +prepend_queue() +{ + : ${test=test} + + _qname="$1"; shift + while $test $# -gt 0; do + eval "_qhead=\"\$_q${_qname}head\"" + case $_qhead in + *1) _qhead=${_qhead%1}000000000 ;; + *) _qhead=${_qhead%0} ;; + esac + eval "_q${_qname}${_qhead}=\"\${1}\"" + eval "_q${_qname}head=\"\${_qhead}\"" + shift + done +} + +###################################################################### +# head_queue name var +# Return the head of the named queue in $var. +###################################################################### +head_queue() +{ + _qname="$1"; shift + eval "_qhead=\"\$_q${_qname}head\"" + eval "${1}=\"\$_q${_qname}${_qhead}\"" +} + +###################################################################### +# pop_queue name var +# Pop off the head of the named queue and return it in $var. +###################################################################### +pop_queue() +{ + _qname="$1"; shift + head_queue $_qname $1 + case $_qhead in + *000000000) _qhead=${_qhead%000000000}1 ;; + *) _qhead=${_qhead}0 ;; + esac + eval "_q${_qname}head=\"\${_qhead}\"" +} + +###################################################################### +# queue_is_empty name +# Return 0 if the named queue is empty and 1 otherwise. +###################################################################### +queue_is_empty() +{ + : ${test=test} + + _qname="$1" + eval "_qhead=\"\$_q${_qname}head\"" + eval "_qtail=\"\$_q${_qname}tail\"" + $test "$_qhead" = "$_qtail" + return $? +} + +###################################################################### +###################################################################### +### +### File queue routines. The file queue is implemented as a file +### whose lines represent the queue elements. The file queue name +### is simply the file used for the queue, thus the use of multiple +### queues is allowed. +### +###################################################################### +###################################################################### + +###################################################################### +# init_fqueue name +# Initialize the named file queue. +###################################################################### +init_fqueue() +{ + _fqname="$1" + : > "$_fqname" +} + +###################################################################### +# append_fqueue name item ... +# Append items onto the end of the named file queue in FIFO order. +###################################################################### +append_fqueue() +{ + : ${echo=echo} + : ${test=test} + + _fqname="$1"; shift + while $test $# -gt 0; do + $echo "$1" >> "$_fqname" + shift + done +} + +###################################################################### +# prepend_fqueue name item ... +# Prepend items to the head of the named file queue in LIFO order. +###################################################################### +prepend_fqueue() +{ + : ${cat=cat} + : ${echo=echo} + : ${mv=mv} + + _fqname="$1"; shift + _fqtmpfile="$_fqname.$$" + init_queue _fqtmpqueue + prepend_queue _fqtmpqueue "$@" + while ! queue_is_empty _fqtmpqueue; do + pop_queue _fqtmpqueue _fqelt + $echo "$_fqelt" >> "$_fqtmpfile" + done + $cat "$_fqname" >> "$_fqtmpfile" + $mv -f "$_fqtmpfile" "$_fqname" +} + +###################################################################### +# head_fqueue name var +# Return the head of the named file queue in $var. +###################################################################### +head_fqueue() +{ + : ${head=head} + + _fqname="$1"; shift + _tmp=`$head -n 1 "$_fqname"` + eval "${1}=\"\$_tmp\"" +} + +###################################################################### +# pop_fqueue name var +# Pop off the head of the named file queue and return it in $var. +###################################################################### +pop_fqueue() +{ + : ${mv=mv} + : ${sed=sed} + + _fqname="$1"; shift + _fqtmpfile="$_fqname.$$" + head_fqueue "$_fqname" $1 + $sed "1,1d" "$_fqname" >> "$_fqtmpfile" + $mv -f "$_fqtmpfile" "$_fqname" +} + +###################################################################### +# fqueue_is_empty name +# Return 0 if the named file queue is empty and >0 otherwise. +###################################################################### +fqueue_is_empty() +{ + : ${test=test} + : ${wc=wc} + + _fqname="$1" + if $test -f "$_fqname"; then + _fqlines=`$wc -l < "$_fqname"` + return $_fqlines + else + return 1 + fi +} |