1*6a7405f5SSimon J. Gerraty: 2*6a7405f5SSimon J. Gerraty# NAME: 3*6a7405f5SSimon J. Gerraty# setopts.sh - set opt_* for shell scripts 4*6a7405f5SSimon J. Gerraty# 5*6a7405f5SSimon J. Gerraty# SYNOPSIS: 6*6a7405f5SSimon J. Gerraty# opt_str=s:a.b^cl,z= 7*6a7405f5SSimon J. Gerraty# opt_a=default 8*6a7405f5SSimon J. Gerraty# 9*6a7405f5SSimon J. Gerraty# . setopts.sh 10*6a7405f5SSimon J. Gerraty# 11*6a7405f5SSimon J. Gerraty# DESCRIPTION: 12*6a7405f5SSimon J. Gerraty# This module sets shell variables for each option specified in 13*6a7405f5SSimon J. Gerraty# "opt_str". 14*6a7405f5SSimon J. Gerraty# 15*6a7405f5SSimon J. Gerraty# If the option is followed by a ``:'' it requires an argument. 16*6a7405f5SSimon J. Gerraty# It defaults to an empty string and specifying that option on 17*6a7405f5SSimon J. Gerraty# the command line overrides the current value. 18*6a7405f5SSimon J. Gerraty# 19*6a7405f5SSimon J. Gerraty# If the option is followed by a ``.'' then it is treated as for 20*6a7405f5SSimon J. Gerraty# ``:'' except that any argument provided on the command line is 21*6a7405f5SSimon J. Gerraty# appended to the current value using the value of "opt_dot" as 22*6a7405f5SSimon J. Gerraty# separator (default is a space). 23*6a7405f5SSimon J. Gerraty# 24*6a7405f5SSimon J. Gerraty# If the option is followed by a ``,'' then it is treated as for 25*6a7405f5SSimon J. Gerraty# a ``.'' except that the separator is "opt_comma" (default ,). 26*6a7405f5SSimon J. Gerraty# 27*6a7405f5SSimon J. Gerraty# If the option is followed by ``='' it requires an argument 28*6a7405f5SSimon J. Gerraty# of the form "var=val" which will be evaluated. 29*6a7405f5SSimon J. Gerraty# 30*6a7405f5SSimon J. Gerraty# If the option is followed by a ``^'' then it is treated as a 31*6a7405f5SSimon J. Gerraty# boolean and defaults to 0. 32*6a7405f5SSimon J. Gerraty# 33*6a7405f5SSimon J. Gerraty# Options that have no qualifier are set to the flag if present 34*6a7405f5SSimon J. Gerraty# otherwise they are unset. That is if '-c' is given then 35*6a7405f5SSimon J. Gerraty# "opt_c" will be set to '-c'. 36*6a7405f5SSimon J. Gerraty# 37*6a7405f5SSimon J. Gerraty# If "opt_assign_eval" is set (and to something other than 38*6a7405f5SSimon J. Gerraty# 'no'), args of the form "var=val" will be evaluated. 39*6a7405f5SSimon J. Gerraty# 40*6a7405f5SSimon J. Gerraty# NOTES: 41*6a7405f5SSimon J. Gerraty# The implementation uses the getopts builtin if available. 42*6a7405f5SSimon J. Gerraty# 43*6a7405f5SSimon J. Gerraty# Also it does not work when loaded via a function call as "$@" 44*6a7405f5SSimon J. Gerraty# will be the args to that function. In such cases set 45*6a7405f5SSimon J. Gerraty# _SETOPTS_DELAY and call 'setopts "$@"; shift $__shift' 46*6a7405f5SSimon J. Gerraty# afterwards. 47*6a7405f5SSimon J. Gerraty# 48*6a7405f5SSimon J. Gerraty# AUTHOR: 49*6a7405f5SSimon J. Gerraty# Simon J. Gerraty <sjg@crufty.net> 50*6a7405f5SSimon J. Gerraty# 51*6a7405f5SSimon J. Gerraty 52*6a7405f5SSimon J. Gerraty# RCSid: 53*6a7405f5SSimon J. Gerraty# $Id: setopts.sh,v 1.13 2023/02/20 19:30:06 sjg Exp $ 54*6a7405f5SSimon J. Gerraty# 55*6a7405f5SSimon J. Gerraty# @(#) Copyright (c) 1995-2023 Simon J. Gerraty 56*6a7405f5SSimon J. Gerraty# 57*6a7405f5SSimon J. Gerraty# This file is provided in the hope that it will 58*6a7405f5SSimon J. Gerraty# be of use. There is absolutely NO WARRANTY. 59*6a7405f5SSimon J. Gerraty# Permission to copy, redistribute or otherwise 60*6a7405f5SSimon J. Gerraty# use this file is hereby granted provided that 61*6a7405f5SSimon J. Gerraty# the above copyright notice and this notice are 62*6a7405f5SSimon J. Gerraty# left intact. 63*6a7405f5SSimon J. Gerraty# 64*6a7405f5SSimon J. Gerraty# Please send copies of changes and bug-fixes to: 65*6a7405f5SSimon J. Gerraty# sjg@crufty.net 66*6a7405f5SSimon J. Gerraty# 67*6a7405f5SSimon J. Gerraty 68*6a7405f5SSimon J. Gerraty# the case checks just skip the sed(1) commands unless needed 69*6a7405f5SSimon J. Gerratycase "$opt_str" in 70*6a7405f5SSimon J. Gerraty*\^*) # the only ones we need to set are the booleans x, 71*6a7405f5SSimon J. Gerraty eval `echo $opt_str | sed -e 's/[^^]*$//' -e 's/[^^]*\([^^]^\)/\1/g' -e 's/\(.\)^/opt_\1=${opt_\1-0}; /g'` 72*6a7405f5SSimon J. Gerraty ;; 73*6a7405f5SSimon J. Gerratyesac 74*6a7405f5SSimon J. Gerratycase "$opt_str" in 75*6a7405f5SSimon J. Gerraty*[=,.\^]*) 76*6a7405f5SSimon J. Gerraty _opt_str=`echo $opt_str | sed -e 's/[=,.]/:/g' -e 's/\^//g'`;; 77*6a7405f5SSimon J. Gerraty*) _opt_str=$opt_str;; 78*6a7405f5SSimon J. Gerratyesac 79*6a7405f5SSimon J. Gerraty 80*6a7405f5SSimon J. Gerratyopt_append=${opt_append:-" "} 81*6a7405f5SSimon J. Gerratyopt_dot=${opt_dot:-$opt_append} 82*6a7405f5SSimon J. Gerratyopt_comma=${opt_comma:-,} 83*6a7405f5SSimon J. Gerraty 84*6a7405f5SSimon J. Gerratyset1opt() { 85*6a7405f5SSimon J. Gerraty o=$1 86*6a7405f5SSimon J. Gerraty a="$2" 87*6a7405f5SSimon J. Gerraty 88*6a7405f5SSimon J. Gerraty case "$opt_str" in 89*6a7405f5SSimon J. Gerraty *${o}:*) eval "opt_$o=\"$a\"";; 90*6a7405f5SSimon J. Gerraty *${o}.*) eval "opt_$o=\"\${opt_$o}\${opt_$o:+$opt_dot}$a\"";; 91*6a7405f5SSimon J. Gerraty *${o},*) eval "opt_$o=\"\${opt_$o}\${opt_$o:+$opt_comma}$a\"";; 92*6a7405f5SSimon J. Gerraty *${o}=*) 93*6a7405f5SSimon J. Gerraty case "$a" in 94*6a7405f5SSimon J. Gerraty *=*) eval "$a";; 95*6a7405f5SSimon J. Gerraty *) Myname=${Myname:-`basename $0 .sh`} 96*6a7405f5SSimon J. Gerraty echo "$Myname: -$o requires argument of form var=val" >&2 97*6a7405f5SSimon J. Gerraty exit 1 98*6a7405f5SSimon J. Gerraty ;; 99*6a7405f5SSimon J. Gerraty esac 100*6a7405f5SSimon J. Gerraty ;; 101*6a7405f5SSimon J. Gerraty *${o}\^*) eval opt_$o=1;; 102*6a7405f5SSimon J. Gerraty *) eval opt_$o=-$o;; 103*6a7405f5SSimon J. Gerraty esac 104*6a7405f5SSimon J. Gerraty} 105*6a7405f5SSimon J. Gerraty 106*6a7405f5SSimon J. Gerratysetopts() { 107*6a7405f5SSimon J. Gerraty __shift=$# 108*6a7405f5SSimon J. Gerraty # use getopts builtin if we can 109*6a7405f5SSimon J. Gerraty case `type getopts 2>&1` in 110*6a7405f5SSimon J. Gerraty *builtin*) 111*6a7405f5SSimon J. Gerraty : OPTIND=$OPTIND @="$@" 112*6a7405f5SSimon J. Gerraty while getopts $_opt_str o 113*6a7405f5SSimon J. Gerraty do 114*6a7405f5SSimon J. Gerraty case "$o" in 115*6a7405f5SSimon J. Gerraty \?) exit 1;; 116*6a7405f5SSimon J. Gerraty esac 117*6a7405f5SSimon J. Gerraty set1opt $o "$OPTARG" 118*6a7405f5SSimon J. Gerraty done 119*6a7405f5SSimon J. Gerraty shift $(($OPTIND - 1)) 120*6a7405f5SSimon J. Gerraty while : 121*6a7405f5SSimon J. Gerraty do 122*6a7405f5SSimon J. Gerraty case "$1" in 123*6a7405f5SSimon J. Gerraty *=*) 124*6a7405f5SSimon J. Gerraty case "$opt_assign_eval" in 125*6a7405f5SSimon J. Gerraty ""|no) break;; 126*6a7405f5SSimon J. Gerraty *) eval "$1"; shift;; 127*6a7405f5SSimon J. Gerraty esac 128*6a7405f5SSimon J. Gerraty ;; 129*6a7405f5SSimon J. Gerraty *) break;; 130*6a7405f5SSimon J. Gerraty esac 131*6a7405f5SSimon J. Gerraty done 132*6a7405f5SSimon J. Gerraty ;; 133*6a7405f5SSimon J. Gerraty *) # likely not a POSIX shell either 134*6a7405f5SSimon J. Gerraty # getopt(1) isn't as good 135*6a7405f5SSimon J. Gerraty set -- `getopt $_opt_str "$@" 2>&1` 136*6a7405f5SSimon J. Gerraty case "$1" in 137*6a7405f5SSimon J. Gerraty getopt:) 138*6a7405f5SSimon J. Gerraty Myname=${Myname:-`basename $0 .sh`} 139*6a7405f5SSimon J. Gerraty echo "$*" | tr ':' '\012' | sed -e '/^getopt/d' -e 's/ getopt$//' -e "s/^/$Myname:/" -e 's/ --/:/' -e 's/-.*//' 2>&2 140*6a7405f5SSimon J. Gerraty exit 1 141*6a7405f5SSimon J. Gerraty ;; 142*6a7405f5SSimon J. Gerraty esac 143*6a7405f5SSimon J. Gerraty 144*6a7405f5SSimon J. Gerraty while : 145*6a7405f5SSimon J. Gerraty do 146*6a7405f5SSimon J. Gerraty : 1="$1" 147*6a7405f5SSimon J. Gerraty case "$1" in 148*6a7405f5SSimon J. Gerraty --) shift; break;; 149*6a7405f5SSimon J. Gerraty -*) 150*6a7405f5SSimon J. Gerraty # Most shells give you ' ' in IFS whether you 151*6a7405f5SSimon J. Gerraty # want it or not, but at least one, doesn't. 152*6a7405f5SSimon J. Gerraty # So the following gives us consistency. 153*6a7405f5SSimon J. Gerraty o=`IFS=" -"; set -- $1; echo $*` # lose the '-' 154*6a7405f5SSimon J. Gerraty set1opt $o "$2" 155*6a7405f5SSimon J. Gerraty case "$_opt_str" in 156*6a7405f5SSimon J. Gerraty *${o}:*) shift;; 157*6a7405f5SSimon J. Gerraty esac 158*6a7405f5SSimon J. Gerraty ;; 159*6a7405f5SSimon J. Gerraty *=*) case "$opt_assign_eval" in 160*6a7405f5SSimon J. Gerraty ""|no) break;; 161*6a7405f5SSimon J. Gerraty *) eval "$1";; 162*6a7405f5SSimon J. Gerraty esac 163*6a7405f5SSimon J. Gerraty ;; 164*6a7405f5SSimon J. Gerraty *) break;; 165*6a7405f5SSimon J. Gerraty esac 166*6a7405f5SSimon J. Gerraty shift 167*6a7405f5SSimon J. Gerraty done 168*6a7405f5SSimon J. Gerraty ;; 169*6a7405f5SSimon J. Gerraty esac 170*6a7405f5SSimon J. Gerraty # let caller know how many args we consumed 171*6a7405f5SSimon J. Gerraty __shift=`expr $__shift - $#` 172*6a7405f5SSimon J. Gerraty} 173*6a7405f5SSimon J. Gerraty 174*6a7405f5SSimon J. Gerraty${_SETOPTS_DELAY:+:} setopts "$@" 175*6a7405f5SSimon J. Gerraty${_SETOPTS_DELAY:+:} shift $__shift 176