home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume31 / cmdline / part01 < prev    next >
Encoding:
Text File  |  1992-07-26  |  68.7 KB  |  2,172 lines

  1. Newsgroups: comp.sources.misc
  2. From: brad@hcx1.ssd.csd.harris.com (Brad Appleton)
  3. Subject:  v31i048:  cmdline - C++ Library for parsing command-line arguments, Part01/07
  4. Message-ID: <1992Jul27.020134.28965@sparky.imd.sterling.com>
  5. X-Md4-Signature: a7697c8b30038458111b360d90ac410a
  6. Date: Mon, 27 Jul 1992 02:01:34 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: brad@hcx1.ssd.csd.harris.com (Brad Appleton)
  10. Posting-number: Volume 31, Issue 48
  11. Archive-name: cmdline/part01
  12. Environment: C++
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then unpack
  16. # it by saving it into a file and typing "sh file".  To overwrite existing
  17. # files, type "sh file -c".  You can also feed this as standard input via
  18. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  19. # will see the following message at the end:
  20. #        "End of archive 1 (of 7)."
  21. # Contents:  MANIFEST Makefile README doc doc/Makefile doc/bugs.man
  22. #   doc/caveats.man doc/environ.man doc/example.man doc/files.man
  23. #   doc/macros.man src src/Makefile src/cmd src/cmd/Makefile
  24. #   src/cmd/cmdparse.h src/cmd/cmdparse.tcl src/cmd/fsm.h
  25. #   src/cmd/main.c src/cmd/quoted.h src/cmd/shell_arg.c
  26. #   src/cmd/shell_arg.h src/cmd/syntax.h src/lib src/lib/Makefile
  27. #   src/lib/arglist.h src/lib/exits.h src/lib/fifolist.c
  28. #   src/lib/patchlevel.c src/lib/states.h
  29. # Wrapped by brad@hcx1 on Mon Jul 20 10:41:25 1992
  30. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  31. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  32.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  33. else
  34. echo shar: Extracting \"'MANIFEST'\" \(3979 characters\)
  35. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  36. X   File Name        Archive #    Description
  37. X-----------------------------------------------------------
  38. X Config.mk                  2    Make flags for the product
  39. X MANIFEST                   1    This shipping list
  40. X Makefile                   1    Makefile for the product
  41. X Overview                   3    A brief overview of the product
  42. X README                     1    Read this file first
  43. X doc                        1    Documentation directory
  44. X doc/Makefile               1    Makefile for the documentation
  45. X doc/bugs.man               1    documents known bugs
  46. X doc/caveats.man            1    documents known peculiarities
  47. X doc/classes.man            4    documents the basics of the most common classes
  48. X doc/cmdargs.man3           2    documents <cmdargs.h>
  49. X doc/cmdline.man3           2    documents <cmdline.h>
  50. X doc/cmdparse.man1          5    documents cmdparse(1)
  51. X doc/environ.man            1    documents the use of environment variables
  52. X doc/example.man            1    documents example use of CmdLine(3C++)
  53. X doc/files.man              1    documents files used by CmdLine(3C++)
  54. X doc/macros.man             1    some common (n|t)roff macros
  55. X doc/parsing.man            2    documents parsing behavior
  56. X src                        1    Source code directory
  57. X src/Makefile               1    Makefile for the source directories
  58. X src/cmd                    1    cmdparse program subdirectory
  59. X src/cmd/Makefile           1    Makefile for the program
  60. X src/cmd/argtypes.c         2    implementation of shell-script arguments
  61. X src/cmd/argtypes.h         2    definition of shell-script arguments
  62. X src/cmd/cmdparse.c         6    the guts of the cmdparse program
  63. X src/cmd/cmdparse.h         1    the specification of the cmdparse program
  64. X src/cmd/cmdparse.pl        2    cmdparse for Perl programmers
  65. X src/cmd/cmdparse.tcl       1    cmdparse for Tcl programmers
  66. X src/cmd/fsm.c              2    finite-state-machine for parsing arg-syntax
  67. X src/cmd/fsm.h              1    finite-state-machine specification
  68. X src/cmd/main.c             1    main program for cmdparse(1)
  69. X src/cmd/quoted.c           2    implementation of quoted-strings
  70. X src/cmd/quoted.h           1    definition of a quoted-string class
  71. X src/cmd/shell_arg.c        1    implementation of an abstract shell-script arg
  72. X src/cmd/shell_arg.h        1    definition of an abstract shell-script argument
  73. X src/cmd/shells.c           4    implementation of command-interpreters
  74. X src/cmd/shells.h           4    definitions of various command-interpreters
  75. X src/cmd/syntax.c           4    implementation of an argument-syntax object
  76. X src/cmd/syntax.h           1    definition of an argument-syntax object
  77. X src/lib                    1    CmdLine library directory
  78. X src/lib/Makefile           1    Makefile for the library
  79. X src/lib/argiter.c          2    command line argument iterator implementation
  80. X src/lib/arglist.h          1    command argument list type definitions
  81. X src/lib/cmdarg.c           3    implementation of base class CmdArg
  82. X src/lib/cmdargs.c          5    implementation of the various argument types
  83. X src/lib/cmdargs.h          7    include file for the various argument types
  84. X src/lib/cmdline.c          3    constructors/destructors for CmdLine objects
  85. X src/lib/cmdline.h          7    include file for the library
  86. X src/lib/cmdtest.c          3    test program for the library
  87. X src/lib/dump.c             3    dumping/debugging member functions
  88. X src/lib/exits.h            1    definition of exit codes used for exit(3C)
  89. X src/lib/fifolist.c         1    implementation of a generic FIFO linked list
  90. X src/lib/fifolist.h         2    definition of a generic FIFO linked list
  91. X src/lib/parse.c            2    public parsing functions for CmdLine
  92. X src/lib/patchlevel.c       1    functions to return version information
  93. X src/lib/private.c          5    private/protected functions for a CmdLine
  94. X src/lib/states.h           1    state enumeration definitions
  95. X src/lib/strindent.c        3    function to print a hanging indented paragraph
  96. X src/lib/unix.c             6    Unix specific parts of a CmdLine
  97. X src/lib/usage.c            3    usage-message specific parts of a CmdLine
  98. END_OF_FILE
  99. if test 3979 -ne `wc -c <'MANIFEST'`; then
  100.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  101. fi
  102. # end of 'MANIFEST'
  103. fi
  104. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  105.   echo shar: Will not clobber existing file \"'Makefile'\"
  106. else
  107. echo shar: Extracting \"'Makefile'\" \(1290 characters\)
  108. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  109. X##########################################################################
  110. X## ^FILE: Makefile - make file for the CmdLine product
  111. X##
  112. X## ^DESCRIPTION:
  113. X##    This is the makefile that is used to build and install the CmdLine
  114. X##    product.
  115. X##
  116. X## ^HISTORY:
  117. X##    04/28/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  118. X###^^#####################################################################
  119. X
  120. Xinclude Config.mk
  121. X
  122. XSUBDIRS = src doc
  123. XSRCDIRS = src
  124. XDOCDIRS = doc
  125. X
  126. X###
  127. X# target dependencies
  128. X###
  129. Xhelp:
  130. X    @$(ECHO) "Usage: make <target>"
  131. X    @$(ECHO) ""
  132. X    @$(ECHO) "where <target> is one of the following:"
  133. X    @$(ECHO) ""
  134. X    @$(ECHO) "    all        -- build (but do not install) the product"
  135. X    @$(ECHO) "    install    -- install the product"
  136. X    @$(ECHO) "    library    -- build the cmdline library"
  137. X    @$(ECHO) "    program    -- build the cmdparse program"
  138. X    @$(ECHO) "    docs       -- build the documentation"
  139. X    @$(ECHO) "    clean      -- remove all intermediate files"
  140. X    @$(ECHO) "    clobber    -- remove all generated files"
  141. X    @$(ECHO) ""
  142. X
  143. Xall install clean clobber:
  144. X    for i in $(SUBDIRS) ; do \
  145. X        ( $(CHDIR) $$i ; $(BUILD) $@ ) ; \
  146. X    done
  147. X
  148. Xlibrary program:
  149. X    for i in $(SRCDIRS) ; do \
  150. X        ( $(CHDIR) $$i ; $(BUILD) $@ ) ; \
  151. X    done
  152. X
  153. Xdocs:
  154. X    for i in $(DOCDIRS) ; do \
  155. X        ( $(CHDIR) $$i ; $(BUILD) all ) ; \
  156. X    done
  157. X
  158. END_OF_FILE
  159. if test 1290 -ne `wc -c <'Makefile'`; then
  160.     echo shar: \"'Makefile'\" unpacked with wrong size!
  161. fi
  162. # end of 'Makefile'
  163. fi
  164. if test -f 'README' -a "${1}" != "-c" ; then 
  165.   echo shar: Will not clobber existing file \"'README'\"
  166. else
  167. echo shar: Extracting \"'README'\" \(6030 characters\)
  168. sed "s/^X//" >'README' <<'END_OF_FILE'
  169. X
  170. X WHAT IS THIS?
  171. X =============
  172. X This is CmdLine, a C++ library for parsing command arguments and assigning
  173. X the corresponding values to program variables. Also included is cmdparse,
  174. X a program to provide an interface to CmdLine for shell-scripts. See the 
  175. X file named "Overview" for a more thorough introduction!
  176. X
  177. X
  178. X AUTHOR
  179. X ======
  180. X Brad Appleton                     Harris Corp., Computer Systems Division
  181. X   Senior Software Engineer        2101 West Cypress Creek Road,  M/S 161 
  182. X     brad@ssd.csd.harris.com       Fort Lauderdale, FL  33309-1892  USA
  183. X       ...!uunet!travis!brad              Phone: (305) 973-5190
  184. X
  185. X
  186. X COPY/REUSE POLICY
  187. X =================
  188. X Permission is hereby granted to freely copy and redistribute this
  189. X software, provided that the author is clearly credited in all copies
  190. X and derivations. Neither the names of the authors nor that of their
  191. X employers may be used to endorse or promote products derived from this
  192. X software without specific written permission.
  193. X
  194. X
  195. X DISCLAIMER
  196. X ==========
  197. X This software is provided ``As Is'' and without any express or implied
  198. X warranties.  Neither the authors nor any of their employers (including
  199. X any of their subsidiaries and subdivisions) are responsible for maintaining
  200. X or supporting this software or for any consequences resulting from the
  201. X use of this software, no matter how awful, even if they arise from flaws
  202. X in the software.
  203. X
  204. X
  205. X CONTENTS
  206. X ========
  207. X See the file "MANIFEST" in the distribution for a complete list and
  208. X description of all the files included in this release.
  209. X
  210. X
  211. X REQUIREMENTS
  212. X ============
  213. X This software should compile on most Unix platforms with a C++ compiler
  214. X with little or no difficulty.
  215. X
  216. X You will need to tweak the Makefiles a tad in order to make them work
  217. X for your C++ compiler.
  218. X
  219. X CmdLine makes extensive use of the "new" operator but makes no attempt
  220. X to see if allocation failed!  CmdLine assumes that any such desired
  221. X error-checking will be taken care of by the programmer by #including
  222. X the header file <new.h> and using the set_new_handler() function.
  223. X
  224. X COMPILATION OPTIONS
  225. X ===================
  226. X The following names may be `#define'd when building CmdLine.
  227. X
  228. X unix            Needed for unix systems
  229. X vms             Needed for vms systems
  230. X msdos           Needed for MS-DOS systems.
  231. X os2             Needed for OS/2 Systems.
  232. X
  233. X unix_style      (This is the default) Use this to have CmdLine parse
  234. X                 command-lines using traditional Unix command-line syntax.
  235. X
  236. X vms_style       (Not yet supported) Use this to have CmdLine parse
  237. X                 command-lines using traditional VAX/VMS DCL syntax.
  238. X
  239. X USE_PLUS        Makes CmdLine use "+" instead of "--" as the keyword prefix
  240. X                 when -Dunix_style is used.
  241. X
  242. X DEBUG_CMDLINE   Enables use of the "dump" member functions in the CmdLine
  243. X                 library.
  244. X
  245. X TEMPLATES       #define this if your C++ compiler supports templates.
  246. X
  247. X GNU_READLINE    Use this if you want CmdLine to use the readline library
  248. X                 (from the FSF) when prompting the user for arguments.
  249. X                 You will probably also need to link with this library.
  250. X
  251. X
  252. X PORTING
  253. X =======
  254. X You may need to tweak the makefiles a bit in order to get CmdLine to build
  255. X properly.  First look at "Config.mk" and change the make-variables to what-
  256. X ever is appropriate for your operating system and compilation environment.
  257. X If you are on an operating system other than Unix, you will also need to
  258. X change all of the "include" statements in the Makefiles to use the proper
  259. X pathname syntax.  If you change the definitions of $(LIBDIR) and $(INCDIR)
  260. X in Config.mk then you should also modify the file doc/macros.man to indicate
  261. X the new locations for where these files are installed.
  262. X
  263. X You should be aware of the following when porting CmdLine to other platforms.
  264. X
  265. X 1) CmdLine assumes that at least one of __STDC__ or __ANSI_CPP__ will be
  266. X    #defined if your C++ compiler uses an ANSI-C preprocessor.
  267. X
  268. X 2) CmdLine uses <stdarg.h> (not <varargs.h>) to handle functions that may
  269. X    take a variable number of arguments.
  270. X 3) Not all systems have the strtod() function used in src/lib/cmdargs.c,
  271. X    If your system DOES have strtod but it is NOT in <stdlib.h> then you
  272. X    will need to add a prototype for it in src/lib/cmdargs.c.  It is possible
  273. X    (but less likely) that you may have similar problems with strtol().
  274. X
  275. X 4) CmdLine uses the AT&T C++ iostream library.  Beyond that, all the
  276. X    #include files it uses are assumed to have the contents specified by
  277. X    the ANSI-C standard and are assumed to have #ifdef __cplusplus statements
  278. X    for when they are being included by C++ files.  CmdLine assumes the
  279. X    existence of the following system header files:
  280. X
  281. X         <stdarg.h>
  282. X         <stdlib.h>
  283. X         <string.h>
  284. X         <ctype.h>
  285. X         <iostream.h>
  286. X         <fstream.h>
  287. X         <strstream.h>
  288. X         <malloc.h>    <--- only used on Unix systems
  289. X
  290. X
  291. X BUGS
  292. X ====
  293. X Please send all bug reports to Brad Appleton <brad@ssd.csd.harris.com>.
  294. X Dont forget to mention which version of CmdLine you have and which
  295. X operating system and C++ compiler you are using.
  296. X
  297. X
  298. X ACKNOWLEDGEMENTS
  299. X ================
  300. X CmdLine is a C++ rewrite of ParseArgs.  The author of this software would
  301. X like to thank Eric Allman and Peter da Silva for their great ideas.
  302. X
  303. X
  304. X FURTHER INFORMATION
  305. X ===================
  306. X For an introduction -- look at the file "Overview" in the distribution!
  307. X
  308. X The documentation is in Unix manpage format (troff with the -man macros)
  309. X and may be found in the "doc" directory but you should be able to find
  310. X out quite a bit by reading the comments in the source files (especially
  311. X in <cmdline.h> and <cmdargs.h>) and by looking at the sample test-program(s).
  312. X
  313. X
  314. X HISTORY
  315. X =======
  316. X Look at the file src/lib/patchlevel.c to see what version of CmdLine you
  317. X have.  Any changes made to the CmdLine product should be documented here:
  318. X
  319. X
  320. X 07/21/92        Brad Appleton        <brad@ssd.csd.harris.com>
  321. X -----------------------------------------------------------------------------
  322. X First release.
  323. X
  324. END_OF_FILE
  325. if test 6030 -ne `wc -c <'README'`; then
  326.     echo shar: \"'README'\" unpacked with wrong size!
  327. fi
  328. # end of 'README'
  329. fi
  330. if test ! -d 'doc' ; then
  331.     echo shar: Creating directory \"'doc'\"
  332.     mkdir 'doc'
  333. fi
  334. if test -f 'doc/Makefile' -a "${1}" != "-c" ; then 
  335.   echo shar: Will not clobber existing file \"'doc/Makefile'\"
  336. else
  337. echo shar: Extracting \"'doc/Makefile'\" \(2902 characters\)
  338. sed "s/^X//" >'doc/Makefile' <<'END_OF_FILE'
  339. X##########################################################################
  340. X## ^FILE: Makefile - make file for the documentation for CmdLine product
  341. X##
  342. X## ^DESCRIPTION:
  343. X##    This is the makefile that is used to build and install the
  344. X##    documentation CmdLine product.
  345. X##
  346. X## ^HISTORY:
  347. X##    04/28/92  Brad Appleton   <brad@ssd.csd.harris.com>   Created
  348. X###^^#####################################################################
  349. X
  350. Xinclude ../Config.mk
  351. X
  352. X###
  353. X# give a usage message if no target is given
  354. X###
  355. Xusage:
  356. X    @echo "Usage: make <target>"
  357. X    @echo " "
  358. X    @echo "where <target> is one of the following: "
  359. X    @echo " "
  360. X    @echo "   install  -- to install the documentation"
  361. X    @echo "   installman  -- to install the unpacked documentation"
  362. X    @echo "   installcatman  -- to install the packed documentation"
  363. X    @echo "   print  -- to print the documentation"
  364. X    @echo "   view   -- to view the documentation"
  365. X    @echo "   text   -- to build text copies of the documentation"
  366. X    @echo "   spell  -- to spell check the documentation"
  367. X    @echo "   clean  -- to remove all intermediate files"
  368. X    @echo "   clobber  -- to remove all created files"
  369. X
  370. X###
  371. X# files used
  372. X###
  373. XINCLUDES=bugs.man caveats.man environ.man example.man files.man \
  374. X         macros.man parsing.man
  375. XDOCS=cmdparse.man1 cmdline.man3 cmdargs.man3
  376. XMAN3FILES=cmdline.3 cmdargs.3
  377. XMAN1FILES=cmdparse.1
  378. XCATMAN3FILES=cmdline.3.z cmdargs.3.z
  379. XCATMAN1FILES=cmdparse.1.z
  380. X
  381. X###
  382. X# target dependencies
  383. X###
  384. X.SUFFIXES: .man1 .man3 .1 .3
  385. X
  386. X.man1.1:
  387. X    $(SOELIM) $< >$*.1
  388. X    $(MANTOCATMAN) $*.1
  389. X
  390. X.man3.3:
  391. X    $(SOELIM) $< >$*.3
  392. X    $(MANTOCATMAN) $*.3
  393. X
  394. X###
  395. X# installation dependencies
  396. X###
  397. Xall:
  398. X
  399. Xinstall: installman installcatman
  400. X
  401. Xinstallman: installman1 installman3
  402. X
  403. Xinstallcatman: installcatman1 installcatman3
  404. X
  405. Xinstallman1: $(MAN1FILES)
  406. X    ( $(CHDIR) $(MANDIR)$(MAN1DIR) ; $(RM) $(MAN1FILES) )
  407. X    $(CP) $(MAN1FILES) $(MANDIR)$(MAN1DIR)
  408. X
  409. Xinstallcatman1: $(CATMAN1FILES)
  410. X    ( $(CHDIR) $(CATMANDIR)$(MAN1DIR) ; $(RM) $(CATMAN1FILES) )
  411. X    $(CP) $(CATMAN1FILES) $(CATMANDIR)$(MAN1DIR)
  412. X
  413. Xinstallman3: $(MAN3FILES)
  414. X    ( $(CHDIR) $(MANDIR)$(MAN3DIR) ; $(RM) $(MAN3FILES) )
  415. X    $(CP) $(MAN3FILES) $(MANDIR)$(MAN3DIR)
  416. X
  417. Xinstallcatman3: $(CATMAN3FILES)
  418. X    ( $(CHDIR) $(CATMANDIR)$(MAN3DIR) ; $(RM) $(CATMAN3FILES) )
  419. X    $(CP) $(CATMAN3FILES) $(CATMANDIR)$(MAN3DIR)
  420. X
  421. X###
  422. X# maintenance dependencies
  423. X###
  424. Xclean:
  425. X    $(RM) $(MAN1FILES) $(MAN3FILES) $(CATMAN1FILES) $(CATMAN3FILES) CmdLine.3.z
  426. X
  427. Xclobber: clean
  428. X    $(RM) *.txt
  429. X
  430. Xspell: $(DOCS) $(INCLUDES)
  431. X    $(SPELL) $(DOCS) $(INCLUDES)
  432. X
  433. Xprint: $(MANFILES)
  434. X    $(TROFF) $(TRFLAGS) $(DOCS)
  435. X
  436. Xtext: ascii
  437. Xtxt: ascii
  438. Xascii:
  439. X    $(NROFF) $(NRFLAGS) cmdparse.man1 | $(COL) > cmdparse1.txt
  440. X    $(NROFF) $(NRFLAGS) cmdline.man3  | $(COL) > cmdline3.txt
  441. X    $(NROFF) $(NRFLAGS) cmdargs.man3  | $(COL) > cmdargs3.txt
  442. X
  443. Xview: $(MANFILES)
  444. X    $(NROFF) $(NRFLAGS) $(DOCS)
  445. X
  446. X##
  447. X# include dependencies
  448. X##
  449. Xcmdparse.1: cmdparse.man1 $(INCLUDES)
  450. X
  451. Xcmdline.3: cmdline.man3 $(INCLUDES)
  452. X
  453. Xcmdargs.3: cmdargs.man3 $(INCLUDES)
  454. X
  455. END_OF_FILE
  456. if test 2902 -ne `wc -c <'doc/Makefile'`; then
  457.     echo shar: \"'doc/Makefile'\" unpacked with wrong size!
  458. fi
  459. # end of 'doc/Makefile'
  460. fi
  461. if test -f 'doc/bugs.man' -a "${1}" != "-c" ; then 
  462.   echo shar: Will not clobber existing file \"'doc/bugs.man'\"
  463. else
  464. echo shar: Extracting \"'doc/bugs.man'\" \(677 characters\)
  465. sed "s/^X//" >'doc/bugs.man' <<'END_OF_FILE'
  466. X.SH BUGS
  467. XWhen a non-multivalued argument appears more than once on the command-line
  468. Xthen only the last value supplied is used. A problem occurs however in the
  469. Xfollowing scenario: suppose `\fB\-s\fP' is an option that takes an optional
  470. Xstring argument (and suppose `\fB\-x\fP' is some boolean flag). Now, if the
  471. Xfollowing command-line is issued:
  472. X
  473. X.XS
  474. Xcommand  \-s string  \-x  \-s
  475. X.XE
  476. X
  477. Xthen, even though it may appear as if the value used will properly correspond
  478. Xto the second instance of the `\fB\-s\fP' option, the value associated with
  479. Xthe option will be ``\fIstring\fP'' (because the first instance overwrote
  480. Xthe default and the second instance left the value untouched).
  481. X
  482. END_OF_FILE
  483. if test 677 -ne `wc -c <'doc/bugs.man'`; then
  484.     echo shar: \"'doc/bugs.man'\" unpacked with wrong size!
  485. fi
  486. # end of 'doc/bugs.man'
  487. fi
  488. if test -f 'doc/caveats.man' -a "${1}" != "-c" ; then 
  489.   echo shar: Will not clobber existing file \"'doc/caveats.man'\"
  490. else
  491. echo shar: Extracting \"'doc/caveats.man'\" \(1292 characters\)
  492. sed "s/^X//" >'doc/caveats.man' <<'END_OF_FILE'
  493. X.SH CAVEATS
  494. XWhen an argument takes a required value and the value is in a separate
  495. Xtoken from the argument (as in "\fB\-c\ \ \fIvalue\fR") then the next
  496. Xtoken on the command-line is assumed to be the value for that argument
  497. X(even if the token \fIlooks\fP like an option because its starts with
  498. Xa `\-' character).
  499. X
  500. XIf however, an argument takes an \fIoptional\fP value and the value is
  501. Xin a separate token from the argument, the next token on the command-line
  502. Xis assumed to be the value for that argument \fIonly if the next token
  503. Xdoes \s-1NOT\s+1 look like an option\fP.  In order to specify a value
  504. Xthat looks like an option to an argument that takes an optional value,
  505. Xit is recommended that the value occur in the same token as the argument
  506. Xitself (as in "\fB\-c\fI\-value\fR").
  507. X
  508. XThe above also applies to non-positional lists.  A non-positional list
  509. Xis automatically terminated by another option, or by the token ``\*(--''.
  510. XIt is a "feature" of \*(NM that the following are equivalent (assuming
  511. Xthat \fB\-l\fP takes a list of one or more values):
  512. X
  513. X.XS
  514. Xcmdname \-l value1 value2 
  515. Xcmdname \-lvalue1 \-lvalue2
  516. X.XE
  517. X
  518. XHence, to supply values that look like options to non-positional list
  519. Xarguments, it is recommended that the following syntax be used:
  520. X
  521. X.XS
  522. Xcmdname \-l\-value1 \-l\-value2
  523. X.XE
  524. X
  525. END_OF_FILE
  526. if test 1292 -ne `wc -c <'doc/caveats.man'`; then
  527.     echo shar: \"'doc/caveats.man'\" unpacked with wrong size!
  528. fi
  529. # end of 'doc/caveats.man'
  530. fi
  531. if test -f 'doc/environ.man' -a "${1}" != "-c" ; then 
  532.   echo shar: Will not clobber existing file \"'doc/environ.man'\"
  533. else
  534. echo shar: Extracting \"'doc/environ.man'\" \(616 characters\)
  535. sed "s/^X//" >'doc/environ.man' <<'END_OF_FILE'
  536. X.SH ENVIRONMENT
  537. XThe following two environment variables (if defined) are used
  538. Xby \*(NM:
  539. X
  540. X.IP "$PROMPT_USER"
  541. XIf this variable exists and is non-empty, then the user will be
  542. Xinteractively prompted for any missing required arguments.
  543. X
  544. X.IP "$USAGE_LEVEL"
  545. XThis variable controls the verboseness of usage messages that are printed.
  546. XIf This variable is empty or is undefined, then verbose messages are printed.
  547. XIf this variable exists and is non-empty, it may be set to one of the
  548. Xfollowing values:
  549. X.RS
  550. X.IP 0
  551. XNo usage message is printed.
  552. X.IP 1
  553. XA terse usage message is printed
  554. X.IP 2
  555. XA verbose usage message is printed.
  556. X.RE
  557. END_OF_FILE
  558. if test 616 -ne `wc -c <'doc/environ.man'`; then
  559.     echo shar: \"'doc/environ.man'\" unpacked with wrong size!
  560. fi
  561. # end of 'doc/environ.man'
  562. fi
  563. if test -f 'doc/example.man' -a "${1}" != "-c" ; then 
  564.   echo shar: Will not clobber existing file \"'doc/example.man'\"
  565. else
  566. echo shar: Extracting \"'doc/example.man'\" \(1994 characters\)
  567. sed "s/^X//" >'doc/example.man' <<'END_OF_FILE'
  568. X.SH EXAMPLE
  569. X.PP
  570. XUsing the \*(NM library is relatively easy \- you need to construct your
  571. Xarguments, your command-line, and your argument iterator.  Then all that is
  572. Xleft to do is call the \f4parse\fP member function of your \*(NM object.
  573. XThe following is a simple example:
  574. X
  575. X.XS
  576. X#include <stdlib.h>
  577. X#include <iostream.h>
  578. X#include <cmdargs.h>
  579. X
  580. Xint  main(int argc, char * argv[])
  581. X{
  582. X      // Declare arguments
  583. X   CmdArgInt  count('c', "count", "number",
  584. X                       "number of copies to print.");
  585. X.sp 4p
  586. X   CmdArgBool xflag('x', "xmode",
  587. X                       "turn on 'x'-mode.");
  588. X.sp 4p
  589. X   CmdArgChar fdsep('s', "separator", "char",
  590. X                       "field-separator to use.");
  591. X.sp 4p
  592. X   CmdArgStr  input("input-file",
  593. X                       "input file to read.");
  594. X.sp 4p
  595. X   CmdArgStrList  output("[output-file \*(..]",
  596. X                            "where to print output.");
  597. X
  598. X      // Declare the command and the argument-iterator
  599. X   CmdLine  cmd(*argv,
  600. X                   &count, &xflag, &fdsep,
  601. X                   &input, &output, NULL);
  602. X.sp 4p
  603. X   CmdArgvIter  arg_iter(--argc, ++argv);
  604. X
  605. X      // Initialize arguments to appropriate default values.
  606. X   count = 1;
  607. X   xflag = 0;
  608. X   fdsep = ',';
  609. X
  610. X      // Parse arguments
  611. X   cmd.parse(arg_iter);
  612. X
  613. X      // Print arguments
  614. X   cout << "count=" << count << endl ;
  615. X   cout << "xflag=" << (xflag ? "ON" : "OFF") << endl ;
  616. X   cout << "fdsep='" << (char) fdsep << "'" << endl ;
  617. X   cout << "input=\\"" << input << "\\"" << endl ;
  618. X   
  619. X   for (int i = 0 ; i < output.count() ; i++) {
  620. X      cout << "output[" << i << "]=" << output[i] << endl ;
  621. X   }
  622. X
  623. X   return  0;
  624. X}
  625. X.XE
  626. X
  627. XThe Unix command-line syntax for the above program would be as follows:
  628. X
  629. X.XS
  630. Xprogname [\-c number] [\-x] [\-s char] input-file [output-file \*(..]
  631. X.XE
  632. X
  633. XThe Unix command-line syntax using long-options (keywords) for the above
  634. Xprogram would be as follows:
  635. X
  636. X.XS
  637. Xprogname [\*(--count number] [\*(--xmode] [\*(--separator char]
  638. X         input-file [output-file \*(..]
  639. X.XE
  640. END_OF_FILE
  641. if test 1994 -ne `wc -c <'doc/example.man'`; then
  642.     echo shar: \"'doc/example.man'\" unpacked with wrong size!
  643. fi
  644. # end of 'doc/example.man'
  645. fi
  646. if test -f 'doc/files.man' -a "${1}" != "-c" ; then 
  647.   echo shar: Will not clobber existing file \"'doc/files.man'\"
  648. else
  649. echo shar: Extracting \"'doc/files.man'\" \(584 characters\)
  650. sed "s/^X//" >'doc/files.man' <<'END_OF_FILE'
  651. X.SH FILES
  652. X.PP
  653. X.IP \f4\*i/cmdline.h\fP
  654. X\*(C+ include file which contains the definition of a command-argument class,
  655. Xa command-line class, and argument-iterator classes.
  656. X
  657. X.IP \f4\*i/cmdargs.h\fP
  658. X\*(C+ include file which contains the definitions of some predefined
  659. Xcommand-argument subclasses.
  660. X
  661. X.IP \f4\*l/libcmdline.a\fP
  662. XThe object library for \*(NM(3\*(C+).
  663. X
  664. X.PP
  665. XWhen compiling your source (on Unix systems), you may need to use
  666. Xthe \fB\-I\f4\*i\fR option. When linking your objects,
  667. Xyou may need to use the \fB\-L\f4\*l\fR option in conjunction
  668. Xwith the \fB\-l\f4cmdline\fR option.
  669. X
  670. END_OF_FILE
  671. if test 584 -ne `wc -c <'doc/files.man'`; then
  672.     echo shar: \"'doc/files.man'\" unpacked with wrong size!
  673. fi
  674. # end of 'doc/files.man'
  675. fi
  676. if test -f 'doc/macros.man' -a "${1}" != "-c" ; then 
  677.   echo shar: Will not clobber existing file \"'doc/macros.man'\"
  678. else
  679. echo shar: Extracting \"'doc/macros.man'\" \(839 characters\)
  680. sed "s/^X//" >'doc/macros.man' <<'END_OF_FILE'
  681. X.\"=========================================
  682. X.\" This file contains some user defined (n|t)roff macros for general use
  683. X.\"=========================================
  684. X.de XS
  685. X. RS
  686. X. nf
  687. X. ft 4
  688. X..
  689. X.de XE
  690. X. ft R
  691. X. fi
  692. X. RE
  693. X..
  694. X.ds -- \-\|\-
  695. X.ds C+ C\s-2\v'-1.5p'\(pl\(pl\v'+1.5p'\s+2
  696. X.ds .. .\^.\^.
  697. X.\"-------------------------------------------
  698. X.\" The following "strings" should correspond to where the CmdLine files
  699. X.\" have been installed.  "b" is where executable files are installed.
  700. X.\" "i" is where the include files where installed and "l" is where the
  701. X.\" object-library is installed. You should change the definition of
  702. X.\" these macros if they are not installed in the places indicated below.
  703. X.\"-------------------------------------------
  704. X.ds b /usr/local/bin
  705. X.ds i /usr/local/include
  706. X.ds l /usr/local/lib
  707. X.ds p \*l/perl
  708. X.ds t \*l/tcl
  709. END_OF_FILE
  710. if test 839 -ne `wc -c <'doc/macros.man'`; then
  711.     echo shar: \"'doc/macros.man'\" unpacked with wrong size!
  712. fi
  713. # end of 'doc/macros.man'
  714. fi
  715. if test ! -d 'src' ; then
  716.     echo shar: Creating directory \"'src'\"
  717.     mkdir 'src'
  718. fi
  719. if test -f 'src/Makefile' -a "${1}" != "-c" ; then 
  720.   echo shar: Will not clobber existing file \"'src/Makefile'\"
  721. else
  722. echo shar: Extracting \"'src/Makefile'\" \(1278 characters\)
  723. sed "s/^X//" >'src/Makefile' <<'END_OF_FILE'
  724. X##########################################################################
  725. X## ^FILE: Makefile - make file for the CmdLine product
  726. X##
  727. X## ^DESCRIPTION:
  728. X##    This is the makefile that is used to build and install the CmdLine
  729. X##    library and the cmdparse program.
  730. X##
  731. X## ^HISTORY:
  732. X##    04/28/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  733. X###^^#####################################################################
  734. X
  735. Xinclude ../Config.mk
  736. X
  737. XSUBDIRS = lib cmd 
  738. XLIBDIRS = lib
  739. XPROGDIRS = cmd
  740. X
  741. X###
  742. X# target dependencies
  743. X###
  744. Xhelp:
  745. X    @$(ECHO) "Usage: make <target>"
  746. X    @$(ECHO) ""
  747. X    @$(ECHO) "where <target> is one of the following:"
  748. X    @$(ECHO) ""
  749. X    @$(ECHO) "    all        -- build (but do not install) the product"
  750. X    @$(ECHO) "    install    -- install CmdLine(3C++) and cmdparse(1)
  751. X    @$(ECHO) "    library    -- build the cmdline library"
  752. X    @$(ECHO) "    program    -- build the cmdparse program"
  753. X    @$(ECHO) "    clean      -- remove all intermediate files"
  754. X    @$(ECHO) "    clobber    -- remove all generated files"
  755. X    @$(ECHO) ""
  756. X
  757. Xall install clean clobber:
  758. X    for i in $(SUBDIRS) ; do \
  759. X        ( $(CHDIR) $$i ; $(BUILD) $@ ) ; \
  760. X    done
  761. X
  762. Xprogram:
  763. X    for i in $(PROGDIRS) ; do \
  764. X        ( $(CHDIR) $$i ; $(BUILD) $@ ) ; \
  765. X    done
  766. X
  767. Xlibrary:
  768. X    for i in $(LIBDIRS) ; do \
  769. X        ( $(CHDIR) $$i ; $(BUILD) $@ ) ; \
  770. X    done
  771. X
  772. END_OF_FILE
  773. if test 1278 -ne `wc -c <'src/Makefile'`; then
  774.     echo shar: \"'src/Makefile'\" unpacked with wrong size!
  775. fi
  776. # end of 'src/Makefile'
  777. fi
  778. if test ! -d 'src/cmd' ; then
  779.     echo shar: Creating directory \"'src/cmd'\"
  780.     mkdir 'src/cmd'
  781. fi
  782. if test -f 'src/cmd/Makefile' -a "${1}" != "-c" ; then 
  783.   echo shar: Will not clobber existing file \"'src/cmd/Makefile'\"
  784. else
  785. echo shar: Extracting \"'src/cmd/Makefile'\" \(3253 characters\)
  786. sed "s/^X//" >'src/cmd/Makefile' <<'END_OF_FILE'
  787. X##########################################################################
  788. X## ^FILE: Makefile - make file for the cmdparse program
  789. X##
  790. X## ^DESCRIPTION:
  791. X##    This is the makefile that is used to build and install the "cmdparse"
  792. X##    program. In order to get cmdparse to build on your system you may
  793. X##    need to change some of the "variables" mentioned below. You may also
  794. X##    need to redefine some of the commands that are used.
  795. X##
  796. X## ^TARGETS:
  797. X##    all     : make the cmdparse program
  798. X##    program : same as "all"
  799. X##    install : build and install the cmdparse program
  800. X##    clean   : remove all intermediate files generated by the build
  801. X##    clobber : remove all files generated by the build
  802. X##
  803. X## ^VARIABLES:
  804. X##    OS         : specify the host operating system (default=unix)
  805. X##    FLAG       : debugging/optimization flags to the compiler (default=-g)
  806. X##    TESTDEFS   : #defines used for testing
  807. X##    USRDEFS    : #defines flags used for building (default=unix)
  808. X##    OPTIONS    : any other compiler flags to use
  809. X##
  810. X## ^HISTORY:
  811. X##    04/10/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  812. X###^^#####################################################################
  813. X
  814. Xinclude ../../Config.mk
  815. X
  816. X###
  817. X# operating-system dependent stuff
  818. X###
  819. XOS=unix
  820. X# OSDEFS=$(DEF)$(OS) $(DEF)$(.UNIVERSE)_universe
  821. X
  822. X##
  823. X# Programs
  824. X##
  825. XPROGRAM=$(PROGNAME)$(EXECEXT)
  826. X
  827. X###
  828. X# Program Libraries
  829. X###
  830. XPROGLIB=$(PROGLIBDIR)lib$(LIBNAME)$(LIBEXT)
  831. X
  832. X###
  833. X# compilation options
  834. X###
  835. XINCLUDES=$(INC)$(PROGLIBDIR)
  836. XFLAG=$(OPT)
  837. X# FLAG=$(DBG)
  838. XTESTDEFS=
  839. XUSRDEFS=
  840. XDEFINES=$(OSDEFS) $(USRDEFS) $(TESTDEFS)
  841. XOPTIONS=
  842. XCFLAGS=$(FLAG) $(INCLUDES) $(DEFINES) $(OPTIONS)
  843. X
  844. X###
  845. X# files used
  846. X###
  847. XOBJS= argtypes$(OBJEXT) cmdparse$(OBJEXT) fsm$(OBJEXT) main$(OBJEXT) \
  848. X   quoted$(OBJEXT) shell_arg$(OBJEXT) shells$(OBJEXT) syntax$(OBJEXT)
  849. X
  850. XPROGLIB=$(PROGLIBDIR)libcmdline$(LIBEXT)
  851. X
  852. X###
  853. X# target dependencies
  854. X###
  855. Xall: program
  856. X
  857. Xprogram: library $(PROGRAM)
  858. X
  859. Xlibrary:
  860. X    ( $(CHDIR) $(PROGLIBDIR) ; $(BUILD) $@ ; )
  861. X
  862. X$(PROGRAM): $(OBJS)
  863. X    $(CC) $(EXE)$@ $(OBJS) $(PROGLIB)
  864. X
  865. X###
  866. X# maintenance dependencies
  867. X###
  868. Xinstall: $(PROGRAM) $(BINDIR) $(PROGRAM).pl
  869. X    -$(RM) $(BINDIR)$(PROGRAM) $(PERLLIB)$(PROGRAM).pl $(TCLLIB)$(PROGRAM).tcl
  870. X    $(CP) $(PROGRAM)  $(BINDIR)$(PROGRAM)
  871. X    $(STRIP) $(BINDIR)$(PROGRAM)
  872. X    -$(CP) $(PROGRAM).pl $(PERLLIB)$(PROGRAM).pl
  873. X    -$(CP) $(PROGRAM).tcl $(TCLLIB)$(PROGRAM).tcl
  874. X
  875. Xclean:
  876. X    -$(RM) *$(OBJEXT) core .exrc *~ \#*\#
  877. X
  878. Xclobber: clean
  879. X    -$(RM) *$(LIBEXT) $(PROGRAM) tags TAGS
  880. X
  881. X###
  882. X# object dependencies
  883. X###
  884. Xargtypes$(OBJEXT) : argtypes$(CEXT) argtypes.h shell_arg.h \
  885. X   $(PROGLIBDIR)cmdargs.h $(PROGLIBDIR)cmdline.h shells.h
  886. X
  887. Xcmdparse$(OBJEXT) : cmdparse$(CEXT) argtypes.h shell_arg.h \
  888. X   $(PROGLIBDIR)cmdargs.h $(PROGLIBDIR)cmdline.h shells.h cmdparse.h \
  889. X   syntax.h fsm.h quoted.h
  890. X
  891. Xfsm$(OBJEXT) : fsm$(CEXT) fsm.h
  892. X
  893. Xmain$(OBJEXT) : main$(CEXT) $(PROGLIBDIR)cmdline.h cmdparse.h \
  894. X   $(PROGLIBDIR)cmdargs.h
  895. X
  896. Xquoted$(OBJEXT) : quoted$(CEXT) quoted.h
  897. X
  898. Xshell_arg$(OBJEXT) : shell_arg$(CEXT) shell_arg.h $(PROGLIBDIR)cmdargs.h \
  899. X   $(PROGLIBDIR)cmdline.h shells.h
  900. X
  901. Xshells$(OBJEXT) : shells$(CEXT) $(PROGLIBDIR)fifolist.h shells.h \
  902. X   argtypes.h shell_arg.h $(PROGLIBDIR)cmdargs.h $(PROGLIBDIR)cmdline.h
  903. X
  904. Xsyntax$(OBJEXT) : syntax$(CEXT) $(PROGLIBDIR)cmdline.h syntax.h fsm.h \
  905. X   quoted.h
  906. END_OF_FILE
  907. if test 3253 -ne `wc -c <'src/cmd/Makefile'`; then
  908.     echo shar: \"'src/cmd/Makefile'\" unpacked with wrong size!
  909. fi
  910. # end of 'src/cmd/Makefile'
  911. fi
  912. if test -f 'src/cmd/cmdparse.h' -a "${1}" != "-c" ; then 
  913.   echo shar: Will not clobber existing file \"'src/cmd/cmdparse.h'\"
  914. else
  915. echo shar: Extracting \"'src/cmd/cmdparse.h'\" \(3484 characters\)
  916. sed "s/^X//" >'src/cmd/cmdparse.h' <<'END_OF_FILE'
  917. X//------------------------------------------------------------------------
  918. X// ^FILE: cmdparse.h - define the interface to cmdparse(1)
  919. X//
  920. X// ^DESCRIPTION:
  921. X//    This file defines a class that carries out the services provided
  922. X//    by cmdparse(1).
  923. X//
  924. X// ^HISTORY:
  925. X//    05/01/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  926. X//-^^---------------------------------------------------------------------
  927. X
  928. X#ifndef _cmdparse_h
  929. X#define _cmdparse_h
  930. X
  931. X#include <cmdargs.h>
  932. X
  933. X
  934. X   // Exit values used
  935. Xenum  ExitValues {
  936. X   e_SUCCESS   = 0,      // no errors
  937. X   e_USAGE     = 1,      // no errors - usage printed
  938. X   e_VERSION   = 1,      // no errors - version printed
  939. X   e_CMDSYNTAX = 2,      // command-line syntax error
  940. X   e_BADSHELL  = 3,      // invalid shell specified
  941. X   e_BADDECLS  = 4,      // invalid declaration(s) given
  942. X} ;
  943. X
  944. X
  945. X   // CmdArgVers is a class that simply prints (on cerr) the version
  946. X   // information for this command.
  947. X   //
  948. Xclass  CmdArgVers : public CmdArg {
  949. Xpublic:
  950. X   CmdArgVers(char optchar, const char * keyword, const char * description);
  951. X
  952. X   virtual ~CmdArgVers(void);
  953. X
  954. X   virtual  int
  955. X   operator()(const char * & arg, CmdLine & cmd);
  956. X} ;
  957. X
  958. X
  959. Xclass  istream ;
  960. Xclass  ArgSyntax ;
  961. Xclass  UnixShell ;
  962. Xclass  CmdParseCommand : public CmdLine {
  963. Xpublic:
  964. X
  965. X   CmdParseCommand(const char * name);
  966. X
  967. X   virtual  ~CmdParseCommand(void);
  968. X
  969. X      // Do whatever it is we need to do!
  970. X   int
  971. X   operator()(CmdLineArgIter & iter) ;
  972. X
  973. Xprivate:
  974. X      // Dont allow copying or assignment
  975. X   CmdParseCommand(const CmdParseCommand &);
  976. X   CmdParseCommand & operator=(const CmdParseCommand &);
  977. X
  978. X      // Set the users arguments
  979. X   void
  980. X   set_args(UnixShell * shell);
  981. X
  982. X      // Parse the users argument declarations
  983. X   int
  984. X   parse_declarations(void);
  985. X
  986. X   int
  987. X   parse_declarations(const char * input);
  988. X
  989. X   int
  990. X   parse_declarations(istream & input);
  991. X
  992. X      // Add a parsed declaration to the user's argument list
  993. X   int
  994. X   usr_append(const char * type,
  995. X              const char * varname,
  996. X              ArgSyntax  & arg,
  997. X              const char * description);
  998. X
  999. X   //------------------------------------------------ arguments to cmdparse(1)
  1000. X
  1001. X   CmdArgBool     anywhere;         // clear OPTS_FIRST
  1002. X   CmdArgBool     anycase;          // set ANY_CASE_OPTS
  1003. X   CmdArgBool     no_abort;         // set NO_ABORT
  1004. X   CmdArgBool     no_guessing;      // set NO_GUESSING
  1005. X   CmdArgBool     prompt;           // set PROMPT_USER
  1006. X   CmdArgBool     opts_only;        // set OPTS_ONLY
  1007. X   CmdArgBool     kwds_only;        // set KWDS_ONLY
  1008. X   CmdArgBool     quiet;            // set QUIET
  1009. X
  1010. X   CmdArgVers     version;          // print version and exit
  1011. X   CmdArgBool     usage;            // print usage and exit
  1012. X
  1013. X   CmdArgBool     array_variant;    // use alternate array syntax
  1014. X   CmdArgStr      true_str;         // TRUE for booleans
  1015. X   CmdArgStr      false_str;        // FALSE for booleans
  1016. X   CmdArgStr      suffix_str;       // suffix for missing optional-values
  1017. X   CmdArgStr      usr_shell;        // the shell (command interpreter)
  1018. X
  1019. X   CmdArgStr      input_file;       // read declarations from file
  1020. X   CmdArgStr      input_var;        // read declarations environment variable
  1021. X   CmdArgStr      input_str;        // read declarations from string
  1022. X
  1023. X   CmdArgDummy    dummy_arg;        // "--"
  1024. X
  1025. X   CmdArgStr      usr_prog;         // program name
  1026. X   CmdArgStrList  usr_args;         // program arguments
  1027. X
  1028. X   CmdLine        usr_cmd;          // the user's CmdLine object
  1029. X} ;
  1030. X
  1031. X#endif  /* _cmdparse_h */
  1032. X
  1033. END_OF_FILE
  1034. if test 3484 -ne `wc -c <'src/cmd/cmdparse.h'`; then
  1035.     echo shar: \"'src/cmd/cmdparse.h'\" unpacked with wrong size!
  1036. fi
  1037. # end of 'src/cmd/cmdparse.h'
  1038. fi
  1039. if test -f 'src/cmd/cmdparse.tcl' -a "${1}" != "-c" ; then 
  1040.   echo shar: Will not clobber existing file \"'src/cmd/cmdparse.tcl'\"
  1041. else
  1042. echo shar: Extracting \"'src/cmd/cmdparse.tcl'\" \(3672 characters\)
  1043. sed "s/^X//" >'src/cmd/cmdparse.tcl' <<'END_OF_FILE'
  1044. X#########################################################################
  1045. X# ^FILE: cmdparse.tcl - cmdparse for tcl scripts
  1046. X#
  1047. X# ^DESCRIPTION:
  1048. X#    This file defines a tcl procedure named cmdparse to parse
  1049. X#    command-line arguments for tcl scripts.
  1050. X#
  1051. X# ^HISTORY:
  1052. X#    05/07/92  Brad Appleton   <brad@ssd.csd.harris.com>   Created
  1053. X##^^#####################################################################
  1054. X
  1055. X########
  1056. X# ^PROCEDURE: cmdparse - parse command-line argument lists
  1057. X#
  1058. X# ^SYNOPSIS:
  1059. X#    cmdparse <options> -- $scriptName $list
  1060. X#
  1061. X#        where <options> is any valid option combination for cmdparse(1),
  1062. X#        $scriptName is the name of the user's tcl script (or procedure),
  1063. X#        and $list is a list (which will usually be $argv for scripts, and
  1064. X#        and $args for procedures).
  1065. X#
  1066. X# ^DESCRIPTION:
  1067. X#    Parseargs will invoke cmdparse(1) with the options and arguments
  1068. X#    specified by the caller.
  1069. X#
  1070. X# ^REQUIREMENTS:
  1071. X#    Any desired initial values for variables from the argument-description
  1072. X#    string should be assigned BEFORE calling this procedure.
  1073. X#
  1074. X# ^SIDE-EFFECTS:
  1075. X#    If cmdparse(1) exits with a non-zero status, then execution
  1076. X#    is terminated.
  1077. X#
  1078. X# ^RETURN-VALUE:
  1079. X#    A string of variable settings for the caller to evaluate.
  1080. X#
  1081. X# ^EXAMPLE:
  1082. X#     #!/usr/local/bin/tcl
  1083. X#
  1084. X#     load  "cmdparse.tcl"
  1085. X#
  1086. X#     set arguments {
  1087. X#        ArgStr   string  "[S|Str [string]]"          "optional string arg"
  1088. X#        ArgStr   groups  "[g|groups newsgroups ...]" "newsgroups to test"
  1089. X#        ArgInt   count   "[c|count integer]"         "group repeat count"
  1090. X#        ArgStr   dirname "[d|directory pathname]"    "working directory"
  1091. X#        ArgBool  xflag   "[x|xflag]"                 "turn on x-mode"
  1092. X#        ArgClear yflag   "[y|yflag]"                 "turn off y-mode"
  1093. X#        ArgChar  sepch   "[s|separator char]"        "field separator"
  1094. X#        ArgStr   files   "[f|files filename ...]"    "files to process"
  1095. X#        ArgStr   name    "[n|name] name"             "name to use"
  1096. X#        ArgStr   argv    "[arguments ...]"           "remaining arguments"
  1097. X#     }
  1098. X#
  1099. X#     set count 1 ;    set dirname "." ;   set sepch "," ;
  1100. X#     set xflag 0 ;    set yflag 1 ;
  1101. X#     set files {} ;   set groups {} ;
  1102. X#     set string "" ;
  1103. X#
  1104. X#     eval [ cmdparse -decls $arguments -- $scriptName $argv ]
  1105. X#
  1106. X###^^####
  1107. Xproc cmdparse args {
  1108. X      ## set temp-file name
  1109. X   if {( ! [info exists env(TMP)] )}  { set env(TMP) "/tmp" }
  1110. X   if {( $env(TMP) == "" )}  { set env(TMP) "/tmp" }
  1111. X   set tmpFileName "$env(TMP)/tmp[id process]"
  1112. X
  1113. X       ## isolate the last argument (a list) from the rest
  1114. X   set last [expr {[llength $args] - 1}]
  1115. X   set cmdArgs [lindex $args $last]
  1116. X   set cmdOpts [lrange $args 0 [expr {$last - 1}]]
  1117. X
  1118. X      ## fork and exec
  1119. X   if {( [set childPid [fork]] == 0 )} {
  1120. X         ## This is the child ...
  1121. X         ##    redirect stdout to temp-file and exec cmdparse(1)
  1122. X         ##
  1123. X      set tmpFile [open $tmpFileName "w"]
  1124. X      close stdout
  1125. X      dup $tmpFile stdout
  1126. X      close $tmpFile
  1127. X      execl cmdparse [concat -shell=tcl $cmdOpts $cmdArgs]
  1128. X   } else {
  1129. X         ## This is the parent ...
  1130. X         ##    wait for the child, check its status, then return its output
  1131. X         ##    dont forget to remove the temp-file.
  1132. X         ##
  1133. X      set childStatus [wait $childPid]
  1134. X      set how [lindex $childStatus 1]
  1135. X      set ret [lindex $childStatus 2]
  1136. X      if {( ($how == "EXIT")  &&  ($ret == 0) )} {
  1137. X         set variableSettings [exec cat $tmpFileName]
  1138. X         unlink -nocomplain $tmpFileName
  1139. X         return $variableSettings
  1140. X      } else {
  1141. X         unlink -nocomplain $tmpFileName
  1142. X         exit [expr {$how == "EXIT" ? $ret : 127}]
  1143. X      }
  1144. X   }
  1145. X}
  1146. X
  1147. END_OF_FILE
  1148. if test 3672 -ne `wc -c <'src/cmd/cmdparse.tcl'`; then
  1149.     echo shar: \"'src/cmd/cmdparse.tcl'\" unpacked with wrong size!
  1150. fi
  1151. # end of 'src/cmd/cmdparse.tcl'
  1152. fi
  1153. if test -f 'src/cmd/fsm.h' -a "${1}" != "-c" ; then 
  1154.   echo shar: Will not clobber existing file \"'src/cmd/fsm.h'\"
  1155. else
  1156. echo shar: Extracting \"'src/cmd/fsm.h'\" \(2265 characters\)
  1157. sed "s/^X//" >'src/cmd/fsm.h' <<'END_OF_FILE'
  1158. X//------------------------------------------------------------------------
  1159. X// ^FILE: fsm.h - define a finite state machine
  1160. X//
  1161. X// ^DESCRIPTION:
  1162. X//     This file defines a finite state machine tailored to the task of
  1163. X//     parsing syntax strings for command-line arguments.
  1164. X//
  1165. X// ^HISTORY:
  1166. X//    03/27/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  1167. X//-^^---------------------------------------------------------------------
  1168. X
  1169. Xclass SyntaxFSM {
  1170. Xpublic:
  1171. X   enum state_t {
  1172. X      START,    // start-state
  1173. X      OPTION,   // just parsed an option-spec
  1174. X      KEYWORD,  // just parsed a keyword-spec
  1175. X      VALUE,    // just parsed a value-spec
  1176. X      LIST,     // just parsed "..."
  1177. X      FINAL,    // final-state
  1178. X      ERROR,    // syntax error encountered
  1179. X   } ;
  1180. X
  1181. X   struct token_t {
  1182. X      const char * start;  // start address of token
  1183. X      unsigned     len;    // length of token
  1184. X
  1185. X      token_t(void) : start(0), len(0) {}
  1186. X
  1187. X      void
  1188. X      set(const char * s, unsigned l) { start = s, len = l; }
  1189. X   } ;
  1190. X
  1191. X   SyntaxFSM(void) : ntoks(0), nbpairs(0), lev(0), fsm_state(START) {}
  1192. X
  1193. X      // Reset the FSM 
  1194. X   void
  1195. X   reset(void) { ntoks = 0; nbpairs = 0; lev = 0; fsm_state = START; }
  1196. X
  1197. X      // Return the number of tokens parsed thus far.
  1198. X   unsigned
  1199. X   num_tokens(void) const  { return  ntoks; }
  1200. X
  1201. X      // Return the number of balanced brace-pairs parsed thus far.
  1202. X   unsigned
  1203. X   num_braces(void) const  { return  nbpairs; }
  1204. X
  1205. X      // Return the current nesting level of brace-pairs
  1206. X   int
  1207. X   level(void) const  { return  lev; }
  1208. X
  1209. X      // Return the current machine state
  1210. X   state_t
  1211. X   state(void) const  { return  fsm_state; }
  1212. X
  1213. X      // Get the next token from "input" and place it in "token"
  1214. X      // (consuming characters from "input").
  1215. X      //
  1216. X      // Return 0 if the resulting state is FINAL;
  1217. X      // otherwise return NON-zero.
  1218. X      //
  1219. X   int
  1220. X   operator()(const char * & input, token_t & token);
  1221. X
  1222. Xprotected:
  1223. X   unsigned  ntoks;      // number of tokens parsed thus far
  1224. X   unsigned  nbpairs;    // number of balanced brace-pairs parsed thus far
  1225. X   int       lev;        // current nesting level of brace-pairs
  1226. X   state_t   fsm_state;  // current machine state
  1227. X
  1228. Xprivate:
  1229. X   void
  1230. X   skip(const char * & input);
  1231. X
  1232. X   void
  1233. X   parse_token(const char * & input);
  1234. X} ;
  1235. X
  1236. END_OF_FILE
  1237. if test 2265 -ne `wc -c <'src/cmd/fsm.h'`; then
  1238.     echo shar: \"'src/cmd/fsm.h'\" unpacked with wrong size!
  1239. fi
  1240. # end of 'src/cmd/fsm.h'
  1241. fi
  1242. if test -f 'src/cmd/main.c' -a "${1}" != "-c" ; then 
  1243.   echo shar: Will not clobber existing file \"'src/cmd/main.c'\"
  1244. else
  1245. echo shar: Extracting \"'src/cmd/main.c'\" \(854 characters\)
  1246. sed "s/^X//" >'src/cmd/main.c' <<'END_OF_FILE'
  1247. X//------------------------------------------------------------------------
  1248. X// ^FILE: main.c - main program for cmdparse(1)
  1249. X//
  1250. X// ^DESCRIPTION:
  1251. X//     Instantiate a CmdParseCommand object and let it go do its stuff!
  1252. X//
  1253. X// ^HISTORY:
  1254. X//    05/03/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  1255. X//-^^---------------------------------------------------------------------
  1256. X
  1257. X#include <new.h>
  1258. X#include <iostream.h>
  1259. X#include <stdlib.h>
  1260. X
  1261. X#include "cmdparse.h"
  1262. X
  1263. X//
  1264. X//  cmdparse_new_handler -- allocation error handler for cmdparse(1).
  1265. X//
  1266. Xvoid  cmdparse_new_handler(void)
  1267. X{
  1268. X   cerr << "cmdparse: free-store allocation error." << endl ;
  1269. X   ::exit(127);
  1270. X}
  1271. X
  1272. Xint
  1273. Xmain(int argc, const char * argv[])
  1274. X{
  1275. X   set_new_handler(cmdparse_new_handler);
  1276. X
  1277. X   CmdParseCommand  cmdparse_cmd(*argv);
  1278. X   CmdArgvIter  argv_iter(--argc, ++argv);
  1279. X
  1280. X   return  cmdparse_cmd(argv_iter);
  1281. X}
  1282. X
  1283. END_OF_FILE
  1284. if test 854 -ne `wc -c <'src/cmd/main.c'`; then
  1285.     echo shar: \"'src/cmd/main.c'\" unpacked with wrong size!
  1286. fi
  1287. # end of 'src/cmd/main.c'
  1288. fi
  1289. if test -f 'src/cmd/quoted.h' -a "${1}" != "-c" ; then 
  1290.   echo shar: Will not clobber existing file \"'src/cmd/quoted.h'\"
  1291. else
  1292. echo shar: Extracting \"'src/cmd/quoted.h'\" \(1637 characters\)
  1293. sed "s/^X//" >'src/cmd/quoted.h' <<'END_OF_FILE'
  1294. X//------------------------------------------------------------------------
  1295. X// ^FILE: quoted.h - a class for "quoted" strings
  1296. X//
  1297. X// ^DESCRIPTION:
  1298. X//    This file implements a quoted-string class.  The main purpose of
  1299. X//    this class is the input extraction operator (operator>>) which
  1300. X//    reads a quoted string from input (enclosed in either single or
  1301. X//    double quotes) and places the result (minus containing quotes)
  1302. X//    into a character string.  Single and double quotes may be made part
  1303. X//    of the string be preceding them with a backslash ('\') in the input
  1304. X//    stream.
  1305. X//
  1306. X// ^HISTORY:
  1307. X//    05/01/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  1308. X//-^^---------------------------------------------------------------------
  1309. X
  1310. X#ifndef _quoted_h
  1311. X#define _quoted_h
  1312. X
  1313. Xclass  istream ;
  1314. Xclass  QuotedString {
  1315. Xpublic:
  1316. X      // constructors and destructors
  1317. X   QuotedString(unsigned  max_size);
  1318. X
  1319. X   QuotedString(const char * str);
  1320. X
  1321. X   QuotedString(const char * str, unsigned  max_size);
  1322. X
  1323. X   QuotedString(const QuotedString & qstr);
  1324. X
  1325. X   virtual ~QuotedString(void);
  1326. X
  1327. X      // assignment
  1328. X   QuotedString &
  1329. X   operator=(const QuotedString & qstr);
  1330. X
  1331. X   QuotedString &
  1332. X   operator=(const char * str);
  1333. X
  1334. X      // convert to a string
  1335. X   operator  char*(void) { return  buffer; }
  1336. X
  1337. X      // operator >> reads a quoted string from input.
  1338. X      // If no beginning or ending quote is seen, than
  1339. X      // a message is printed on cerr and the failbit
  1340. X      // of the input stream is set.
  1341. X      //
  1342. X   friend  istream &
  1343. X   operator>>(istream & is, QuotedString & qstr);
  1344. X
  1345. Xprivate:
  1346. X   unsigned  size;
  1347. X   char    * buffer;
  1348. X} ;
  1349. X
  1350. X#endif  /* _quoted_h */
  1351. X
  1352. END_OF_FILE
  1353. if test 1637 -ne `wc -c <'src/cmd/quoted.h'`; then
  1354.     echo shar: \"'src/cmd/quoted.h'\" unpacked with wrong size!
  1355. fi
  1356. # end of 'src/cmd/quoted.h'
  1357. fi
  1358. if test -f 'src/cmd/shell_arg.c' -a "${1}" != "-c" ; then 
  1359.   echo shar: Will not clobber existing file \"'src/cmd/shell_arg.c'\"
  1360. else
  1361. echo shar: Extracting \"'src/cmd/shell_arg.c'\" \(2891 characters\)
  1362. sed "s/^X//" >'src/cmd/shell_arg.c' <<'END_OF_FILE'
  1363. X//------------------------------------------------------------------------
  1364. X// ^FILE: shell_arg.c - implement a shell-script argument
  1365. X//
  1366. X// ^DESCRIPTION:
  1367. X//    This file implements the base class that is used for all
  1368. X//    shell-script command arguments.
  1369. X//
  1370. X// ^HISTORY:
  1371. X//    04/22/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  1372. X//-^^---------------------------------------------------------------------
  1373. X
  1374. X#include <stdlib.h>
  1375. X#include <iostream.h>
  1376. X#include <string.h>
  1377. X#include <ctype.h>
  1378. X
  1379. X#include "shell_arg.h"
  1380. X
  1381. X//----------------------------------------------------------------- initialize
  1382. X
  1383. Xvoid
  1384. XShellCmdArg::initialize(const char * variable_name)
  1385. X{
  1386. X   if (is_array()) {
  1387. X      shell_array = new ShellArray(variable_name) ;
  1388. X   } else {
  1389. X      shell_variable = new ShellVariable(variable_name) ;
  1390. X   }
  1391. X}
  1392. X
  1393. X//---------------------------------------------------------------- constructors
  1394. X
  1395. XShellCmdArg::ShellCmdArg(char    * variable_name,
  1396. X                         char      optchar,
  1397. X                         char    * keyword,
  1398. X                         char    * value,
  1399. X                         char    * description,
  1400. X                         unsigned  syntax_flags)
  1401. X   : CmdArg(optchar, keyword, value, description, syntax_flags),
  1402. X     sca_name(variable_name), sca_keyword(keyword),
  1403. X     sca_value(value), sca_description(description)
  1404. X{
  1405. X   initialize(variable_name);
  1406. X}
  1407. X
  1408. XShellCmdArg::ShellCmdArg(char    * variable_name,
  1409. X                         char      optchar,
  1410. X                         char    * keyword,
  1411. X                         char    * description,
  1412. X                         unsigned  syntax_flags)
  1413. X   : CmdArg(optchar, keyword, description, syntax_flags),
  1414. X     sca_name(variable_name), sca_keyword(keyword),
  1415. X     sca_value(NULL), sca_description(description)
  1416. X{
  1417. X   initialize(variable_name);
  1418. X}
  1419. X
  1420. XShellCmdArg::ShellCmdArg(char    * variable_name,
  1421. X                         char    * value,
  1422. X                         char    * description,
  1423. X                         unsigned  syntax_flags)
  1424. X   : CmdArg(value, description, syntax_flags),
  1425. X     sca_name(variable_name), sca_keyword(NULL),
  1426. X     sca_value(value), sca_description(description)
  1427. X{
  1428. X   initialize(variable_name);
  1429. X}
  1430. X
  1431. X//------------------------------------------------------------------ destructor
  1432. X
  1433. XShellCmdArg::~ShellCmdArg(void)
  1434. X{
  1435. X   if (is_array()) {
  1436. X      delete  shell_array ;
  1437. X   } else {
  1438. X      delete  shell_variable ;
  1439. X   }
  1440. X   delete [] sca_name ;
  1441. X   delete [] sca_keyword ;
  1442. X   delete [] sca_value ;
  1443. X   delete [] sca_description ;
  1444. X}
  1445. X
  1446. X//-------------------------------------------------------------------- is_array
  1447. X
  1448. Xint
  1449. XShellCmdArg::is_array(void) const
  1450. X{
  1451. X   return  (syntax() & CmdArg::isLIST) ;
  1452. X}
  1453. X
  1454. X//------------------------------------------------------------------------- set
  1455. X
  1456. Xvoid
  1457. XShellCmdArg::set(const char * value)
  1458. X{
  1459. X   if (is_array()) {
  1460. X      shell_array->append(value);
  1461. X   } else {
  1462. X      shell_variable->set(value);
  1463. X   }
  1464. X}
  1465. X
  1466. END_OF_FILE
  1467. if test 2891 -ne `wc -c <'src/cmd/shell_arg.c'`; then
  1468.     echo shar: \"'src/cmd/shell_arg.c'\" unpacked with wrong size!
  1469. fi
  1470. # end of 'src/cmd/shell_arg.c'
  1471. fi
  1472. if test -f 'src/cmd/shell_arg.h' -a "${1}" != "-c" ; then 
  1473.   echo shar: Will not clobber existing file \"'src/cmd/shell_arg.h'\"
  1474. else
  1475. echo shar: Extracting \"'src/cmd/shell_arg.h'\" \(2791 characters\)
  1476. sed "s/^X//" >'src/cmd/shell_arg.h' <<'END_OF_FILE'
  1477. X//------------------------------------------------------------------------
  1478. X// ^FILE: shell_arg.h - define a shell-script command-line argument
  1479. X//
  1480. X// ^DESCRIPTION:
  1481. X//    This file defines the base class for all shell-script command
  1482. X//    line arguments.  In addition to inheriting from class CmdArg,
  1483. X//    a ShellCmdArg must also contain a variable-name, and its value.
  1484. X//
  1485. X// ^HISTORY:
  1486. X//    04/22/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  1487. X//-^^---------------------------------------------------------------------
  1488. X
  1489. X#ifndef  _shell_arg_h
  1490. X#define  _shell_arg_h
  1491. X
  1492. X#include  <cmdargs.h>
  1493. X
  1494. X#include  "shells.h"
  1495. X
  1496. X   // All of our shell-script args will be ShellCmdArgs with two possible
  1497. X   // exceptions:
  1498. X   //   1) We may have a CmdArgUsage or
  1499. X   //   2) CmdArg::is_dummy() may return TRUE
  1500. X   //
  1501. X   // Hence, before we can downcast a CmdArg * to a ShellCmdArg *
  1502. X   // we must first make sure of the following:
  1503. X   //   1) is_dummy returns FALSE and that
  1504. X   //   2) CmdArg::GIVEN is set (if a CmdArgUsage was given then we would have
  1505. X   //      already exited!).
  1506. X   //
  1507. X
  1508. Xclass  ShellCmdArg : public CmdArg {
  1509. Xpublic:
  1510. X   ShellCmdArg(char    * variable_name,
  1511. X               char      optchar,
  1512. X               char    * keyword,
  1513. X               char    * value,
  1514. X               char    * description,
  1515. X               unsigned  syntax_flags =CmdArg::isOPTVALREQ);
  1516. X
  1517. X   ShellCmdArg(char    * variable_name,
  1518. X               char      optchar,
  1519. X               char    * keyword,
  1520. X               char    * description,
  1521. X               unsigned  syntax_flags =CmdArg::isOPT);
  1522. X
  1523. X   ShellCmdArg(char    * variable_name,
  1524. X               char    * value,
  1525. X               char    * description,
  1526. X               unsigned  syntax_flags =CmdArg::isPOSVALREQ);
  1527. X
  1528. X   virtual ~ShellCmdArg(void);
  1529. X
  1530. X      // Return the name of this variable/array
  1531. X   const char *
  1532. X   name(void) const { return  sca_name; }
  1533. X
  1534. X      // Are we an array or a variable?
  1535. X   int
  1536. X   is_array(void) const;
  1537. X
  1538. X      // Return the variable portion
  1539. X   ShellVariable &
  1540. X   variable(void)  { return  *shell_variable; }
  1541. X
  1542. X      // Return the array portion
  1543. X   ShellArray &
  1544. X   array(void)  { return  *shell_array; }
  1545. X
  1546. X      // If we are a variable then the "set" member function sets the
  1547. X      // value of the variable, otherwise it appends to the list of
  1548. X      // values of the array
  1549. X      //
  1550. X   void
  1551. X   set(const char * value);
  1552. X
  1553. X   virtual  int
  1554. X   operator()(const char * & arg, CmdLine & cmd) = 0;
  1555. X
  1556. Xprivate:
  1557. X   ShellCmdArg(const ShellCmdArg & cp);
  1558. X
  1559. X   ShellCmdArg &
  1560. X   operator=(const ShellCmdArg & cp);
  1561. X
  1562. X   void
  1563. X   initialize(const char * name);
  1564. X
  1565. X   union { 
  1566. X      ShellVariable *  shell_variable;
  1567. X      ShellArray    *  shell_array;
  1568. X   } ;
  1569. X
  1570. X   char * sca_name;
  1571. X   char * sca_keyword;
  1572. X   char * sca_value;
  1573. X   char * sca_description;
  1574. X} ;
  1575. X
  1576. X#endif  /* _shell_arg_h */
  1577. X
  1578. END_OF_FILE
  1579. if test 2791 -ne `wc -c <'src/cmd/shell_arg.h'`; then
  1580.     echo shar: \"'src/cmd/shell_arg.h'\" unpacked with wrong size!
  1581. fi
  1582. # end of 'src/cmd/shell_arg.h'
  1583. fi
  1584. if test -f 'src/cmd/syntax.h' -a "${1}" != "-c" ; then 
  1585.   echo shar: Will not clobber existing file \"'src/cmd/syntax.h'\"
  1586. else
  1587. echo shar: Extracting \"'src/cmd/syntax.h'\" \(1455 characters\)
  1588. sed "s/^X//" >'src/cmd/syntax.h' <<'END_OF_FILE'
  1589. X//------------------------------------------------------------------------
  1590. X// ^FILE: syntax.h - define an object to represent the syntax of a
  1591. X//                   command-line argument.
  1592. X//
  1593. X// ^DESCRIPTION:
  1594. X//    This file defines an object that parses and records the syntax of
  1595. X//    a command-line argument.
  1596. X//
  1597. X// ^HISTORY:
  1598. X//    04/29/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  1599. X//-^^---------------------------------------------------------------------
  1600. X
  1601. X#ifndef _syntax_h
  1602. X#define _syntax_h
  1603. X
  1604. X#include  "fsm.h"
  1605. X
  1606. Xclass  istream;
  1607. Xclass  ArgSyntax {
  1608. Xpublic:
  1609. X   ArgSyntax(void)
  1610. X      : arg_syntax(0), arg_char(0), arg_keyword(0), arg_value(0)
  1611. X      {}
  1612. X
  1613. X      // Return the syntax flags
  1614. X   unsigned
  1615. X   syntax(void) const { return  arg_syntax; }
  1616. X
  1617. X      // Return the option character
  1618. X   char
  1619. X   optchar(void) const { return  arg_char; }
  1620. X
  1621. X      // Return the keyword name
  1622. X   const char *
  1623. X   keyword(void) const { return  arg_keyword; }
  1624. X
  1625. X      // Return the value name
  1626. X   const char *
  1627. X   value(void) const { return  arg_value; }
  1628. X
  1629. X      // Extract the syntax (compile it) from an input stream
  1630. X   friend  istream &
  1631. X   operator>>(istream & is, ArgSyntax & arg);
  1632. X
  1633. Xprivate:
  1634. X   unsigned     arg_syntax ;
  1635. X   char         arg_char;
  1636. X   const char * arg_keyword;
  1637. X   const char * arg_value;
  1638. X
  1639. Xprivate:
  1640. X   int
  1641. X   parse_syntax(const char * syntax);
  1642. X
  1643. X   void
  1644. X   parse_value(const SyntaxFSM & fsm);
  1645. X
  1646. X   istream &
  1647. X   parse_flag(istream & is);
  1648. X} ;
  1649. X
  1650. X#endif  /* _syntax_h */
  1651. END_OF_FILE
  1652. if test 1455 -ne `wc -c <'src/cmd/syntax.h'`; then
  1653.     echo shar: \"'src/cmd/syntax.h'\" unpacked with wrong size!
  1654. fi
  1655. # end of 'src/cmd/syntax.h'
  1656. fi
  1657. if test ! -d 'src/lib' ; then
  1658.     echo shar: Creating directory \"'src/lib'\"
  1659.     mkdir 'src/lib'
  1660. fi
  1661. if test -f 'src/lib/Makefile' -a "${1}" != "-c" ; then 
  1662.   echo shar: Will not clobber existing file \"'src/lib/Makefile'\"
  1663. else
  1664. echo shar: Extracting \"'src/lib/Makefile'\" \(3443 characters\)
  1665. sed "s/^X//" >'src/lib/Makefile' <<'END_OF_FILE'
  1666. X##########################################################################
  1667. X## ^FILE: Makefile - make file for the CmdLine C++ library
  1668. X##
  1669. X## ^DESCRIPTION:
  1670. X##    This is the makefile that is used to build and install the CmdLine
  1671. X##    library. In order to get CmdLine to build on your system you may
  1672. X##    need to change some of the "variables" mentioned below. You may also
  1673. X##    need to redefine some of the commands that are used.
  1674. X##
  1675. X## ^TARGETS:
  1676. X##    all     : make the library and the test program
  1677. X##    library : make the library
  1678. X##    test    : make the test program
  1679. X##    install : build and install the library and its include files
  1680. X##    clean   : remove all intermediate files generated by the build
  1681. X##    clobber : remove all files generated by the build
  1682. X##
  1683. X## ^VARIABLES:
  1684. X##    OS         : specify the host operating system (default=unix)
  1685. X##    STYLE      : specify the desired command-line syntax (default=unix)
  1686. X##    FLAG       : debugging/optimization flags to the compiler (default=-g)
  1687. X##    TESTDEFS   : #defines used for testing
  1688. X##    USRDEFS    : #defines used for building (default=unix)
  1689. X##    OPTIONS    : any other compiler flags to use
  1690. X##
  1691. X## ^HISTORY:
  1692. X##    04/10/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  1693. X###^^#####################################################################
  1694. X
  1695. Xinclude ../../Config.mk
  1696. X
  1697. X###
  1698. X# operating-system dependent stuff
  1699. X###
  1700. X# OSDEFS=$(DEF)$(OS) $(DEF)$(.UNIVERSE)_universe
  1701. XSTYLE=$(OS)
  1702. X
  1703. X###
  1704. X# compilation options
  1705. X###
  1706. XINCLUDES=$(INC)$(CURDIR)
  1707. XFLAG=$(OPT)
  1708. X# FLAG=$(DBG)
  1709. XTESTDEFS=
  1710. X# USRDEFS=$(DEF)DEBUG_CMDLINE
  1711. XDEFINES=$(OSDEFS) $(USRDEFS) $(TESTDEFS) $(DEF)$(STYLE)_style
  1712. XOPTIONS=
  1713. XCFLAGS=$(FLAG) $(INCLUDES) $(DEFINES) $(OPTIONS)
  1714. X
  1715. X###
  1716. X# libraries
  1717. X###
  1718. XLIBRARY=lib$(LIBNAME)$(LIBEXT)
  1719. X
  1720. X###
  1721. X# files used
  1722. X###
  1723. XOBJS=argiter$(OBJEXT) cmdarg$(OBJEXT) cmdargs$(OBJEXT) \
  1724. X   cmdline$(OBJEXT) dump$(OBJEXT)  fifolist$(OBJEXT) \
  1725. X   parse$(OBJEXT) patchlevel$(OBJEXT) private$(OBJEXT) \
  1726. X   strindent$(OBJEXT) $(STYLE)$(OBJEXT) usage$(OBJEXT)
  1727. X
  1728. X###
  1729. X# target dependencies
  1730. X###
  1731. Xall: library test
  1732. X
  1733. Xlibrary: $(LIBRARY)
  1734. X
  1735. Xtest: cmdtest$(EXECEXT)
  1736. X
  1737. Xcmdtest$(EXECEXT): cmdtest$(OBJEXT) $(OBJS)
  1738. X    $(CC) $(EXE)$@ cmdtest$(OBJEXT) $(LIBRARY)
  1739. X
  1740. X$(LIBRARY): $(OBJS)
  1741. X    $(AR) $@ $(OBJS)
  1742. X    $(RANLIB) $@
  1743. X
  1744. X###
  1745. X# maintenance dependencies
  1746. X###
  1747. Xinstall: $(LIBRARY) $(LIBDIR) $(INCDIR) cmdline.h cmdargs.h
  1748. X    -$(RM) $(LIBDIR)$(LIBRARY) $(INCDIR)cmdline.h $(INCDIR)cmdargs.h
  1749. X    $(CP) $(LIBRARY) $(LIBDIR)$(LIBRARY)
  1750. X    $(CP) cmdline.h $(INCDIR)cmdline.h
  1751. X    $(CP) cmdargs.h $(INCDIR)cmdargs.h
  1752. X
  1753. Xclean:
  1754. X    -$(RM) *$(OBJEXT) core .exrc *~ \#*\#
  1755. X
  1756. Xclobber: clean
  1757. X    -$(RM) *$(LIBEXT) cmdtest tags TAGS
  1758. X
  1759. X###
  1760. X# object dependencies
  1761. X###
  1762. Xargiter$(OBJEXT) : argiter$(CEXT) cmdline.h
  1763. X
  1764. Xcmdarg$(OBJEXT) : cmdarg$(CEXT) cmdline.h
  1765. X
  1766. Xcmdargs$(OBJEXT) : cmdargs$(CEXT) cmdargs.h cmdline.h exits.h fifolist.h
  1767. X
  1768. Xcmdline$(OBJEXT) : cmdline$(CEXT) cmdline.h cmdargs.h arglist.h fifolist.h \
  1769. X   states.h
  1770. X
  1771. Xcmdtest$(OBJEXT) : cmdtest$(CEXT) cmdargs.h cmdline.h
  1772. X
  1773. Xdump$(OBJEXT) : dump$(CEXT) cmdline.h arglist.h fifolist.h states.h
  1774. X
  1775. Xfifolist$(OBJEXT) : fifolist$(CEXT) cmdline.h fifolist.h
  1776. X
  1777. Xparse$(OBJEXT) : parse$(CEXT) exits.h states.h cmdline.h arglist.h \
  1778. X   fifolist.h
  1779. X
  1780. Xpatchlevel$(OBJEXT) : patchlevel$(CEXT) cmdline.h
  1781. X
  1782. Xprivate$(OBJEXT) : private$(CEXT) cmdline.h states.h arglist.h fifolist.h
  1783. X
  1784. Xstrindent$(OBJEXT) : strindent$(CEXT) cmdline.h
  1785. X
  1786. Xunix$(OBJEXT) : unix$(CEXT) exits.h cmdline.h states.h
  1787. X
  1788. Xusage$(OBJEXT) : usage$(CEXT) cmdline.h states.h arglist.h fifolist.h
  1789. END_OF_FILE
  1790. if test 3443 -ne `wc -c <'src/lib/Makefile'`; then
  1791.     echo shar: \"'src/lib/Makefile'\" unpacked with wrong size!
  1792. fi
  1793. # end of 'src/lib/Makefile'
  1794. fi
  1795. if test -f 'src/lib/arglist.h' -a "${1}" != "-c" ; then 
  1796.   echo shar: Will not clobber existing file \"'src/lib/arglist.h'\"
  1797. else
  1798. echo shar: Extracting \"'src/lib/arglist.h'\" \(834 characters\)
  1799. sed "s/^X//" >'src/lib/arglist.h' <<'END_OF_FILE'
  1800. X//------------------------------------------------------------------------
  1801. X// ^FILE: arglist.h - lists to hold CmdArgs
  1802. X//
  1803. X// ^DESCRIPTION:
  1804. X//   This file declares the types that are used by a CmdLine to hold the
  1805. X//   arguments associated with it.  What we do is keep a list of lists
  1806. X//   of CmdArgs. The first list is the arguments that were specified
  1807. X//   by the user/programmer, The second list is the list of default
  1808. X//   arguments for this command. Only two lists are used at present.
  1809. X//
  1810. X// ^HISTORY:
  1811. X//    03/21/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  1812. X//-^^---------------------------------------------------------------------
  1813. X
  1814. X#ifndef _arglist_h
  1815. X#define _arglist_h
  1816. X
  1817. X#include "fifolist.h"
  1818. X
  1819. Xclass CmdArg;
  1820. X
  1821. XDECLARE_FIFO_LIST(CmdArgList, CmdArg);
  1822. X
  1823. XDECLARE_FIFO_LIST(CmdArgListList, CmdArgList);
  1824. X
  1825. X#endif /* _arglist_h */
  1826. X
  1827. END_OF_FILE
  1828. if test 834 -ne `wc -c <'src/lib/arglist.h'`; then
  1829.     echo shar: \"'src/lib/arglist.h'\" unpacked with wrong size!
  1830. fi
  1831. # end of 'src/lib/arglist.h'
  1832. fi
  1833. if test -f 'src/lib/exits.h' -a "${1}" != "-c" ; then 
  1834.   echo shar: Will not clobber existing file \"'src/lib/exits.h'\"
  1835. else
  1836. echo shar: Extracting \"'src/lib/exits.h'\" \(1075 characters\)
  1837. sed "s/^X//" >'src/lib/exits.h' <<'END_OF_FILE'
  1838. X//------------------------------------------------------------------------
  1839. X// ^FILE: exits.h - define exit codes used by the CmdLine library
  1840. X//
  1841. X// ^DESCRIPTION:
  1842. X//    When we call exit(3C), we want to use a value that is appropriate
  1843. X//    for the operating system that we are on.  Here are the values
  1844. X//    that we need to define:
  1845. X//
  1846. X//       e_SUCCESS  -- no errors everything is fine
  1847. X//       e_USAGE    -- no errors but we didnt parse the command-line
  1848. X//                     because we saw a CmdArgUsage argument
  1849. X//       e_SYNTAX   -- a syntax error occurred
  1850. X//       e_INTERNAL -- an internal error occurred
  1851. X//
  1852. X// ^HISTORY:
  1853. X//    04/13/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  1854. X//-^^---------------------------------------------------------------------
  1855. X
  1856. X#ifndef e_SUCCESS
  1857. X
  1858. X#ifdef vms
  1859. X# include <ssdef.h>
  1860. X# define  e_SUCCESS   SS$_NORMAL
  1861. X# define  e_USAGE     SS$_NOTMODIFIED
  1862. X# define  e_SYNTAX    SS$_BADPRAM
  1863. X# define  e_INTERNAL  SS$_CANCEL
  1864. X#else
  1865. X# define  e_SUCCESS   0
  1866. X# define  e_USAGE     1
  1867. X# define  e_SYNTAX    2
  1868. X# define  e_INTERNAL  127
  1869. X#endif
  1870. X
  1871. X#endif
  1872. END_OF_FILE
  1873. if test 1075 -ne `wc -c <'src/lib/exits.h'`; then
  1874.     echo shar: \"'src/lib/exits.h'\" unpacked with wrong size!
  1875. fi
  1876. # end of 'src/lib/exits.h'
  1877. fi
  1878. if test -f 'src/lib/fifolist.c' -a "${1}" != "-c" ; then 
  1879.   echo shar: Will not clobber existing file \"'src/lib/fifolist.c'\"
  1880. else
  1881. echo shar: Extracting \"'src/lib/fifolist.c'\" \(3127 characters\)
  1882. sed "s/^X//" >'src/lib/fifolist.c' <<'END_OF_FILE'
  1883. X//------------------------------------------------------------------------
  1884. X// ^FILE: fifolist.c - implementation of FIFO linked lists
  1885. X//
  1886. X// ^DESCRIPTION:
  1887. X//    This file implements the classes declared in fifolist.h
  1888. X//
  1889. X// ^HISTORY:
  1890. X//    03/21/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  1891. X//-^^---------------------------------------------------------------------
  1892. X
  1893. X#include <stdlib.h>
  1894. X#include "cmdline.h"
  1895. X#include "fifolist.h"
  1896. X
  1897. X//------------------------------------------------------------- GenericFifoList
  1898. X
  1899. X   // Destructor
  1900. XGenericFifoList::~GenericFifoList(void) {
  1901. X   GenericFifoListNode * nd = head;
  1902. X   head = NULL;
  1903. X   while (nd) {
  1904. X      GenericFifoListNode * to_delete = nd;
  1905. X      nd = nd->next;
  1906. X      if (del_items)  delete  to_delete->contents;
  1907. X      delete  to_delete;
  1908. X   }
  1909. X}
  1910. X
  1911. X   // Add an item to the end
  1912. Xvoid
  1913. XGenericFifoList::add(void * item) {
  1914. X   if (item) {
  1915. X      GenericFifoListNode * nd = new GenericFifoListNode(NULL, item);
  1916. X      if (head == NULL) {
  1917. X         head = tail = nd;
  1918. X      } else {
  1919. X         tail->next = nd;
  1920. X         tail = nd;
  1921. X      }
  1922. X      ++num_items;
  1923. X      mod = 1;
  1924. X   }
  1925. X}
  1926. X
  1927. X   // Remove an item off the front
  1928. Xvoid *
  1929. XGenericFifoList::remove(void) {
  1930. X   if (head == NULL)  return  NULL;
  1931. X   GenericFifoListNode * nd = head;
  1932. X   void * result = head->contents;
  1933. X   head = head->next;
  1934. X   delete  nd;
  1935. X   --num_items;
  1936. X   mod = 1;
  1937. X   return  result;
  1938. X}
  1939. X
  1940. X//--------------------------------------------------------- GenericFifoListIter
  1941. X
  1942. XGenericFifoListIter::~GenericFifoListIter(void) {}
  1943. X
  1944. Xvoid *
  1945. XGenericFifoListIter::operator()(void) {
  1946. X   void * result = NULL;
  1947. X   if (current) {
  1948. X      result  = current->contents;
  1949. X      current = current->next;
  1950. X   }
  1951. X   return  result;
  1952. X}
  1953. X
  1954. X//-------------------------------------------------------- GenericFifoListArray
  1955. X
  1956. XGenericFifoListArray::~GenericFifoListArray(void) {}
  1957. X
  1958. Xvoid *
  1959. XGenericFifoListArray::operator[](unsigned  ndx) {
  1960. X   unsigned  max_index = count();
  1961. X   if (! max_index--)  return  NULL;     // check for underflow
  1962. X   if (ndx > max_index)  return  NULL;  // check for overflow
  1963. X
  1964. X   // if we want the first element -- just return the head
  1965. X   if (ndx == 0)  return  list.head->contents;
  1966. X
  1967. X   // if we want the last element -- just return the tail
  1968. X   if (ndx == max_index)  return  list.tail->contents;
  1969. X
  1970. X   // If we are going backward or stuff has been modified, then rewind
  1971. X   if ((ndx < index) || list.modified()) {
  1972. X      index = 0;
  1973. X      current = list.head;
  1974. X   }
  1975. X
  1976. X   // Skip from current to the desired element
  1977. X   while (index < ndx) {
  1978. X      current = current->next;
  1979. X      ++index;
  1980. X   }
  1981. X
  1982. X   return  current->contents;
  1983. X}
  1984. X
  1985. X//-------------------------------------------------------------------- FifoList
  1986. X
  1987. X#ifdef TEMPLATES
  1988. X
  1989. X   // Destructor
  1990. Xtemplate <class Type>
  1991. XFifoList<Type>::~FifoList(void) {
  1992. X   GenericFifoListNode * nd = head;
  1993. X   head = NULL;
  1994. X   while (nd) {
  1995. X      GenericFifoListNode * to_delete = nd;
  1996. X      nd = nd->next;
  1997. X      if (del_items)  delete (Type *)to_delete->contents;
  1998. X      delete  to_delete;
  1999. X   }
  2000. X}
  2001. X
  2002. Xtemplate <class Type>
  2003. XFifoListIter<Type>::~FifoListIter(void) {}
  2004. X
  2005. Xtemplate <class Type>
  2006. XFifoListArray<Type>::~FifoListArray(void) {}
  2007. X
  2008. X#endif
  2009. END_OF_FILE
  2010. if test 3127 -ne `wc -c <'src/lib/fifolist.c'`; then
  2011.     echo shar: \"'src/lib/fifolist.c'\" unpacked with wrong size!
  2012. fi
  2013. # end of 'src/lib/fifolist.c'
  2014. fi
  2015. if test -f 'src/lib/patchlevel.c' -a "${1}" != "-c" ; then 
  2016.   echo shar: Will not clobber existing file \"'src/lib/patchlevel.c'\"
  2017. else
  2018. echo shar: Extracting \"'src/lib/patchlevel.c'\" \(1335 characters\)
  2019. sed "s/^X//" >'src/lib/patchlevel.c' <<'END_OF_FILE'
  2020. X//------------------------------------------------------------------------
  2021. X// ^FILE: patchlevel.c - version specific information
  2022. X//
  2023. X// ^DESCRIPTION:
  2024. X//    This file contains all the version specific information of this
  2025. X//    particular release of the CmdLine library.  It also implements
  2026. X//    the static member functions of a CmdLine that return version
  2027. X//    specific information.
  2028. X//
  2029. X// ^HISTORY:
  2030. X//    04/03/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  2031. X//-^^---------------------------------------------------------------------
  2032. X
  2033. X#include "cmdline.h"
  2034. X
  2035. X   // Record the version-identifier for this project.
  2036. X   //
  2037. X   // My source-code management system lets me use a symbolic-name
  2038. X   // to identify a given configuration of the project. From this
  2039. X   // symbolic-name I can easily find out the exact version of each
  2040. X   // file that makes up this version of the project.
  2041. X   //
  2042. Xstatic const char ident[] =
  2043. X   "@(#)SMS  task: cmdline-1.00" ;
  2044. X
  2045. X
  2046. X   // Release and patchlevel information
  2047. X#define  CMDLINE_RELEASE     1
  2048. X#define  CMDLINE_PATCHLEVEL  0
  2049. X#define  CMDLINE_IDENT       "@(#)CmdLine    1.00"
  2050. X
  2051. Xunsigned
  2052. XCmdLine::release(void)  { return  CMDLINE_RELEASE; }
  2053. X
  2054. Xunsigned
  2055. XCmdLine::patchlevel(void)  { return  CMDLINE_PATCHLEVEL; }
  2056. X
  2057. Xconst char *
  2058. XCmdLine::ident(void) {
  2059. X   static const char Ident[] = CMDLINE_IDENT ;
  2060. X
  2061. X   return  Ident;
  2062. X}
  2063. X
  2064. END_OF_FILE
  2065. if test 1335 -ne `wc -c <'src/lib/patchlevel.c'`; then
  2066.     echo shar: \"'src/lib/patchlevel.c'\" unpacked with wrong size!
  2067. fi
  2068. # end of 'src/lib/patchlevel.c'
  2069. fi
  2070. if test -f 'src/lib/states.h' -a "${1}" != "-c" ; then 
  2071.   echo shar: Will not clobber existing file \"'src/lib/states.h'\"
  2072. else
  2073. echo shar: Extracting \"'src/lib/states.h'\" \(2443 characters\)
  2074. sed "s/^X//" >'src/lib/states.h' <<'END_OF_FILE'
  2075. X//------------------------------------------------------------------------
  2076. X// ^FILE: states.h - state definitions for the CmdLine library
  2077. X//
  2078. X// ^DESCRIPTION:
  2079. X//     This file contains the definitions for the various values of the
  2080. X//  state and parse-state of a command-line object. It also contains
  2081. X//  any definitions that are dependent upon the command-line syntax
  2082. X//  (i.e. unix_style or vms_style).
  2083. X//
  2084. X// ^HISTORY:
  2085. X//    03/26/92    Brad Appleton    <brad@ssd.csd.harris.com>    Created
  2086. X//-^^---------------------------------------------------------------------
  2087. X
  2088. X#ifndef _states_h
  2089. X#define _states_h
  2090. X
  2091. X#include "cmdline.h"
  2092. X
  2093. X#ifdef unix_style
  2094. X   // Default command-flags for a unix-command
  2095. X   static const unsigned DEFAULT_CMDFLAGS = CmdLine::OPTS_FIRST ;
  2096. X#endif
  2097. X
  2098. X#ifdef vms_style
  2099. X   // Default command-flags for a vms-command
  2100. X   static const unsigned DEFAULT_CMDFLAGS = CmdLine::TEMP ;
  2101. X#endif
  2102. X
  2103. X//
  2104. X// cmd_state_t -- Define the bitmasks used to record the command state
  2105. X//
  2106. Xenum cmd_state_t {
  2107. X   cmd_END_OF_OPTIONS  = 0x01,  // no more options/keywords?
  2108. X   cmd_OPTIONS_USED    = 0x02,  // were options used on cmdline?
  2109. X   cmd_KEYWORDS_USED   = 0x04,  // were keywords used on cmdline?
  2110. X   cmd_GUESSING        = 0x08,  // are we currently trying to guess?
  2111. X} ;
  2112. X
  2113. X//
  2114. X// cmd_parse_state_t -- Define the possible parse-states for the command
  2115. X//
  2116. X// We use "START_STATE" to reset the state. Only one of the NEED*
  2117. X// states may be set at a time. For any of the NEED* states, TOK_REQUIRED
  2118. X// may or may not be set. TOK_REQUIRED should NOT be set if none of the
  2119. X// NEED* states is set.
  2120. X//
  2121. X// Note: we have the "states" set up so that one can test for WANT or NEED
  2122. X// by a bitwise & with a WANT flag. One can test if the particular "WANT"
  2123. X// is truly "NEEDED" by a bitwise & with the TOK_REQUIRED_FLAG. For
  2124. X// convenience, each WANT_XXX that is truly REQUIRED may also be
  2125. X// represented by NEED_XXX.
  2126. X//
  2127. Xenum cmd_parse_state_t {
  2128. X   cmd_START_STATE  = 0x00,  // start-state (this MUST be 0)
  2129. X
  2130. X   cmd_TOK_REQUIRED = 0x01,  // is the "wanted" token required?
  2131. X
  2132. X   cmd_WANT_VAL     = 0x02,  // are we expecting a value?
  2133. X   cmd_NEED_VAL     = (cmd_WANT_VAL | cmd_TOK_REQUIRED),
  2134. X
  2135. X#ifdef vms_style
  2136. X   cmd_WANT_VALSEP  = 0x04,  // are we expecting ':' or '='
  2137. X   cmd_NEED_VALSEP  = (cmd_WANT_VALSEP | cmd_TOK_REQUIRED),
  2138. X
  2139. X   cmd_WANT_LISTSEP = 0x08,  // are we expecting ',' or '+'
  2140. X   cmd_NEED_LISTSEP = (cmd_WANT_LISTSEP | cmd_TOK_REQUIRED),
  2141. X#endif
  2142. X} ;
  2143. X
  2144. X
  2145. X#endif /* _states_h */
  2146. END_OF_FILE
  2147. if test 2443 -ne `wc -c <'src/lib/states.h'`; then
  2148.     echo shar: \"'src/lib/states.h'\" unpacked with wrong size!
  2149. fi
  2150. # end of 'src/lib/states.h'
  2151. fi
  2152. echo shar: End of archive 1 \(of 7\).
  2153. cp /dev/null ark1isdone
  2154. MISSING=""
  2155. for I in 1 2 3 4 5 6 7 ; do
  2156.     if test ! -f ark${I}isdone ; then
  2157.     MISSING="${MISSING} ${I}"
  2158.     fi
  2159. done
  2160. if test "${MISSING}" = "" ; then
  2161.     echo You have unpacked all 7 archives.
  2162.     rm -f ark[1-9]isdone
  2163. else
  2164.     echo You still need to unpack the following archives:
  2165.     echo "        " ${MISSING}
  2166. fi
  2167. ##  End of shell archive.
  2168. exit 0
  2169.  
  2170. exit 0 # Just in case...
  2171.