xref: /freebsd/contrib/bmake/mk/setopts.sh (revision 6a7405f5a6b639682cacf01e35d561411ff556aa)
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