]> git.ipfire.org Git - thirdparty/bash.git/blame - examples/functions/autoload.v2
Imported from ../bash-2.05a.tar.gz.
[thirdparty/bash.git] / examples / functions / autoload.v2
CommitLineData
ccc6cda3
JA
1#
2# An almost ksh-compatible `autoload'. A function declared as `autoload' will
3# be read in from a file the same name as the function found by searching the
4# $FPATH (which works the same as $PATH), then that definition will be run.
5#
6# To do this without source support, we define a dummy function that, when
7# executed, will load the file (thereby re-defining the function), then
8# execute that newly-redefined function with the original arguments.
9#
10# It's not identical to ksh because ksh apparently does lazy evaluation
11# and looks for the file to load from only when the function is referenced.
12# This one requires that the file exist when the function is declared as
13# `autoload'.
14#
15# usage: autoload [-pu] [func ...]
16#
17# options:
18# -p print in a format that can be reused as input
19# -u unset each function and remove it from the autoload list
20#
f73dda09 21# The first cut of this was by Bill Trost, trost@reed.edu
ccc6cda3
JA
22#
23# Chet Ramey
24# chet@ins.CWRU.Edu
25
26unset _AUTOLOADS
27_aindex=0
28
29#
30# Declare a function ($1) to be autoloaded from a file ($2) when it is first
31# called. This defines a `temporary' function that will `.' the file
32# containg the real function definition, then execute that new definition with
33# the arguments given to this `fake' function. The autoload function defined
34# by the file and the file itself *must* be named identically.
35#
36
37_aload()
38{
39 eval $1 '() { . '$2' ; '$1' "$@" ; return $? ; }'
40 _autoload_addlist "$1"
41}
42
43_autoload_addlist()
44{
45 local i=0
46
47 while (( i < $_aindex )); do
48 case "${_AUTOLOADS[i]}" in
49 "$1") return 1 ;;
50 esac
51 (( i += 1 ))
52 done
53 _AUTOLOADS[_aindex]="$1"
54 (( _aindex += 1 ))
55 return 0
56}
57
58_autoload_dump()
59{
60 local func
61
62 for func in ${_AUTOLOADS[@]}; do
63 [ -n "$1" ] && echo -n "autoload "
64 echo "$func"
65 done
66}
67
68# Remove $1 from the list of autoloaded functions
69_autoload_remove_one()
70{
71 local i=0 nnl=0
72 local -a nlist
73
74 while (( i < _aindex )); do
75 case "${_AUTOLOADS[i]}" in
76 "$1") ;;
77 *) nlist[nnl]="${_AUTOLOADS[i]}" ; (( nnl += 1 ));;
78 esac
79 (( i += 1 ))
80 done
81 unset _AUTOLOADS _aindex
82 eval _AUTOLOADS=( ${nlist[@]} )
83 _aindex=$nnl
84}
85
86# Remove all function arguments from the list of autoloaded functions
87_autoload_remove()
88{
89 local func i es=0
90
91 # first unset the autoloaded functions
92 for func; do
93 i=0
94 while (( i < _aindex )); do
95 case "${_AUTOLOADS[i]}" in
96 "$func") unset -f $func ; break ;;
97 esac
98 (( i += 1 ))
99 done
100 if (( i == _aindex )); then
101 echo "autoload: $func: not an autoloaded function" >&2
102 es=1
103 fi
104 done
105
106 # then rebuild the list of autoloaded functions
107 for func ; do
108 _autoload_remove_one "$func"
109 done
110
111 return $es
112}
113
114#
115# Search $FPATH for a file the same name as the function given as $1, and
116# autoload the function from that file. There is no default $FPATH.
117#
118
119autoload()
120{
121 local -a fp
122 local _autoload_unset nfp i
123
124 if (( $# == 0 )) ; then
125 _autoload_dump
126 return 0
127 fi
128
129 OPTIND=1
130 while getopts pu opt
131 do
132 case "$opt" in
133 p) _autoload_dump printable; return 0;;
134 u) _autoload_unset=y ;;
135 *) echo "autoload: usage: autoload [-pu] [function ...]" >&2
136 return 1 ;;
137 esac
138 done
139
140 shift $(( $OPTIND - 1 ))
141
142 if [ -n "$_autoload_unset" ]; then
143 _autoload_remove "$@"
144 return $?
145 fi
146
147 #
148 # If there is no $FPATH, there is no work to be done
149 #
150
151 if [ -z "$FPATH" ] ; then
152 echo "autoload: FPATH not set or null" >&2
153 return 1
154 fi
155
156 #
157 # This treats FPATH exactly like PATH: a null field anywhere in the
158 # FPATH is treated the same as the current directory.
159 #
160 # This turns $FPATH into an array, substituting `.' for `'
161 #
162 eval fp=( $(
163 IFS=':'
164 set -- ${FPATH}
165 for p in "$@" ; do echo -n "${p:-.} "; done
166 )
167 )
168
169 nfp=${#fp[@]}
170
171 for FUNC ; do
172 i=0;
173 while (( i < nfp )) ; do
174 if [ -f ${fp[i]}/$FUNC ] ; then
175 break # found it!
176 fi
177 (( i += 1 ))
178 done
179
180 if (( i == nfp )) ; then
181 echo "autoload: $FUNC: autoload function not found" >&2
182 es=1
183 continue
184 fi
185
186# echo auto-loading $FUNC from ${fp[i]}/$FUNC
187 _aload $FUNC ${fp[i]}/$FUNC
188 es=0
189 done
190
191 return $es
192}