| 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 func [func...] | 
|---|
| 16 | # | 
|---|
| 17 | # The first cut of this was by Bill Trost, trost@reed.bitnet | 
|---|
| 18 | # | 
|---|
| 19 | # Chet Ramey | 
|---|
| 20 | # chet@ins.CWRU.Edu | 
|---|
| 21 |  | 
|---|
| 22 | # | 
|---|
| 23 | # Declare a function ($1) to be autoloaded from a file ($2) when it is first | 
|---|
| 24 | # called.  This defines a `temporary' function that will `.' the file | 
|---|
| 25 | # containg the real function definition, then execute that new definition with | 
|---|
| 26 | # the arguments given to this `fake' function.  The autoload function defined | 
|---|
| 27 | # by the file and the file itself *must* be named identically. | 
|---|
| 28 | # | 
|---|
| 29 |  | 
|---|
| 30 | aload() | 
|---|
| 31 | { | 
|---|
| 32 | eval $1 '() {  . '$2' ; '$1' "$@" ; return $? ; }' | 
|---|
| 33 | } | 
|---|
| 34 |  | 
|---|
| 35 | # | 
|---|
| 36 | # Search $FPATH for a file the same name as the function given as $1, and | 
|---|
| 37 | # autoload the function from that file.  There is no default $FPATH. | 
|---|
| 38 | # | 
|---|
| 39 |  | 
|---|
| 40 | autoload() | 
|---|
| 41 | { | 
|---|
| 42 | # | 
|---|
| 43 | # Save the list of functions; we're going to blow away the arguments | 
|---|
| 44 | # in a second.  If any of the names contain white space, TFB. | 
|---|
| 45 | # | 
|---|
| 46 |  | 
|---|
| 47 | local args="$*" | 
|---|
| 48 |  | 
|---|
| 49 | # | 
|---|
| 50 | # This should, I think, list the functions marked as autoload and not | 
|---|
| 51 | # yet defined, but we don't have enough information to do that here. | 
|---|
| 52 | # | 
|---|
| 53 | if [ $# -eq 0 ] ; then | 
|---|
| 54 | echo "usage: autoload function [function...]" >&2 | 
|---|
| 55 | return 1 | 
|---|
| 56 | fi | 
|---|
| 57 |  | 
|---|
| 58 | # | 
|---|
| 59 | # If there is no $FPATH, there is no work to be done | 
|---|
| 60 | # | 
|---|
| 61 |  | 
|---|
| 62 | if [ -z "$FPATH" ] ; then | 
|---|
| 63 | echo autoload: FPATH not set or null >&2 | 
|---|
| 64 | return 1 | 
|---|
| 65 | fi | 
|---|
| 66 |  | 
|---|
| 67 | # | 
|---|
| 68 | # This treats FPATH exactly like PATH: a null field anywhere in the | 
|---|
| 69 | # FPATH is treated the same as the current directory. | 
|---|
| 70 | # | 
|---|
| 71 | # The path splitting command is taken from Kernighan and Pike | 
|---|
| 72 | # | 
|---|
| 73 |  | 
|---|
| 74 | #       fp=$(echo $FPATH | sed 's/^:/.:/ | 
|---|
| 75 | #                               s/::/:.:/g | 
|---|
| 76 | #                               s/:$/:./ | 
|---|
| 77 | #                               s/:/ /g') | 
|---|
| 78 |  | 
|---|
| 79 | # replaced with builtin mechanisms 2001 Oct 10 | 
|---|
| 80 |  | 
|---|
| 81 | fp=${FPATH/#:/.:} | 
|---|
| 82 | fp=${fp//::/:.:} | 
|---|
| 83 | fp=${fp/%:/:.} | 
|---|
| 84 | fp=${fp//:/ } | 
|---|
| 85 |  | 
|---|
| 86 | for FUNC in $args ; do | 
|---|
| 87 | # | 
|---|
| 88 | # We're blowing away the arguments to autoload here... | 
|---|
| 89 | # We have to; there are no arrays (well, there are, but | 
|---|
| 90 | # this doesn't use them yet). | 
|---|
| 91 | # | 
|---|
| 92 | set -- $fp | 
|---|
| 93 |  | 
|---|
| 94 | while [ $# -ne 0 ] ; do | 
|---|
| 95 | if [ -f $1/$FUNC ] ; then | 
|---|
| 96 | break                   # found it! | 
|---|
| 97 | fi | 
|---|
| 98 | shift | 
|---|
| 99 | done | 
|---|
| 100 |  | 
|---|
| 101 | if [ $# -eq 0 ] ; then | 
|---|
| 102 | echo "$FUNC: autoload function not found" >&2 | 
|---|
| 103 | continue | 
|---|
| 104 | fi | 
|---|
| 105 |  | 
|---|
| 106 | #               echo auto-loading $FUNC from $1/$FUNC | 
|---|
| 107 | aload $FUNC $1/$FUNC | 
|---|
| 108 | done | 
|---|
| 109 |  | 
|---|
| 110 | return 0 | 
|---|
| 111 | } | 
|---|