home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume26 / rmgetpts / part01 < prev    next >
Encoding:
Text File  |  1993-07-17  |  9.2 KB  |  370 lines

  1. Newsgroups: comp.sources.unix
  2. From: mzraly@ra.cs.umb.edu (Michael S. Zraly)
  3. Subject: v26i298: rmgetopts - remove getopts(1) from shell scripts, Part01/01
  4. Sender: unix-sources-moderator@gw.home.vix.com
  5. Approved: vixie@gw.home.vix.com
  6.  
  7. Submitted-By: mzraly@ra.cs.umb.edu (Michael S. Zraly)
  8. Posting-Number: Volume 26, Issue 298
  9. Archive-Name: rmgetopts/part01
  10.  
  11. The following program reads a shell script that uses getopts(1) to
  12. parse command line options and writes a new shell script that parses
  13. command line options without using getopts.
  14.  
  15. This program was written in response to questions I have received from
  16. people wanting to use sftp (comp.sources.unix, volume 26) who don't
  17. have geopts built into their shell and don't have access to shells that
  18. do (e.g. ksh, bash).
  19.  
  20. #! /bin/sh
  21. # This is a shell archive.  Remove anything before this line, then unpack
  22. # it by saving it into a file and typing "sh file".  To overwrite existing
  23. # files, type "sh file -c".  You can also feed this as standard input via
  24. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  25. # will see the following message at the end:
  26. #        "End of archive 1 (of 1)."
  27. # Contents:  MANIFEST Makefile README rmgetopts rmgetopts.1
  28. # Wrapped by mzraly@ra.cs.umb.edu on Fri Jul 16 06:00:50 1993
  29. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  30. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  31.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  32. else
  33. echo shar: Extracting \"'MANIFEST'\" \(251 characters\)
  34. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  35. X   File Name        Archive #    Description
  36. X-----------------------------------------------------------
  37. X MANIFEST                   1    
  38. X Makefile                   1    
  39. X README                     1    
  40. X rmgetopts                  1    
  41. X rmgetopts.1                1    
  42. END_OF_FILE
  43. if test 251 -ne `wc -c <'MANIFEST'`; then
  44.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  45. fi
  46. # end of 'MANIFEST'
  47. fi
  48. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  49.   echo shar: Will not clobber existing file \"'Makefile'\"
  50. else
  51. echo shar: Extracting \"'Makefile'\" \(609 characters\)
  52. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  53. X# rmgetopts Makefile
  54. X# Michael S Zraly
  55. X# mzraly@cs.umb.edu
  56. X# 16 July 1993
  57. X
  58. XPROG=    rmgetopts
  59. X
  60. XBIN=    /usr/local/bin
  61. XMAN=    /usr/local/man
  62. X
  63. XFILES=    Makefile README $(PROG) $(PROG).1
  64. X
  65. Xall:    $(PROG).man $(PROG).1 $(PROG)
  66. X
  67. Xinstall:    all
  68. X    cp $(PROG) $(BIN) && chmod 755 $(BIN)/$(PROG)
  69. X    cp $(PROG).1 $(MAN)/man1/$(PROG).1 && chmod 644 $(MAN)/man1/$(PROG).1
  70. X    cp $(PROG).man $(MAN)/cat1/$(PROG).1 && chmod 644 $(MAN)/cat1/$(PROG).1
  71. X
  72. Xclean:
  73. X    rm -f $(PROG).man $(PROG).tar.Z
  74. X
  75. X$(PROG).man:    $(PROG).1
  76. X    nroff -man $(PROG).1 > $(PROG).man
  77. X
  78. Xdist:    $(PROG).tar.Z
  79. X
  80. X$(PROG).tar.Z:    $(FILES)
  81. X    tar cvf - $(FILES) | compress > $(PROG).tar.Z
  82. END_OF_FILE
  83. if test 609 -ne `wc -c <'Makefile'`; then
  84.     echo shar: \"'Makefile'\" unpacked with wrong size!
  85. fi
  86. # end of 'Makefile'
  87. fi
  88. if test -f 'README' -a "${1}" != "-c" ; then 
  89.   echo shar: Will not clobber existing file \"'README'\"
  90. else
  91. echo shar: Extracting \"'README'\" \(1030 characters\)
  92. sed "s/^X//" >'README' <<'END_OF_FILE'
  93. Xrmgetopts README
  94. XMichael S Zraly
  95. Xmzraly@cs.umb.edu
  96. X16 July 1993
  97. X
  98. X
  99. XDESCRIPTION
  100. X
  101. XRmgetopts is a shell script that read a shell script that uses getopts
  102. Xto parse ocmmand line options and converts it into a script that does
  103. Xnot.  The resulting script will still parse command line options with
  104. Xthe same syntax, but will be slightly more portable (albeit slower).
  105. X
  106. XINSTALLATION
  107. X
  108. XType "make install".  The only "compiling" necessary is the formatting
  109. Xof the manual page; "make install" merely formats the manual page with
  110. Xnroff(1) and copies the manual pages and shell script into the
  111. Xappropriate directories.  You'll have to update the whatis(1) database
  112. Xby hand, though, since there are too many variations for me to worry
  113. Xabout.
  114. X
  115. XBUG REPORTS
  116. X
  117. XSend them (and fixes, if you have them) to me at:
  118. X
  119. X    mzraly@cs.umb.edu
  120. X
  121. XHISTORY
  122. X
  123. XI rewrote rmgetopts in response to the mail I got after posting sftp,
  124. Xwhich uses getopts, to comp.sources.unix.  I had not realized at the
  125. Xtime that getopts was a shell built-in and that so few people had it.
  126. X
  127. END_OF_FILE
  128. if test 1030 -ne `wc -c <'README'`; then
  129.     echo shar: \"'README'\" unpacked with wrong size!
  130. fi
  131. # end of 'README'
  132. fi
  133. if test -f 'rmgetopts' -a "${1}" != "-c" ; then 
  134.   echo shar: Will not clobber existing file \"'rmgetopts'\"
  135. else
  136. echo shar: Extracting \"'rmgetopts'\" \(2531 characters\)
  137. sed "s/^X//" >'rmgetopts' <<'END_OF_FILE'
  138. X#!/bin/sh
  139. X#
  140. X# rmgetopts --    Replace option-parsing in shell script using getopts
  141. X#        with more portable (but less efficient) hand-coded
  142. X#        version.
  143. X#
  144. X#    NOTE:    rmgetopts expects its input to have the form
  145. X#
  146. X#            ... random shell code ...
  147. X#            while getopts optstr var
  148. X#            do
  149. X#                ... more shell code ...
  150. X#            done
  151. X#            shift `expr $OPTIND - 1`
  152. X#            ... still more shell code ...
  153. X#
  154. X#    In particular:
  155. X#
  156. X#    (1) 'while getopts optstr var; do' is NOT allowed, at
  157. X#        least not yet.  The 'do' must follow the 'while'
  158. X#        on a line by itself.
  159. X#
  160. X#    (2) For now, whitespace consists solely of blank spaces
  161. X#        (i.e. no tabs)
  162. X#
  163. X#    (3) No whitespace of any sort may precede any of the
  164. X#        'while', 'do', 'done' or 'shift' lines.
  165. X#
  166. X#    (4) No comments may follow any of the 'while', 'do',
  167. X#        'done', or 'shift' lines.
  168. X#
  169. X#    (5) No restriction is made on the amount of whitespace
  170. X#        used to separate individual tokens on any line.
  171. X#        Trailing whitespace is allowed, but discouraged.
  172. X#
  173. X# Michael S Zraly
  174. X# mzraly@cs.umb.edu
  175. X# 16 July 1993
  176. X
  177. Xprog=`basename $0`
  178. Xusage='[file]'
  179. X
  180. XUSAGE="usage: $prog $usage"
  181. X
  182. X# determine value of $infile
  183. Xinfile=/tmp/rXmXg.??
  184. Xtrap 'rm -f $infile' 0 1 2 15
  185. X
  186. X# create $infile
  187. Xcase "$#" in
  188. X0)    cat > $infile
  189. X    ;;
  190. X1)    cp $1 $infile
  191. X    shift
  192. X    ;;
  193. X*)    echo $USAGE 1>&2
  194. X    exit 1
  195. X    ;;
  196. Xesac
  197. X
  198. X# make sure $infile contains calls to getopts...
  199. Xcase `grep -c '^while  *getopts' $infile` in
  200. X0)    echo $prog: cannot find getopts in input 1>&2
  201. X    exit 1
  202. X    ;;
  203. Xesac
  204. X
  205. X# edit $infile
  206. Xed - $infile <<'EOF' >/dev/null
  207. X/^while  *getopts/
  208. Xs/while  *getopts  */OPTSTR=/
  209. Xs/  */\
  210. X/
  211. Xs/.*/\
  212. X    &=$OPTOPT/
  213. X+1s/^do$//
  214. X?OPTSTR=?a
  215. Xwhile test "$#" -gt 0
  216. Xdo
  217. X    case "$1" in
  218. X    -|[!-]*)    break;;    # break from while loop
  219. X    --)    shift; break;;    # break from while loop
  220. X    esac
  221. X
  222. X    OPTPOS=2
  223. X    OPTOPT=`echo x$1 | colrm 1 $OPTPOS | colrm 2`    # x$1 to avoid -n
  224. X
  225. X    while test -n "$OPTOPT"
  226. X    do
  227. X        # if not legal arg, set OPTOPT to ?
  228. X        case "`echo $OPTSTR | grep -c -e $OPTOPT`" in
  229. X        0)    echo $prog: illegal option -- $OPTOPT 1>&2
  230. X            OPTOPT='?';;
  231. X        esac
  232. X
  233. X        # set OPTARG appropriately
  234. X        case "`echo $OPTSTR | grep -c -e $OPTOPT:`" in
  235. X        1)    OPTPOS=`expr $OPTPOS + 1`
  236. X            OPTARG=`echo x$1 | colrm 1 $OPTPOS`
  237. X            case "$OPTARG" in
  238. X            "")    shift; OPTARG=$1;;
  239. X            esac
  240. X            OPTPOS=32766    # terminate this arg
  241. X            ;;
  242. X        *)    OPTARG=;;
  243. X        esac
  244. X.
  245. X+1,/^done *$/-1s/^/    /
  246. X/^done *$/d
  247. X/^shift  *`expr  *$OPTIND  *-  *1`/d
  248. Xi
  249. X        # move on to next char in this arg
  250. X        OPTPOS=`expr $OPTPOS + 1`
  251. X        OPTOPT=`echo x$1 | colrm 1 $OPTPOS | colrm 2`
  252. X    done
  253. X    shift
  254. Xdone
  255. X.
  256. Xw
  257. Xq
  258. XEOF
  259. X
  260. X# print $infile (trap 0 should remove it)
  261. Xcat $infile
  262. X
  263. END_OF_FILE
  264. if test 2531 -ne `wc -c <'rmgetopts'`; then
  265.     echo shar: \"'rmgetopts'\" unpacked with wrong size!
  266. fi
  267. chmod +x 'rmgetopts'
  268. # end of 'rmgetopts'
  269. fi
  270. if test -f 'rmgetopts.1' -a "${1}" != "-c" ; then 
  271.   echo shar: Will not clobber existing file \"'rmgetopts.1'\"
  272. else
  273. echo shar: Extracting \"'rmgetopts.1'\" \(1250 characters\)
  274. sed "s/^X//" >'rmgetopts.1' <<'END_OF_FILE'
  275. X.\" rmgetopts manual-page
  276. X.\" Michael S Zraly
  277. X.\" mzraly@cs.umb.edu
  278. X.\" 16 July 1993
  279. X.\"
  280. X.TH RMGETOPTS 1 "July 16, 1993"
  281. X.SH NAME
  282. Xrmgetopts \- remove getopts processing from shell script
  283. X.SH SYNOPSIS
  284. X.B rmgetopts
  285. X[
  286. X.I file
  287. X]
  288. X.SH DESCRIPTION
  289. X.LP
  290. X.I rmgetopts
  291. Xreads a shell script that uses
  292. X.IR getopts (1)
  293. Xto process command options and converts it into one that does not.
  294. XInput
  295. X.B must
  296. Xhave the following form:
  297. X.LP
  298. X.RS
  299. X.nf
  300. X\&... random shell code ...
  301. X\&while getopts optstr var
  302. X\&do
  303. X\&    ... more shell code ...
  304. X\&done
  305. X\&shift `expr $OPTIND - 1`
  306. X\&... still more shell code ...
  307. X.fi
  308. X.RE
  309. X.LP
  310. X.I rmgetopts
  311. Xis a ``dumb'' program that knows next to nothing about shell syntax;
  312. Xthe following restriction must be observed for it to work properly.
  313. X.IP \(bu
  314. XThe
  315. X.I do
  316. Xmust follow the
  317. X.I while
  318. Xon a separate line.
  319. X.IP \(bu
  320. XNo trailing comments are allowed on any of the
  321. X.IR while ,
  322. X.IR do ,
  323. X.IR done ,
  324. Xor
  325. X.I shift
  326. Xlines.
  327. X.IP \(bu
  328. XNone of the
  329. X.IR while ,
  330. X.IR do ,
  331. X.IR done ,
  332. Xor
  333. X.I shift
  334. Xlines may have whitespace preceding the first keyword.
  335. XAll lines in between the
  336. X.I do
  337. Xand
  338. X.I done
  339. Xlines ought to be indented.
  340. X.SH "SEE ALSO"
  341. X.IR getopts (1),
  342. X.IR sh (1).
  343. X.SH BUGS
  344. XThe resulting code process options rather slowly.
  345. X.SH AUTHOR
  346. XMichael S Zraly (mzraly@cs.umb.edu)
  347. END_OF_FILE
  348. if test 1250 -ne `wc -c <'rmgetopts.1'`; then
  349.     echo shar: \"'rmgetopts.1'\" unpacked with wrong size!
  350. fi
  351. # end of 'rmgetopts.1'
  352. fi
  353. echo shar: End of archive 1 \(of 1\).
  354. cp /dev/null ark1isdone
  355. MISSING=""
  356. for I in 1 ; do
  357.     if test ! -f ark${I}isdone ; then
  358.     MISSING="${MISSING} ${I}"
  359.     fi
  360. done
  361. if test "${MISSING}" = "" ; then
  362.     echo You have the archive.
  363.     rm -f ark[1-9]isdone
  364. else
  365.     echo You still need to unpack the following archives:
  366.     echo "        " ${MISSING}
  367. fi
  368. ##  End of shell archive.
  369. exit 0
  370.