1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
# Common getopt function...
# This does not output anything -- it sets the variables in environment right
# away
# To parse options, source this file. It will parse any options specified in
# "$options" and in addition will handle -d/--dir and -A/--archive. The -d
# option is handled by changing to the directory right away, the -A option's
# value is simply stored in "$archive" variable.
# The options variable is a space-separated list of clauses like:
# <name>[|<alternate names...>][={f|s}]
#
# The name is name of the variable/function (and in the same time variable).
# foo
# If "--foo" is encountered, foo=yes is executed
# foo|f|bar
# If "--foo", "-f" or "--bar" is encountered, foo=--foo is executed,
# resp. foo=-f, foo==--bar.
# foo=s
# If "--foo" is encountered, foo is set to next argument (alternate names
# are possible too).
# foo=f
# If "--foo" is encountered, process_foo is called with the next argument.
# (of course, alternate names are possible too).
#
# "dir|d=f archive|A=s" should be specified to handle dir and archive options
# (all the rest is provided here).
#
# WARNING: Option names may only contain alphanumerics and underscore, NO '-' !!
# The file must be sourced directly in the appropriate context where options
# should be parsed (since functions have privat argument lists) and does the
# parsing whlie being sourced. So $options must be defined beforehand.
process_dir () {
cd "$1" || { echo "* Can't change to directory $1" >&2; exit 1; }
}
aba_describe_argument () {
local spec preeq posteq name variant
for spec in $options; do
preeq=${spec%%=*}
name=${spec%%[|=]*}
case $spec in
*=*) posteq="=${spec##*=}";;
*) posteq="";;
esac
while [ -n "$preeq" ]; do
variant=${preeq%%|*}
preeq=${preeq#$variant}
preeq=${preeq#|}
test "$1" = "--$variant" -o "$1" = "-$variant" && echo "$name$posteq"
done
done
}
archive=$(tla my-default-archive)
next=''
for arg; do
shift # Gradualy clean up old args
if [ -z "$options" ]; then
set -- "$@" "$arg"
elif [ -n "$next" ]; then
case $next in
*=f) eval "process_${next%=f} \"$arg\"";;
*=s) eval "${next%=s}=\"$arg\"";;
esac
next=''
else
case $arg in
--) options='';;
-[a-zA-Z]|--[^-]?*)
desc=$(aba_describe_argument $arg)
test -z "$desc" && { echo "* Unrecognized option: $arg" >&2; exit 1; }
case $desc in
*=[fs]) next=$desc;;
*) eval "$desc=yes";;
esac;;
*) set -- "$@" "$arg";;
esac
fi
done
# arch-tag: 85616ea1-0cd4-4f5d-be25-530325e9081d
# vim: set ft=sh:
|