~abentley/bzrtools/bzrtools.dev

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: