1#From: Mark Kennedy <mtk@ny.ubs.com>
2#Message-ID: <35E2B899.63A02DF5@ny.ubs.com>
3#Date: Tue, 25 Aug 1998 09:14:01 -0400
4#To: chet@nike.ins.cwru.edu
5#Subject: a newer version of the ksh-style 'autoload'
6
7#enclosed you'll find 'autoload.v3',  a version of the autoloader
8#that emulates the ksh semantics of delaying the resolution (and loading) of the function
9#until its first use.  i took the liberty of simplifying the code a bit although it still uses the
10#same functional breakdown.  i recently went through the exercise of converting
11#my ksh-based environment to bash (a very, very pleasant experience)
12#and this popped out.
13
14# the psuedo-ksh autoloader.
15
16# The first cut of this was by Bill Trost, trost@reed.bitnet.
17# The second cut came from Chet Ramey, chet@ins.CWRU.Edu
18# The third cut came from Mark Kennedy, mtk@ny.ubs.com.  1998/08/25
19
20unset _AUTOLOADS
21
22_aload()
23{
24    local func
25    for func; do
26	eval $func '()
27		{
28		    local f=$(_autoload_resolve '$func')
29		    if [[ $f ]]; then
30			. $f
31			'$func' "$@"
32			return $?
33		    else
34			return 1
35		    fi
36		}'
37	_autoload_addlist $func
38    done
39}
40
41_autoload_addlist()
42{
43	local func
44
45	for func in ${_AUTOLOADS[@]}; do
46	    [[ $func = "$1" ]] && return
47	done
48
49	_AUTOLOADS[${#_AUTOLOADS[@]}]=$1
50}
51
52_autoload_dump()
53{
54    local func
55
56    for func in ${_AUTOLOADS[@]}; do
57	[[ $1 ]] && echo -n "autoload "
58	echo $func
59    done
60}
61
62_autoload_remove_one()
63{
64    local func
65    local -a NEW_AUTOLOADS
66
67    for func in ${_AUTOLOADS[@]}; do
68	[[ $func != "$1" ]] && NEW_AUTOLOADS[${#NEW_AUTOLOADS[@]}]=$func
69    done
70
71    _AUTOLOADS=( ${NEW_AUTOLOADS[@]} )
72}
73
74_autoload_remove()
75{
76    local victim func
77
78    for victim; do
79	for func in ${_AUTOLOADS[@]}; do
80	    [[ $victim = "$func" ]] && unset -f $func && continue 2
81	done
82	echo "autoload: $func: not an autoloaded function" >&2
83    done
84
85    for func; do
86	    _autoload_remove_one $func
87    done
88}
89
90_autoload_resolve()
91{
92    if [[ ! "$FPATH" ]]; then
93	    echo "autoload: FPATH not set or null" >&2
94	    return
95    fi
96
97    local p
98
99    for p in $( (IFS=':'; set -- ${FPATH}; echo "$@") ); do
100	p=${p:-.}
101	if [ -f $p/$1 ]; then echo $p/$1; return; fi
102    done
103
104    echo "autoload: $1: function source file not found" >&2
105}
106
107autoload()
108{
109    if (( $# == 0 )) ; then _autoload_dump; return; fi
110
111    local opt OPTIND
112
113    while getopts pu opt
114    do
115	case $opt in
116	    p) _autoload_dump printable; return;;
117	    u) shift $((OPTIND-1)); _autoload_remove "$@"; return;; 
118	    *) echo "autoload: usage: autoload [-pu] [function ...]" >&2; return;;
119	esac
120    done
121
122    shift $(($OPTIND-1))
123
124    _aload "$@"
125}
126