home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume2 / autoload < prev    next >
Internet Message Format  |  1991-08-07  |  4KB

  1. From: john@basser.cs.su.oz.AU (John Mackin)
  2. Newsgroups: comp.sources.misc
  3. Subject: v02i093: Autoloading shell scripts as functions
  4. Message-ID: <1226@basser.oz>
  5. Date: 12 Apr 88 21:41:16 GMT
  6. Approved: john@basser.cs.su.oz.AU
  7.  
  8. comp.sources.misc: Volume 2, Issue 93
  9. Submitted-By: John Mackin <john@basser.cs.su.oz.AU>
  10. Archive-Name: autoload
  11.  
  12. # This is a shell archive.  Remove anything before this line,
  13. # then unpack it by saving it in a file and typing "sh file".
  14. #
  15. # Wrapped by john on Wed Apr 13 07:08:49 EST 1988
  16. # Contents:  README autoload which
  17.  
  18. echo x - README
  19. sed 's/^@//' > "README" <<'@//E*O*F README//'
  20. @        Autoloading Shell Scripts as Functions
  21.  
  22. @    Concept and Implementation by (in alphabetical order):
  23.  
  24. @        John Mackin <john@basser.cs.su.oz.AU>
  25. @        Boyd Roberts <boyd@basser.cs.su.oz.AU>
  26.  
  27.  
  28. If you don't have a shell that supports functions, don't bother with
  29. this.  If you do, well, we developed this under the Rob Pike (Eighth
  30. Edition) shell, but we tested it on System V (seems to work as long
  31. as you don't try to export any functions) and under ksh (seems like
  32. it might work, we aren't sure though).  Caveat emptor, it's mainly the
  33. idea that matters, we're sure you can make it work on your implementation
  34. if you want to.
  35.  
  36. Suppose you have a shell function that you don't often use, that must
  37. be a function and not a script (maybe it sets environment variables).
  38. Or just say you have some big functions that you would like to have
  39. around when you want them, but that don't clutter your environment
  40. when you're not using them (for those that can export functions, that
  41. is).  Then this code is for you.  Originally inspired by the Franz
  42. Lisp `autoload' mechanism, this allows you to write your functions
  43. as scripts, and have them autoloaded as functions into the calling
  44. shell the first time they are executed.
  45.  
  46. For example, if $HOME/bin was in your path, and $HOME/bin/foo contained:
  47.  
  48. @    #!/bin/sh
  49.  
  50. @    echo This is foo.
  51.  
  52. Then if you included our autoload functions in your .profile, along
  53. with a call to autoload:
  54.  
  55. @    autoload foo
  56.  
  57. foo would originally get a function definition that would cause its
  58. autoloading if it were ever used, and after it was first used it would
  59. be defined as:
  60.  
  61. @    foo()
  62. @    {
  63. @        echo This is foo.
  64. @    }
  65.  
  66. We've included a copy of `which' after Kernighan & Pike (`The UNIX
  67. Programming Environment') so that this can be 100% self-contained.  Feel
  68. free to use a shell builtin instead if you have one that works (we
  69. do, almost...).
  70.  
  71. One `gotcha' is that if you autoload a script that uses here documents
  72. (that is, `<<') you may be surprised by the result.  It works on our
  73. shell, though; well, sort of.  I have no idea what other shells will
  74. do with it.
  75.  
  76. Another `gotcha' is that you shouldn't blindly autoload any script;
  77. rather, it requires a little bit of pre-planning.  In particular,
  78. setting environment variables cuts both ways.  What's great for
  79. a cutie that changes $TERM based on what kind of terminal your
  80. window is emulating is no fun at all if the script (and hence
  81. the function) changes PATH, or worse, IFS.
  82.  
  83. Have fun!
  84.  
  85. John Mackin, Basser Department of Computer Science,
  86. @         University of Sydney, Sydney, Australia
  87.  
  88. john@basser.oz.AU (john%basser.oz.AU@UUNET.UU.NET)
  89. {uunet,mcvax,ukc,nttlab}!munnari!basser.oz!john
  90. @//E*O*F README//
  91. chmod u=rw,g=r,o=r README
  92. echo x - autoload
  93. sed 's/^@//' > "autoload" <<'@//E*O*F autoload//'
  94. autoload()
  95. {
  96. @    for i
  97. @    do
  98. @        eval "$i()
  99. @        {
  100. @            loadit $i &&
  101. @            $i "'"$@"'"
  102. @        }
  103. @        export $i
  104. @        "
  105. @    done
  106. }
  107.  
  108. loadit()
  109. {
  110. @    if cmd=`which $1`
  111. @    then
  112. @        eval "$1()
  113. @        {
  114. @            `sed 's/\([^A-Za-z0-9_]*\)exec[     ]/\1/
  115. @                  s/\([^A-Za-z0-9_]*\)exit[     ]/\1return /
  116. @                  s/\([^A-Za-z0-9_]*\)exit$/\1return/
  117. @                  s/\([^A-Za-z0-9_]*\)trap[     ]/\1: /' $cmd`
  118. @        }
  119. @        "
  120. @    else
  121. @        echo $1: not found >&2
  122. @        return 1
  123. @    fi
  124. }
  125.  
  126. export autoload loadit
  127. @//E*O*F autoload//
  128. chmod u=rw,g=r,o=r autoload
  129. echo x - which
  130. sed 's/^@//' > "which" <<'@//E*O*F which//'
  131. # which - which command will execute?
  132.  
  133. oldpath=$PATH
  134. PATH=/bin:/usr/bin
  135.  
  136. case $# in
  137.  
  138. @    1)    ;;
  139. @    *)    echo usage: `basename $0` command-name >&2; exit 2 ;;
  140.  
  141. esac
  142.  
  143. for i in `echo $oldpath | sed 's/^:/.:/
  144. @                   s/::/:.:/g
  145. @                   s/:$/:./
  146. @                   s/:/ /g'`
  147. do
  148. @    if test -f $i/$1
  149. @    then
  150. @    echo $i/$1
  151. @    exit 0
  152. @    fi
  153. done
  154.  
  155. exit 1
  156. @//E*O*F which//
  157. chmod u=rwx,g=rx,o=rx which
  158. exit 0
  159.