a82ffe9d5826da5c4ca117a82c1e9c960c1f71d0
[platform/upstream/bash.git] / examples / functions / autoload.v3
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
20 unset _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
107 autoload()
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 }