v17i046: parseargs - functions to parse command line arguments, Part01/12

Brad Appleton brad at hcx1.ssd.csd.harris.com
Mon Mar 18 06:05:28 AEST 1991


Submitted-by: Brad Appleton <brad at hcx1.ssd.csd.harris.com>
Posting-number: Volume 17, Issue 46
Archive-name: parseargs/part01

This is part 1 of parseargs

#!/bin/sh
# This is a shell archive (produced by shar 3.49)
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
#
# made 03/16/1991 21:25 UTC by kent at sparky.IMD.Sterling.COM
# Source directory /u1/csm/queue/parseargs
#
# existing files will NOT be overwritten unless -c is specified
#
# This is part 1 of a multipart archive                                    
# do not concatenate these parts, unpack them in order with /bin/sh        
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#   5018 -rw-rw-r-- parseargs/Intro
#   4033 -rw-rw-r-- parseargs/MANIFEST
#   4516 -rw-rw-r-- parseargs/Makefile
#   7778 -rw-rw-r-- parseargs/Makefile.cpp
#  41278 -rw-rw-r-- parseargs/README
#  16890 -rw-rw-r-- parseargs/amiga_args.c
#   5961 -rw-rw-r-- parseargs/arglist.c
#  22590 -rw-rw-r-- parseargs/argtype.c
#   7427 -rw-rw-r-- parseargs/argtype3.txt
#   2300 -rw-rw-r-- parseargs/doc/Makefile
#   3591 -rw-rw-r-- parseargs/doc/arg_macros.inc
#   3543 -rw-rw-r-- parseargs/doc/argdesc.inc
#   5228 -rw-rw-r-- parseargs/doc/argflags.inc
#   7204 -rw-rw-r-- parseargs/doc/argtype.man3
#   1216 -rw-rw-r-- parseargs/doc/argvalopt.inc
#   2103 -rw-rw-r-- parseargs/doc/bugs.inc
#   1768 -rw-rw-r-- parseargs/doc/caveats.inc
#   1627 -rw-rw-r-- parseargs/doc/cmd_macros.inc
#   1093 -rw-rw-r-- parseargs/doc/defargs.inc
#   1979 -rw-rw-r-- parseargs/doc/env_args.inc
#   3224 -rw-rw-r-- parseargs/doc/env_parse.inc
#   2820 -rw-rw-r-- parseargs/doc/env_usage.inc
#    937 -rw-rw-r-- parseargs/doc/fparseargs3.inc
#   1101 -rw-rw-r-- parseargs/doc/lib_bugs.inc
#    428 -rw-rw-r-- parseargs/doc/lparseargs3.inc
#   4932 -rw-rw-r-- parseargs/doc/multivals.inc
#  12151 -rw-rw-r-- parseargs/doc/parseargs.man1
#   9554 -rw-rw-r-- parseargs/doc/parseargs.man3
#   1461 -rw-rw-r-- parseargs/doc/parseargs1.inc
#    642 -rw-rw-r-- parseargs/doc/parseargs3.inc
#    974 -rw-rw-r-- parseargs/doc/parsecntl.man3
#   1721 -rw-rw-r-- parseargs/doc/parsecntl3.inc
#   4875 -rw-rw-r-- parseargs/doc/parsecntls.inc
#   5108 -rw-rw-r-- parseargs/doc/parseflags.inc
#   1427 -rw-rw-r-- parseargs/doc/parsemodes.inc
#   2118 -rw-rw-r-- parseargs/doc/returns.inc
#   6926 -rw-rw-r-- parseargs/doc/sh_arrays.inc
#   2275 -rw-rw-r-- parseargs/doc/shells.inc
#    836 -rw-rw-r-- parseargs/doc/sparseargs3.inc
#    449 -rw-rw-r-- parseargs/doc/usage3.inc
#    737 -rw-rw-r-- parseargs/doc/vparseargs3.inc
#  23858 -rw-rw-r-- parseargs/ibm_args.c
#   6648 -rw-rw-r-- parseargs/parseargs.awk
#  70264 -rw-rw-r-- parseargs/parseargs.c
#  42981 -rw-rw-r-- parseargs/parseargs.h
#   2311 -rwxrwxr-x parseargs/parseargs.pl
#  33378 -rw-rw-r-- parseargs/parseargs1.txt
#  37108 -rw-rw-r-- parseargs/parseargs3.txt
#  17278 -rw-rw-r-- parseargs/parsecntl3.txt
#  12588 -rw-rw-r-- parseargs/pgopen.c
#    977 -rw-rw-r-- parseargs/pgopen.h
#   9196 -rw-rw-r-- parseargs/stest.c
#  34399 -rw-rw-r-- parseargs/strfuncs.c
#   1729 -rw-rw-r-- parseargs/strfuncs.h
#   5916 -rw-rw-r-- parseargs/syserr.c
#   6643 -rwxrwxr-x parseargs/test.awk
#   2023 -rwxrwxr-x parseargs/test.csh
#   2097 -rwxrwxr-x parseargs/test.ksh
#   1718 -rwxrwxr-x parseargs/test.pl
#   1728 -rwxrwxr-x parseargs/test.rc
#   1789 -rwxrwxr-x parseargs/test.sh
#  20417 -rw-rw-r-- parseargs/unix_args.c
#   7749 -rw-rw-r-- parseargs/unix_man.c
#   7432 -rw-rw-r-- parseargs/useful.h
#  30360 -rw-rw-r-- parseargs/vms_args.c
#   8146 -rw-rw-r-- parseargs/vprintf.c
#   7121 -rw-rw-r-- parseargs/winsize.c
#  70930 -rw-rw-r-- parseargs/xparse.c
#
if test -r _shar_seq_.tmp; then
	echo 'Must unpack archives in sequence!'
	echo Please unpack part `cat _shar_seq_.tmp` next
	exit 1
fi
# ============= parseargs/Intro ==============
if test ! -d 'parseargs'; then
    echo 'x - creating directory parseargs'
    mkdir 'parseargs'
fi
if test -f 'parseargs/Intro' -a X"$1" != X"-c"; then
	echo 'x - skipping parseargs/Intro (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting parseargs/Intro (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'parseargs/Intro' &&
X
X                                  PARSEARGS
X
X                        extracted from Eric Allman's
X
X                            NIFTY UTILITY LIBRARY
X
X                          Created by Eric P. Allman
X                             <eric at Berkeley.EDU>
X
X                         Modified by Peter da Silva
X                            <peter at Ferranti.COM>
X
X                   Modified and Rewritten by Brad Appleton
X                          <brad at SSD.CSD.Harris.COM>
X
X
X Welcome to parseargs! Dont let the initial size of this package scare you.
X over 75% of it is English text, and more than 50% of the source is comments.
X
X Parseargs is a set of functions to parse command-line arguments. Unlike
X getopt and its variants, parseargs does more than just split up the
X command-line into some canonical form. Parseargs will actually parse the
X command-line, assigning the appropriate command-line values to the
X corresponding variables, and will verify the command-line syntax (and print
X a usage message if necessary). Furthermore, many features of it's parsing
X behavior are configurable at run-time. Some of these features include the
X following:
X
X     o  Prompting the user for missing arguments
X     o  Allowing keywords (+count=4) and/or options (-c4)
X     o  Checking for default arguments in an environment variable
X     o  Ignoring bad syntax instead of terminating
X     o  Ignoring upper/lower case on the command-line
X     o  Controlling the location of non-positional parameters
X     o  Controlling the contents (syntax and verbosity) of usage messages
X     o  Having long usage messages piped through a paging program
X
X Parseargs also allows for options that take an optional argument, and
X options that take a (possibly optional) list of one or more arguments.
X In addition, parseargs may be configured at compile-time to parse
X command-lines in accordance with the native command-syntax of any of the
X following operating systems:
X
X     o  Unix
X     o  VAX/VMS
X     o  OS/2
X     o  MS-DOS
X     o  AmigaDOS
X
X Parseargs consists of a set of C-functions to parse arguments from the
X command-line, from files, from strings, from linked-lists, and from
X string-vectors. Also included is a command-line interface which will parse
X arguments for shell scripts (sh, csh/tcsh, ksh, bash, and rc), awk-scripts,
X and perl-scripts.
X
X The basic structure used by parseargs is the argument-descriptor (sometimes
X called "argdesc" for brevity).  An array/string of argdescs is declared by
X the user to describe the command in question.  The resulting argdesc-array
X is passed to all the parseargs functions and is used to hold all information
X about the command. a sample argdesc-array is shown below.
X
X    STARTOFARGS,
X    { 'a', ARGVALOPT, argStr,   &area,    "AREAcode : optional area-code" },
X    { 'g', ARGLIST,   argStr,   &groups,  "newsGROUPS : groups to test" },
X    { 'r', ARGOPT,    argInt,   &count,   "REPcount : repetition factor" },
X    { 's', ARGOPT,    argChar,  &sepch,   "SEPchar : field separator" },
X    { 'x', ARGOPT,    argBool,  &xflag,   "Xflag : turn on X-mode" },
X    { ' ', ARGREQ,    argStr,   &name,    "name : name to use" },
X    { ' ', ARGLIST,   argStr,   &args,    "args : any remaining arguments" },
X    ENDOFARGS
X
X Once the above array/string is declared it is a simple matter to invoke
X parseargs from C as in the following example:
X
X    status = parseargs( argdesc_array, argv );
X
X or from a shell script as in the following example:
X
X    echo "$ARGDESC_STR" | parseargs -s sh -- "$0" "$@" >tmp$$
X    if [ $? = 0 ] ; then
X       . tmp$$
X    fi
X    /bin/rm -f tmp$$
X
X And before you know it, your command-line had been parsed, all variables 
X have been assigned their corresponding values from the command-line, syntax
X has been verified, and a usage message (if required) has been printed. 
X
X Under UNIX, the command-line syntax (using single character options) for the
X above command would be:
X
X    cmdname [-a [<areacode>]] [-g <newsgroups>...] [-r <repcount>]
X            [-s <sepchar>] [-x]  <name>  [<args>...]
X
X The UNIX command-line syntax using keywords (or long options) would be:
X
X    cmdname [+area [<areacode>]] [+groups <newsgroups>...] [+rep <repcount>]
X            [+sep <sepchar>] [+x]  <name>  [<args>...]
X
X The VMS command-line syntax would be the following:
X
X    cmdname [/AREA[=<areacode>]] [/GROUPS=<newsgroups>[,<newsgroups>...]
X            [/REP=<repcount>] [/SEP=<sepchar>] [/X]  <name>
X            [<args>[,<args>...]]
X
X The MS-DOS and OS/2 command-line syntax would be the following (unless the
X environment variable $SWITCHAR is '-' in which case UNIX syntax is used):
X
X    cmdname [/a[=<areacode>]] [/g=<newsgroups>...] [/r=<repcount>]
X            [/s=<sepchar>] [/x]  <name>  [<args>...]
X
X  The AmigaDOS command-line syntax would be the following:
X
X    cmdname [AREA [<areacode>]] [GROUPS <newsgroups>...] [REP <repcount>]
X            [SEP <sepchar>] [X]  <name>  [<args>...]
X
X
X Please look at the README files and manpages for more detailed information!
SHAR_EOF
chmod 0664 parseargs/Intro ||
echo 'restore of parseargs/Intro failed'
Wc_c="`wc -c < 'parseargs/Intro'`"
test 5018 -eq "$Wc_c" ||
	echo 'parseargs/Intro: original size 5018, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= parseargs/MANIFEST ==============
if test -f 'parseargs/MANIFEST' -a X"$1" != X"-c"; then
	echo 'x - skipping parseargs/MANIFEST (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting parseargs/MANIFEST (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'parseargs/MANIFEST' &&
X   File Name		Archive #	Description
-----------------------------------------------------------
X Intro                      2	Introduction to parseargs
X MANIFEST                   1	This file
X Makefile                   2	makefile for parseargs library
X Makefile.cpp               3	makefile template read by the C preprocessor
X README                     1	release information
X amiga_args.c               4	parse AmigaDOS command-lines
X arglist.c                  2	implement the listXxxx functions for arglists
X argtype.c                  5	implement the argXxxx argument type functions
X doc/                       1	directory containing documentation
X doc/Makefile               2	makefile for the documentation
X doc/arg_macros.inc         2	describe arg-xxx and ARG_XXX macros
X doc/argdesc.inc            2	describe an ARGDESC structure
X doc/argflags.inc           2	describe argument flags
X doc/argtype.man3           3	{n,t}roff source for argtype(3)
X doc/argvalopt.inc          1	describe options with optional arguments
X doc/bugs.inc               2	BUGS section for parseargs(1)
X doc/caveats.inc            1	CAVEATS section for parseargs(1) and (3)
X doc/cmd_macros.inc         1	describe CMD_XXX macros
X doc/defargs.inc            1	describe the default argdesc-array
X doc/env_args.inc           1	describe use of $CMD_ARGS
X doc/env_parse.inc          2	describe use of $PARSECNTL
X doc/env_usage.inc          2	describe use of $USAGECNTL
X doc/fparseargs3.inc        1	describe fparseargs(3)
X doc/lib_bugs.inc           1	BUGS section for parseargs(3)
X doc/lparseargs3.inc        1	describe lparseargs(3)
X doc/multivals.inc          2	describe multivals(3)
X doc/parseargs.man1         4	{n,t}roff source for parseargs(1)
X doc/parseargs.man3         4	{n,t}roff source for parseargs(3)
X doc/parseargs1.inc         1	describe parseargs(1)
X doc/parseargs3.inc         1	describe parseargs(3)
X doc/parsecntl.man3         1	{n,t}roff source for parsecntl(3)
X doc/parsecntl3.inc         1	describe parsecntl(3)
X doc/parsecntls.inc         2	describe function-codes for parsecntl(3)
X doc/parseflags.inc         2	describe parse flags
X doc/parsemodes.inc         1	describe modes for parsecntl(3)
X doc/returns.inc            2	describe function return values
X doc/sh_arrays.inc          3	describe handling of shell arrays
X doc/shells.inc             2	describe handling of different shells
X doc/sparseargs3.inc        1	describe sparseargs(3)
X doc/usage3.inc             1	describe usage(3)
X doc/vparseargs3.inc        1	describe vparseargs(3)
X ibm_args.c                 5	parse MS-DOS and OS/2 command-lines
X parseargs.awk              3	parseargs for awk
X parseargs.c                7	C source for parseargs(1)
X parseargs.h                6	include file for parseargs library
X parseargs.pl               2	parseargs for perl
X pgopen.c                   4	pipe output to a pager
X pgopen.h                   1	include file for pgopen.c
X stest.c                    3	test progarm for parseargs(3)
X strfuncs.c                 6	string library
X strfuncs.h                 1	include file for strfuncs.c
X syserr.c                   2	diagnostic message printing routines
X test.awk                   3	awk test program for parseargs(1)
X test.csh                   2	C-shell test program for parseargs(1)
X test.ksh                   2	Korn shell test program for parseargs(1)
X test.pl                    1	perl test program for parseargs(1)
X test.rc                    1	Plan 9 shell test program for parseargs(1)
X test.sh                    1	Bourne shell test program for parseargs(1)
X unix_args.c                4	parse Unix command-lines
X unix_man.c                 3	print Unix manual-page templates
X useful.h                   3	common include file for the library
X vms_args.c                 5	parse VAX/VMS DCL command-lines
X vprintf.c                  3	portable vfprintf, vprintf, and vsprintf
X winsize.c                  3	determine # rows and # columns of window
X xparse.c                   8	implement the parseargs library
SHAR_EOF
chmod 0664 parseargs/MANIFEST ||
echo 'restore of parseargs/MANIFEST failed'
Wc_c="`wc -c < 'parseargs/MANIFEST'`"
test 4033 -eq "$Wc_c" ||
	echo 'parseargs/MANIFEST: original size 4033, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= parseargs/Makefile ==============
if test -f 'parseargs/Makefile' -a X"$1" != X"-c"; then
	echo 'x - skipping parseargs/Makefile (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting parseargs/Makefile (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'parseargs/Makefile' &&
# $Header: Makefile,v 2.1 89/12/30 20:59:01 eric Exp $
X
###
# operating-system dependent stuff
###
.UNIVERSE =	att
#.UNIVERSE =	ucb
OS_TYPE =	unix
# OS_DEFS =	-D${OS_TYPE} -D${.UNIVERSE}_universe
X
###
# targets
###
NAME =	parseargs
PROGRAM =	${NAME}
LIBRARY =	${NAME}
STYLE =	unix
X
###
# target directories
###
LOCAL =  /usr/local
LIBDIR = ${LOCAL}/lib
INCDIR = ${LOCAL}/include
X
###
# compilation options
###
INCLUDES =	-I.
# MODEL =	-Ms
# MODELNAME =	S
OPT =	-O
# OPT =	-g
TEST_DEFS =	
USR_DEFS =	-DUSE_PAGER
DEFINES =	${OS_DEFS} ${USR_DEFS} ${TEST_DEFS} -D${STYLE}_style
OPTIONS =
CFLAGS =	${OPT} ${MODEL} ${INCLUDES} ${DEFINES} ${OPTIONS}
LINTFLAGS =	${INCLUDES} ${DEFINES} ${OPTIONS}
X
###
# libraries
###
LIBARGS =	${MODELNAME}lib${STYLE}_args.a
LIBFILE =	${MODELNAME}libparse.a
LOCLIBS =	${LIBARGS}
# SYSLIBS =	-lm -lcurses -ltermcap
LIBS =	${LOCLIBS} ${SYSLIBS}
X
###
# commands
###
AR =	ar rvu
DEL =	rm -f
COPY =	cp
CHDIR =	cd
LINT =	lint
MKTAGS =	ctags
PRINT =	pr
RANLIB =	ranlib
SHAR =	shar
SQZ =	compress -v
X
###
# files used
###
DOCS=	doc/Makefile \
X		doc/argtype.man3 \
X		doc/parseargs.man1 \
X		doc/parseargs.man3 \
X		doc/parsecntl.man3 \
X		doc/arg_macros.inc \
X		doc/argdesc.inc \
X		doc/argflags.inc \
X		doc/argvalopt.inc \
X		doc/bugs.inc \
X		doc/caveats.inc \
X		doc/cmd_macros.inc \
X		doc/defargs.inc \
X		doc/env_args.inc \
X		doc/env_parse.inc \
X		doc/env_usage.inc \
X		doc/fparseargs3.inc \
X		doc/lib_bugs.inc \
X		doc/lparseargs3.inc \
X		doc/multivals.inc \
X		doc/parseargs1.inc \
X		doc/parseargs3.inc \
X		doc/parsecntl3.inc \
X		doc/parsecntls.inc \
X		doc/parseflags.inc \
X		doc/parsemodes.inc \
X		doc/returns.inc \
X		doc/sh_arrays.inc \
X		doc/shells.inc \
X		doc/sparseargs3.inc \
X		doc/usage3.inc \
X		doc/vparseargs3.inc
SCRIPTS =	test.sh  test.csh  test.ksh  test.rc  test.awk  test.pl
TEMPLATES =	${NAME}.pl  ${NAME}.awk
XXXFILES =	Intro  README  MANIFEST  Makefile  Makefile.cpp
X
HDRS =	${NAME}.h \
X		pgopen.h \
X		strfuncs.h \
X		useful.h
X
SRCS =	${NAME}.c \
X		argtype.c \
X		arglist.c \
X		amiga_args.c \
X		ibm_args.c \
X		pgopen.c \
X		stest.c \
X		strfuncs.c \
X		syserr.c \
X		unix_args.c \
X		unix_man.c \
X		vms_args.c \
X		vprintf.c \
X		winsize.c \
X		xparse.c
X
OBJS =  ${STYLE}_args.o \
X		 arglist.o \
X		 argtype.o \
X		 pgopen.o \
X		 strfuncs.o \
X		 syserr.o \
X		 vprintf.o \
X		 winsize.o \
X		 xparse.o
X
PROG_OBJS =  ${NAME}.o   unix_man.o
TEST_OBJS =  stest.o
X
FILES =	${XXFILES} ${DOCS} ${HDRS} ${SRCS} ${TEMPLATES} ${SCRIPTS}
X
###
# target dependencies
###
all: ${LIBARGS} test ${PROGRAM}
X
test: ${STYLE}_test
X
${STYLE}_test :  stest.o ${LOCLIBS}
X	${CC} ${CFLAGS} -o ${STYLE}_test  stest.o ${LOCLIBS} ${SYSLIBS}
X
${LIBARGS}: ${OBJS}
X	${AR} $@ ${OBJS}
X	${RANLIB} $@
X
${PROGRAM}: ${PROG_OBJS} ${LOCLIBS}
X	${CC} ${CFLAGS} -o $@ ${PROG_OBJS} ${LOCLIBS} ${SYSLIBS}
X
###
# object dependencies
###
${NAME}.o:	${NAME}.c ${NAME}.h strfuncs.h useful.h
amiga_args.o:	amiga_args.c ${NAME}.h pgopen.h strfuncs.h useful.h
arglist.o:	arglist.c ${NAME}.h strfuncs.h useful.h
argtype.o:	argtype.c ${NAME}.h strfuncs.h useful.h
ibm_args.o:	ibm_args.c ${NAME}.h pgopen.h strfuncs.h useful.h
pgopen.o:	pgopen.c useful.h
stest.o:	stest.c ${NAME}.h useful.h
strfuncs.o:	strfuncs.c useful.h
syserr.o:	syserr.c useful.h
unix_args.o:	unix_args.c ${NAME}.h pgopen.h strfuncs.h useful.h
unix_man.o:	unix_man.c ${NAME}.h strfuncs.h useful.h
vms_args.o:	vms_args.c ${NAME}.h pgopen.h strfuncs.h useful.h
vprintf.o:	vprintf.c useful.h
winsize.o:	winsize.c useful.h
xparse.o:	xparse.c ${NAME}.h strfuncs.h useful.h
X
###
# installation dependencies
###
install:  ${INCDIR}/${NAME}.h \
X		 ${LIBDIR}/${LIBFILE} \
X		 ${LOCAL}/${PROGRAM}
X
X ${INCDIR}/${NAME}.h: ${NAME}.h useful.h
X	( ${CHDIR} ${INCDIR}; ${DEL} ${NAME}.h useful.h )
X	${COPY} ${NAME}.h useful.h ${INCDIR}
X
X ${LIBDIR}/${LIBFILE}: ${LIBARGS}
X	${DEL}   ${LIBDIR}/${LIBFILE}
X	${COPY} ${LIBARGS}   ${LIBDIR}/${LIBFILE}
X	${RANLIB}   ${LIBDIR}/${LIBFILE}
X
X ${LOCAL}/${PROGRAM}: ${PROGRAM} ${TEMPLATES}
X	( ${CHDIR} ${LOCAL} ; ${DEL} ${PROGRAM} ${TEMPLATES} )
X	${COPY} ${PROGRAM} ${TEMPLATES} ${LOCAL}
X
###
# maintenance dependencies
###
lint: ${SRCS}
X	${LINT} ${LINTFLAGS} ${SRCS}
X
shar: ${NAME}.shar
X
${NAME}.shar: ${FILES}
X	${DEL} ${NAME}.shar
X	${SHAR} ${FILES}  >${NAME}.shar
X
clean:
X	${DEL} ${OBJS} ${PROG_OBJS} ${TEST_OBJS}
X	${DEL} tags core .exrc
X
clobber: clean
X	${DEL} ${LIBARGS}  ${PROGRAM}  ${STYLE}_test
X
tags: ${SRCS} ${HDRS}
X	${MKTAGS} ${SRCS} ${HDRS}
X
collapse: clobber shar
X	${SQZ} ${NAME}.shar
X	${DEL} ${FILES}
X
print: ${SRCS} ${HDRS}
X	@${PRINT} ${SRCS} ${HDRS}
X
SHAR_EOF
chmod 0664 parseargs/Makefile ||
echo 'restore of parseargs/Makefile failed'
Wc_c="`wc -c < 'parseargs/Makefile'`"
test 4516 -eq "$Wc_c" ||
	echo 'parseargs/Makefile: original size 4516, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= parseargs/Makefile.cpp ==============
if test -f 'parseargs/Makefile.cpp' -a X"$1" != X"-c"; then
	echo 'x - skipping parseargs/Makefile.cpp (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting parseargs/Makefile.cpp (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'parseargs/Makefile.cpp' &&
#define REM #
#define REMLINE ###
X
#define ECHO(x) x
X
#ifdef unix
# define SYSTEM_NAME \unix
# define SYSTEM_TYPE att
# define _Output(file) >file
# define _Executable(file) file
# define _Library(file) file
# define _Object(file) file.o
# define _SubDir(d1,d2) d1/d2
# define _Dir(dir) dir
# define _Pathname(dir,file) dir/file
# define ROOT_DIR /
# define AR_CMD ar rvu
# define DEL_CMD rm -f
# define COPY_CMD cp
# define CHDIR_CMD cd
# define LINT_CMD lint
# define MKTAGS_CMD ctags
# define PRINT_CMD pr
# define RANLIB_CMD ranlib
# define SHAR_CMD shar
# define SQZ_CMD compress -v
#endif
X
#ifdef vms
# define SYSTEM_NAME \vms
# define SYSTEM_TYPE dec
# define _Output(file) /OUTPUT=file
# define _Executable(file) file.exe
# define _Library(file) file
# define _Object(file) file.obj
# define _SubDir(d1,d2) d1.d2
# define _Dir(dir) [dir]
# define _Pathname(dir,file) ECHO(dir)file
# define ROOT_DIR
# define AR_CMD ar rvu
# define DEL_CMD delete/file
# define COPY_CMD copy/file
# define CHDIR_CMD set/dir
# define LINT_CMD lint
# define MKTAGS_CMD ctags
# define PRINT_CMD type
# define RANLIB_CMD ranlib
# define SHAR_CMD shar
# define SQZ_CMD compress/file
#endif
X
#if ( defined(AZTEC) || defined(MANX) )
# define SYSTEM_NAME amiga
# define SYSTEM_TYPE commodore
# define _Output(file) >file
# define _Executable(file) file.exe
# define _Library(file) file
# define _Object(file) file.obj
# define _SubDir(d1,d2) d1/d2
# define _Dir(dir) dir
# define _Pathname(dir,file) dir/file
# define ROOT_DIR /
# define AR_CMD ar rvu
# define DEL_CMD rm -f
# define COPY_CMD cp
# define CHDIR_CMD cd
# define LINT_CMD lint
# define MKTAGS_CMD ctags
# define PRINT_CMD type
# define RANLIB_CMD ranlib
# define SHAR_CMD shar
# define SQZ_CMD compress -v
#endif
X
#ifdef MS_DOS
# define SYSTEM_NAME dos
# define SYSTEM_TYPE ibm
# define _Output(file) >file
# define _Executable(file) file.exe
# define _Library(file) file
# define _Object(file) file.obj
# define _SubDir(d1,d2) d1\\d2
# define _Dir(dir) dir
# define _Pathname(dir,file) dir\\file
# define ROOT_DIR \\
# define AR_CMD ar rvu
# define DEL_CMD del
# define COPY_CMD copy
# define CHDIR_CMD cd
# define LINT_CMD lint
# define MKTAGS_CMD ctags
# define PRINT_CMD type
# define RANLIB_CMD ranlib
# define SHAR_CMD shar
# define SQZ_CMD arc -c
#endif
X
#ifdef OS2
# define SYSTEM_NAME os2
# define SYSTEM_TYPE ibm
# define _Output(file) >file
# define _Executable(file) file.exe
# define _Library(file) file
# define _Object(file) file.obj
# define _SubDir(d1,d2) d1\\d2
# define _Dir(dir) dir
# define _Pathname(dir,file) dir\\file
# define ROOT_DIR \\
# define AR_CMD ar rvu
# define DEL_CMD del
# define COPY_CMD copy
# define CHDIR_CMD cd
# define LINT_CMD lint
# define MKTAGS_CMD ctags
# define PRINT_CMD type
# define RANLIB_CMD ranlib
# define SHAR_CMD shar
# define SQZ_CMD arc -c
#endif
X
REM $Header: Makefile,v 2.1 89/12/30 20:59:01 eric Exp $
X
REMLINE
REM operating-system dependent stuff
REMLINE
.UNIVERSE =	SYSTEM_TYPE
OS_TYPE =	SYSTEM_NAME
REM OS_DEFS =	-D${OS_TYPE} -D${.UNIVERSE}_universe
X
REMLINE
REM targets
REMLINE
NAME =	parseargs
PROGRAM =	_Executable(${NAME})
LIBRARY =	_Library(${NAME})
STYLE =	SYSTEM_NAME
X
REMLINE
REM target directories
REMLINE
LOCAL =	_Dir(_SubDir(usr,local))
LIBDIR =	_Dir(_SubDir(${LOCAL},lib))
INCDIR =	_Dir(_SubDir(${LOCAL},include))
X
REMLINE
REM compilation options
REMLINE
INCLUDES =	-I.
REM MODEL =	-Ms
REM MODELNAME =	S
OPT =	-O
REM OPT =	-g
TEST_DEFS =	
USR_DEFS =	-DUSE_PAGER
DEFINES =	${OS_DEFS} ${USR_DEFS} ${TEST_DEFS} -D${STYLE}_style
OPTIONS =
CFLAGS =	${OPT} ${MODEL} ${INCLUDES} ${DEFINES} ${OPTIONS}
LINTFLAGS =	${INCLUDES} ${DEFINES} ${OPTIONS}
X
REMLINE
REM libraries
REMLINE
LIBARGS =	${MODELNAME}lib${STYLE}_args.a
LIBFILE =	${MODELNAME}libparse.a
LOCLIBS =	${LIBARGS}
REM SYSLIBS =	-lm -lcurses -ltermcap
LIBS =	${LOCLIBS} ${SYSLIBS}
X
REMLINE
REM commands
REMLINE
AR =	AR_CMD
DEL =	DEL_CMD
COPY =	COPY_CMD
CHDIR =	CHDIR_CMD
LINT =	LINT_CMD
MKTAGS =	MKTAGS_CMD
PRINT =	PRINT_CMD
RANLIB =	RANLIB_CMD
SHAR =	SHAR_CMD
SQZ =	SQZ_CMD
X
REMLINE
REM files used
REMLINE
DOCS=	doc/Makefile \
X		doc/argtype.man3 \
X		doc/parseargs.man1 \
X		doc/parseargs.man3 \
X		doc/parsecntl.man3 \
X		doc/arg_macros.inc \
X		doc/argdesc.inc \
X		doc/argflags.inc \
X		doc/argvalopt.inc \
X		doc/bugs.inc \
X		doc/caveats.inc \
X		doc/cmd_macros.inc \
X		doc/defargs.inc \
X		doc/env_args.inc \
X		doc/env_parse.inc \
X		doc/env_usage.inc \
X		doc/fparseargs3.inc \
X		doc/lib_bugs.inc \
X		doc/lparseargs3.inc \
X		doc/multivals.inc \
X		doc/parseargs1.inc \
X		doc/parseargs3.inc \
X		doc/parsecntl3.inc \
X		doc/parsecntls.inc \
X		doc/parseflags.inc \
X		doc/parsemodes.inc \
X		doc/returns.inc \
X		doc/sh_arrays.inc \
X		doc/shells.inc \
X		doc/sparseargs3.inc \
X		doc/usage3.inc \
X		doc/vparseargs3.inc
SCRIPTS =	test.sh  test.csh  test.ksh  test.rc  test.awk  test.pl
TEMPLATES =	${NAME}.pl  ${NAME}.awk
XXXFILES =	Intro  README  MANIFEST  Makefile  Makefile.cpp
X
HDRS =	${NAME}.h \
X		pgopen.h \
X		strfuncs.h \
X		useful.h
X
SRCS =	${NAME}.c \
X		argtype.c \
X		arglist.c \
X		amiga_args.c \
X		ibm_args.c \
X		pgopen.c \
X		stest.c \
X		strfuncs.c \
X		syserr.c \
X		unix_args.c \
X		unix_man.c \
X		vms_args.c \
X		vprintf.c \
X		winsize.c \
X		xparse.c
X
OBJS = _Object(${STYLE}_args) \
X		_Object(arglist) \
X		_Object(argtype) \
X		_Object(pgopen) \
X		_Object(strfuncs) \
X		_Object(syserr) \
X		_Object(vprintf) \
X		_Object(winsize) \
X		_Object(xparse)
X
PROG_OBJS = _Object(${NAME})  _Object(unix_man)
TEST_OBJS = _Object(stest)
X
FILES =	${XXFILES} ${DOCS} ${HDRS} ${SRCS} ${TEMPLATES} ${SCRIPTS}
X
REMLINE
REM target dependencies
REMLINE
all: ${LIBARGS} test ${PROGRAM}
X
test: ${STYLE}_test
X
${STYLE}_test : _Object(stest) ${LOCLIBS}
X	${CC} ${CFLAGS} -o ${STYLE}_test _Object(stest) ${LOCLIBS} ${SYSLIBS}
X
${LIBARGS}: ${OBJS}
X	${AR} $@ ${OBJS}
X	${RANLIB} $@
X
${PROGRAM}: ${PROG_OBJS} ${LOCLIBS}
X	${CC} ${CFLAGS} -o $@ ${PROG_OBJS} ${LOCLIBS} ${SYSLIBS}
X
REMLINE
REM object dependencies
REMLINE
${NAME}.o:	${NAME}.c ${NAME}.h strfuncs.h useful.h
amiga_args.o:	amiga_args.c ${NAME}.h pgopen.h strfuncs.h useful.h
arglist.o:	arglist.c ${NAME}.h strfuncs.h useful.h
argtype.o:	argtype.c ${NAME}.h strfuncs.h useful.h
ibm_args.o:	ibm_args.c ${NAME}.h pgopen.h strfuncs.h useful.h
pgopen.o:	pgopen.c useful.h
stest.o:	stest.c ${NAME}.h useful.h
strfuncs.o:	strfuncs.c useful.h
syserr.o:	syserr.c useful.h
unix_args.o:	unix_args.c ${NAME}.h pgopen.h strfuncs.h useful.h
unix_man.o:	unix_man.c ${NAME}.h strfuncs.h useful.h
vms_args.o:	vms_args.c ${NAME}.h pgopen.h strfuncs.h useful.h
vprintf.o:	vprintf.c useful.h
winsize.o:	winsize.c useful.h
xparse.o:	xparse.c ${NAME}.h strfuncs.h useful.h
X
REMLINE
REM installation dependencies
REMLINE
install: _Pathname(${INCDIR},${NAME}.h) \
X		_Pathname(${LIBDIR},${LIBFILE}) \
X		_Pathname(${LOCAL},${PROGRAM})
X
_Pathname(${INCDIR},${NAME}.h): ${NAME}.h useful.h
X	( ${CHDIR} ${INCDIR}; ${DEL} ${NAME}.h useful.h )
X	${COPY} ${NAME}.h useful.h ${INCDIR}
X
_Pathname(${LIBDIR},${LIBFILE}): ${LIBARGS}
X	${DEL}  _Pathname(${LIBDIR},${LIBFILE})
X	${COPY} ${LIBARGS}  _Pathname(${LIBDIR},${LIBFILE})
X	${RANLIB}  _Pathname(${LIBDIR},${LIBFILE})
X
_Pathname(${LOCAL},${PROGRAM}): ${PROGRAM} ${TEMPLATES}
X	( ${CHDIR} ${LOCAL} ; ${DEL} ${PROGRAM} ${TEMPLATES} )
X	${COPY} ${PROGRAM} ${TEMPLATES} ${LOCAL}
X
REMLINE
REM maintenance dependencies
REMLINE
lint: ${SRCS}
X	${LINT} ${LINTFLAGS} ${SRCS}
X
shar: ${NAME}.shar
X
${NAME}.shar: ${FILES}
X	${DEL} ${NAME}.shar
X	${SHAR} ${FILES} _Output(${NAME}.shar)
X
clean:
X	${DEL} ${OBJS} ${PROG_OBJS} ${TEST_OBJS}
X	${DEL} tags core .exrc
X
clobber: clean
X	${DEL} ${LIBARGS}  ${PROGRAM}  ${STYLE}_test
X
tags: ${SRCS} ${HDRS}
X	${MKTAGS} ${SRCS} ${HDRS}
X
collapse: clobber shar
X	${SQZ} ${NAME}.shar
X	${DEL} ${FILES}
X
print: ${SRCS} ${HDRS}
X	@${PRINT} ${SRCS} ${HDRS}
X
SHAR_EOF
chmod 0664 parseargs/Makefile.cpp ||
echo 'restore of parseargs/Makefile.cpp failed'
Wc_c="`wc -c < 'parseargs/Makefile.cpp'`"
test 7778 -eq "$Wc_c" ||
	echo 'parseargs/Makefile.cpp: original size 7778, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= parseargs/README ==============
if test -f 'parseargs/README' -a X"$1" != X"-c"; then
	echo 'x - skipping parseargs/README (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting parseargs/README (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'parseargs/README' &&
X
X
X
X                                   PARSEARGS
X
X                          extracted from Eric Allman's
X
X                             NIFTY UTILITY LIBRARY
X
X                                 Eric P. Allman
X                            University of California
X                              Berkeley, California
X                               eric at Berkeley.EDU
X
X                                modifications by
X
X                                 Peter da Silva
X                  Ferranti International Controls Corporation
X                               Sugar Land, Texas
X                               peter at ferranti.com
X
X                          modified and rewritten by
X
X                                 Brad Appleton
X                 Harris Corporation, Computer Systems Division
X                         Fort Lauderdale, Florida USA
X                            brad at ssd.csd.harris.com
X
X
X
X SUMMARY
X =======
X This directory contains a subset of a utility library that I have used
X (in various forms) for several years now. This particular version is
X rather sparse, being a relatively recent reimplementation.
X
X [ The rest of the utility library has been left out, to reduce the
X size of Parseargs. The complete set of utilities was pubbed in the
X first comp.sources.misc distribution. -- PDS ]
X
X I am making this available as a  result of the rather surprising
X response to my C  Advisor column in UNIX Review Vol. 7 No. 11 on
X argument parsing, in which I  described an alternative to getopt.
X Several dozen people have asked for the source code -- an amazing
X number, considering that in the four years prior to this column, I
X have gotten perhaps six letters in total.
X
X
X COPY/REUSE POLICY
X =================
X Permission is hereby granted to freely copy and redistribute this
X software, provided that the author is clearly credited in all copies
X and derivations. Neither the name of the author nor that of the
X University may be used to endorse or promote products derived from
X this software without specific written permission. This software is
X provided ``As Is'' and without any express or implied warranties.
X
X
X CONTENTS
X ========
X     README : this file.
X     [ Intro : introduction to parseargs -- BDA ]
X     [ doc/Makefile : makefile for parseargs documentation -- BDA ]
X     [ doc/* : documentation for parseargs -- BDA ]
X     Makefile : a makefile for the library.
X     [ Makefile.cpp : a makefile template -- BDA ]
X     useful.h : a general header file, used by most everything.
X     parseargs.h : headers for the argument parser.
X     [ parseargs.c is now broken down into the following files : PDS ]
X         unix_args.c : a command line argument parser. Popular
X             response to my C Advisor column about this routine
X             in UNIX Review Vol. 7 No. 11 prompted me to make
X             this distribution available.
X         amiga_args.c : Amiga version of unix_args.c -- PDS
X         ibm_args.c : IBM-PC version of unix_args.c -- BDA
X         vms_args.c : VAX/VMS version of unix_args.c -- BDA
X         arglist.c : routines for ARGLIST options. -- PDS
X         argtype.c : routines for other options. The argument value parsers
X             for floating point values may be excluded by #defining the
X             macro NOFLOAT (only if you do NOT need floating-point values).
X             I had to break this out because RISC/os 4.01 from Mips doesn't
X             seem to support strtod in the BSD environment. You may find you
X             need to include -lm for this to work.
X         strfuncs.[ch] : string-manipulation functions &
X             dictionary-style searching routines.
X     [ end of parseargs.c : PDS ]
X     [ parseargs.c has been resurrected as a command line interface
X             to the parseargs library routines -- BDA ]
X     syserr.c : error message printing routines.
X     stest.c : a small test program for the argument parser.
X     [ xparse.c : source for [flsv]parseargs() and parsecntl() -- BDA ]
X     [ unix_man.c : routine to print unix man1 templates -- BDA ]
X     [ winsize.c : routine to "portably" get the screen size -- BDA ]
X     [ pgopen.[ch] : Unix source to pipe output to a pager -- BDA ]
X     [ vprintf.c : portable implementations of vprintf() & vfprintf() ]
X     [ parseargs.awk : awk interface to parseargs(1) -- BDA ]
X     [ parseargs.pl : perl interface to parseargs(1) -- BDA ]
X     [ test.sh : Bourne shell-script to test parseargs(1) -- BDA ]
X     [ test.csh : C shell-script to test parseargs(1) -- BDA ]
X     [ test.ksh : Korn shell-script to test parseargs(1) -- BDA ]
X     [ test.awk : awk script to test parseargs(1) -- BDA ]
X     [ test.pl : perl script to test parseargs(1) -- BDA ]
X
X The parseargs routines really ought to have a way of matching a  list
X (e.g., return the rest of argv). This isn't especially hard to do, but
X I haven't gotten around to it yet. [ Added, with ARGLIST flag -- PDS ]
X
X [ Added argUsage and argDummy pseudo-argument types -- BDA ]
X [ Added arg{S,T,U}Bool boolean argument types -- BDA ]
X [ Added ARGNOVAL argument flag to implement trigger types -- BDA ]
X [ Added ARGVALOPT, ARGVALREQ, and ARGVALGIVEN argument flags to
X   implement options with optional arguments -- BDA ]
X [ Added ARGPOS argument flag to implement arguments that may be
X    matched both positonally and by keyword -- BDA ]
X [ Added ARGVEC for argc/argv structures and implemented them for
X   string, character, floating point, and integer types -- BDA ]
X [ Added fparseargs(3), sparseargs(3), vparseargs(3), lparseargs(3),
X   and parsecntl(3) functions for flexibility and robustness -- BDA ]
X
X
X DISCLAIMERS
X ===========
X I hacked this code up to (hopefully) work on ANSI C  compilers, since
X several readers seem to be interested in this sort of thing. I can't
X claim to have really tested this.
X [ Now compiles under both BSD & AT&T Unix Systems using both ANSI and
X   non-ANSI C compilers -- BDA ]
X
X The original version was tested under SunOS 4.0 on SPARC
X architectures. The version you see has been loosely tested on a Mips
X M/2000 running RISC/os 4.01; I  have only tried it in the BSD
X environment, and that only loosely.
X
X ACKNOWLEDGEMENTS
X ================
X I wrote the first version of this code while working at the
X International Computer Science Institute in Berkeley, CA.
X
X ______________________________________________________________________________
X
X      Update to parseargs by Peter da Silva (peter at ferranti.com):
X
X (2nd update: more improvements to arg parsing, argChar type)
X (3rd update: return to original calling sequence, argList type)
X (4th update: removed routines not relevant to parseargs,
X              removed tracing/interactive stuff.)
X
X
X Parseargs is a really nifty set of routines, but it doesn't fit too
X well with standard UNIX semantics. In particular, you can get into a
X lot of trouble using it in a script if it drops into interactive mode
X on you. Also, it's not as useful as it could be for non-UNIX systems.
X To make it work better, I've made a couple of changes.
X
X It compiled straight out of the box on System III once I'd provided
X bcopy, bcmp, and strtol. The strtol I've provided is almost totally
X untested, but hopefully you won't need to use it. It's only for folks
X with old UNIX systems.
X
X First change was to disable the interactive prompting for arguments. I
X think that's inconsistent with usual UNIX semantics.
X
X The second change was to allow for a trailing list of arguments. I
X originally implemented this by changing the calling sequence to
X parseargs. On reflection this would just produce incompatibilities, so
X I added a  new flag, ARGLIST, and a new type, listStr. Later, other
X kinds of lists can presumably be added. A list handles a pointer to a
X list of objects:
X
X     struct arglist *fred;
X
X Operations are defined on arglists, L_NEXT(fred) produces the next
X element in fred. L_STRING(fred) produces the value of fred cast to
X "char *".
X
X During evaluation the list is kept in LIFO order, and it's reversed
X just before returning to parseargs. This simplifies the coding of the
X list routines, but still lets you step through the list in a
X reasonable order. [ lists are now maintained in FIFO order --BDA ]
X
X The final change is the addition of a  'argChar' type. This parses
X character arguments (such as the '-T' option to 'awk'), accepting
X single characters,
X
X Parseargs itself no longer uses ckalloc, traceset, funclist, and so
X on. these routines are pretty cool, but when you're grafting parseargs
X onto an existing program they just get in the way. Also, it's possible
X to make parseargs fail in a cleaner fashion by handling out-of-memory
X cases myself. Certainly there's not going to be any loose memory lying
X around to be collected when parseargs starts up!
X
X Also, the error messages have been made a  bit more descriptive.
X Instead of saying "stest: value required for -c flag", it prints
X "stest: RepCount required for -c flag". The ad_prompt element should
X really be a descriptive word that can be used in a sentence... or for
X non_UNIX systems a multi-character or keyword based flag. I have an
X Amiga version included, for example, that uses keyword syntax. In that
X version, the usage message reads:
X
X     Usage: amiga_test <name> [GROUP <newsgroup>]... [REP <repcount>] +
X             [DIR <dirname>] [X] [Y] [Z] [TAB <tabchar>] [<file>]...
X
X Instead of:
X
X     Usage: unix_test <Name> [-n <newsGROUP>]... [-c <REPcount>] [-d <DIRname>] [-x] [-y] [-z] [-t <TABchar>] [<File>]...
X
X
X This would solve the old problem of UNIX programs sticking out like a
X sore thumb in other operating systems.
X
X The Amiga version still needs to prompt for options if called with a
X single types and finally integrate CLI and Workbench environments.
X
X Latest update: the prompt string may include a more extensive comment
X (in parentheses, after the one-word initial comment), that will be
X used in error messages and listed in the usage message.
X
X [ comment may appear in square brackets, curly braces, angle brackets,
X   or parentheses (so one can use the other 3 in the comment) -- BDA ]
X
X The environment variable USAGE controls the printing of the usage
X message:
X
X     USAGE == -1 No usage message.
X     USAGE == 0 Short message (default).
X     USAGE == 1 Names of flags given in parentheses.
X     USAGE == 2 Long description of options given.
X     USAGE == 3 Both flag names and long description given.
X
X Examples:
X
X     $ USAGE=3; export USAGE
X     $ unix_test -c
X     unix_test: REPcount (number of times to repeat each group) required for -c flag
X     unix_test: Name required
X     Usage: unix_test <Name> [-n <newsGROUP>]... [-c <REPcount>] [-d <DIRname>] [-x] (Xflag) [-y] (Yflag) [-z] (Zflag) [-t <TABchar>] [<File>]...
X     Options:
X             -n newsGROUP newsgroups to test
X             -c REPcount number of times to repeat each group
X             -x (Xflag) expand in X direction
X             -y (Yflag) expand in Y direction
X             -z (Zflag) expand in Z direction
X     $ USAGE=0; export USAGE
X     $ unix_test
X     unix_test: Name required
X     Usage: unix_test <Name> [-n <newsGROUP>]... [-c <REPcount>] [-d <DIRname>] [-x] [-y] [-z] [-t <TABchar>] [<File>]...
X     $ USAGE=-1; export USAGE
X     $ unix_test
X     unix_test: Name required
X
X
X [ changed to use the environment variable USAGECNTL instead of USAGE.
X   "USAGE" is a variable name commonly used in shell scripts. --BDA ]
X
X [ when keywords are desired (via USAGECNTL) their actual command-line
X   syntax is now displayed (instead of just appearing in parentheses)
X   -- BDA ]
X
X ______________________________________________________________________________
X
X
X             Update to parseargs (and major re-write) by Brad Appleton
X                        (brad at travis.ssd.csd.harris.com)
X                              Last Update: 03/01/91
X
X DISCLAIMER
X ==========
X Neither Brad Appleton, nor Harris Corporation (including any of its
X subsidiaries and subdivisions and Harris Computer Systems Division in
X particular) are responsible for maintaining and supporting this
X software or for any consequences resulting from the use of this
X software, no matter how awful, even if they arise from flaws in the
X software.
X
X
X NEW FILES: parseargs.c, xparse.c, pgopen.[ch], vprintf.c
X ========================================================
X I thought parseargs was so cool that I wanted to be able to use it for
X shell-scripts too! To do that I would need a command-line interface.
X I decided to make the command-line interface look as close as possible
X to the C-interface so I  basically implemented a  very small
X interpreter; Hence, parseargs.c was resurrected but this time as an
X interface to the parseargs library instead of being the guts of it.
X
X Xparse.c implements routines to parse arguments from a   file
X (fparseargs), from an arglist (lparseargs), from a  string
X (sparseargs), from a variable argument-list (vparseargs), and from a
X string-vector (parseargs). It also contains the routine parsecntl()
X which controls the parsing behavior of a  commands, and the routine
X usage() which prints a usage message. Each of the <os>_args.c files
X used to implement its own parseargs() and usage() functions, this has
X been changed so that parseargs() and usage() are implemented in
X xparse.c and the guts of the os-specific parsing and formatting is
X implemented in the routines <os>_parse() and <os>_usage() in the file
X <os>_args.c!
X
X On Unix systems, if the user desires, usage messages are paged using
X popen(3S). The pager used is ${USAGE_PAGER:-${PAGER:-/usr/ucb/more}}.
X If for some reason this fails then no paging is performed. The pager
X library is implemented in the file pgopen.c and only used if the macro
X USE_PAGER is #defined. Pgopen.h is an include file which will include
X the external declarations for pgopen.c if USE_PAGER is #defined and
X defines some functionally equivalent (but non-paging) macros instead.
X
X The file vprintf.c is a  portable implementation of vprintf(),
X vfprintf(), and vsprintf() for systems (such as BSD Unix) that don't
X already have them.
X
X
X NEW ARGUMENT TYPES: argUsage, arg[UTS]Bool, & argDummy
X ======================================================
X I added the following argument types to parseargs:
X
X    argUsage -- print a usage message
X    argDummy -- dummy argument, not parsed but used for messages
X    argSBool -- set a boolean flag
X    argTBool -- toggle a boolean flag
X    argUBool -- unset a boolean flag
X
X Consult the manual page for argtype(3) for more information.
X I also added the capability to handle ARGVEC arguments into the
X remaining argument type functions.
X
X NEW ARGUMENT FLAGS:
X ===================
X I added the following argument flags to parseargs:
X
X     ARGPOS -- arg is positionally matched and keyword matched
X     ARGNOVAL -- arg takes no value
X     ARGVALOPT -- arg takes an optional value
X     ARGVALREQ -- arg requires a value
X     ARGGIVEN -- arg was supplied on command-line
X     ARGVALGIVEN -- arg-value was supplied on command-line
X     ARGDESCRIBED -- argument was given a description
X     ARGKEYWORD -- argument was matched as a keyword
X     ARGVALSEP -- arg-value was in a separate token from the argument
X
X Consult the manual page for parseargs(1) & parseargs(3) for more information.
X
X NEW INTERFACE
X =============
X I added a set of Macros to allow a more "self documenting" approach to
X declaring argument-descriptor arrays. The "old-style" is still
X accepted (but if used it is recommended that the STARTOFARGS macro is
X used in conjunction with ENDOFARGS). The new style is documented in the
X parseargs(3) manual under the heading "CMD MACROS"
X
X
X MODIFICATIONS TO USAGE MESSAGES
X ===============================
X After Peter modified usage() to look at the USAGE environment
X variable, I decided that, even if the user had turned USAGE off, that
X (s)he really did want the usage if an argUsage option was specified so
X I added a  static global Usage_Requested to xparse.c to over-ride
X the USAGE variable (if necessary) so that a verbose message is always
X given when an argUsage option is specified (regardless of the value in
X the environment variable).
X
X I also changed the name of the environment variable that gets "looked"
X up to be USAGECNTL instead of USAGE since USAGE is a common variable
X name for shell scripts. Furthermore, I changed the contents of USAGECNTL
X from a number to a sequence of mnemonic strings (for better readability).
X I also made USAGECNTL control whether or not a command-description is
X printed and whther or not the message is piped to a pager on Unix.
X
X Under VMS, the global symbol USAGECNTL is used in lieu of an environment
X variable.  See the parseargs(3) and parseargs(1) manual pages for more
X information regarding USAGECNTL.
X
X SPECIFYING ALTERNATE PARSING BEHAVIOR
X =====================================
X Parseargs provides 3 methods for controlling "how" the command-line is
X parsed. There is a parsecntl() function which may be used to specify
X flags other than the default parse-behavior. The user may define the
X environment variable (or global symbol) PARSECNTL to contain the option-
X string that corresponds to the desired combination of pa_XXXX flags
X #defined in parseargs.h. The parseargs command, also allows for options
X to specify certain parsing behavior. The parsecntl() function provides
X finer control than either of the other two methods. The user's PARSECNTL
X variable will always over-ride any conflicting flags that were set by
X parsecntl() or by the parseargs command via command-line options.
X See the manual pages for parseargs(1), parseargs(3), and parsecntl(3)
X for more information.
X
X GIVING DEFAULT ARGUMENTS
X ========================
X Programs that use parseargs may be given default arguments under UNIX
X and PCs through the use of environment variables (symbols are used for
X VMS systems). If a C-program or a shell-script uses parseargs to imple-
X ment a command named "foo" then the environment variable (or global
X synbol) FOO_ARGS will be parsed for any "default" arguments before argv
X is parsed.  Argv will over-ride any options that are specified in
X FOO_ARGS (except that ARGLISTs and ARGVECs set in FOO_ARGS will be
X appended from argv[]).
X
X
X SPECIFYING DEFAULT ARGDESCs TO SEARCH
X =====================================
X If a given option/qualifier does not appear to match any items in the
X argdesc-array, a  default argdesc-array is then searched to match the
X option. If it is STILL unmatched then it is flagged as such. The
X default-argdesc array is automatically used by all programmer-defined
X argdesc-array but may be unset or reset using the pc_DEFARGS function
X of parsecntl(3).
X
X
X ADDING NEW SHELLS TO parseargs(1)
X =================================
X I did my best to implement parseargs.c in a manner that would make it
X relatively easy to add new shell-types. At this point in time, parseargs
X will generate output for the following command-interpreters:
X
X     sh           (Bourne Shell)
X     csh/tcsh     (C-Shell)
X     bash         (Bourne-Again Shell)
X     ksh          (Korn Shell)
X     rc           (Plan 9 Shell)
X     perl
X     awk
X
X Parseargs.c thinks the Free Software Foundation's Bourne-Again Shell
X (bash) is equivalent to the Bourne shell (sh). Bash is a superset of
X sh (so I am told) but I do not know enough about it to treat it
X differently. I  hope someone who is familiar with bash syntax will
X correct this deficiency (particularly with shell arrays).
X
X If someone wants to try to add more shell-types to parseargs.c, here
X are the main things that need to be done:
X
X 1. add #defines for both the name (a string) and type (an integer) of
X    shell (e.g #define BOURNE_SHELL "sh" and #define SH 4)
X
X 2. add a shell_info entry into the array Shell[]. The index of the
X    entry in the array should be the number used in the #define for the
X    type of shell.
X
X 3. make sure that get_shell_type() will return the proper value for
X    the new shell.
X
X 4. print_args doesnt really do any shell specific stuff outside of
X    indexing into the table. The print_arglist() and
X    unset_positional_parameters() functions do some shell specific stuff
X    and will need a case added to the switch statement(s) for the newly
X    added shell.
X
X 5. If the information in the shell-info structure is not sufficient
X    for the new shell then you should either:
X       a) redefine the structure for all shells including your shell.
X       b) add some special code into print_args() for your shell!
X
X For a more thorough discussion of parseargs(1), consult the manual pages!
X
X
X MODIFICATIONS TO KEYWORD MATCHING
X =================================
X I changed keyword matching in strfuncs.c just a tad by allowing only a
X partial match on the keyword (instead of a full match), this way the
X user only needs to give enough of the keyword on the command line so
X that it will uniquely match a  suffix of a  keyword in the arg-
X descriptor table. A drawback to this is that if the user does NOT
X specify enough of the keyword to uniquely match ONE arg-desc entry,
X then the first such entry encountered will be considered to match the
X partial keyword on the command-line.
X
X This "shortest-prefix" matching is performed 1st on only the uppercase
X characters in the ad_prompt, and then (if no match) on the whole
X prompt. This is "nice" in that the user only needs to specify the
X shortest prefix but it also means that a typo can very easily be
X interpreted as an option when it shouldnt be (both "+new" and "+gr"
X would match "newsGROUPS") or the wrong option may be matched if too
X small a portion of the keyword is provided.
X
X To help prevent this type of thing... Unless the keyword to be matched
X has length < 2, I force the user to specify at least 2 characters for
X the keyword (for VAX/VMS this minimum length becomes 4 iff the keyword
X starts with "NO").
X
X amiga_args.c still uses the old keyword matching function. Since
X AmigaDOS keywords have no '/' or '-' prefix -- I thought it would be
X too dangerous to allow such "partial matching" because it would be too
X easy for bona-fide arguments to partially match a keyword!
X
X
X MODIFICATIONS TO CHARACTER ARGTYPES
X ===================================
X Under UNIX, an argChar option argument may now be provided on the
X command-line immediately following the option-letter and the
X characters following the character argument are still processed as
X options. Hence, if '-c' is an argChar option and '-x', '-y', and '-z'
X are boolean options, then we may specify the character '_' as an
X argument to '-c' as well as specifying the '-x', '-y' and '-z' flags
X in the following manner:
X
X     -c_xyz
X
X Of course, the following will have the same effect:
X
X     -c_ -xyz
X
X as will this:
X
X     -c _ -xyz
X
X but the following is incorrect:
X
X     -c _xyz
X
X In other words, only the character that immediately follows an argChar
X option is considered to be an argument to the option and other option
X characters may immediately precede the single-character argument.
X
X
X MODIFICATIONS TO BOOLEAN ARGTYPES
X =================================
X Boolean types may now take an argument if so desired. under VAX/VMS:
X
X     "/FLAG" (1)
X
X will turn ON an an argBool or argSBool flag, will turn OFF an argUBool
X flag, and will toggle an argTBool flag. However, the following:
X
X     "/FLAG=ON" (2)
X
X will turn ON the flag regardless of whether it is argBool, argSBool,
X argUBool, or argTBool (so long as it is one of them). Similarly,
X
X     "/FLAG=OFF" (3)
X
X will always turn a boolean flag OFF!
X
X Similar syntax is used for AmigaDOS, the corresponding Amiga
X specification for examples (1)-(3) above would be:
X
X     FLAG (1)
X     FLAG=ON (2)
X     FLAG=OFF (3)
X
X For the Amiga, the boolean argument MUST be part of the same argv[]
X element as the keyword itself ("FLAG ON" or "FLAG OFF" is not
X acceptable).
X
X For Unix (and IBM-PCs), long option examples of (1)-(3) would be the
X following:
X
X     +flag (1)
X     +flag=on (2)
X     +flag=off (3)
X
X As with the Amiga, the boolean argument ("on" or "off") MUST be part
X of the same argv[] element as the long-option itself.
X
X For single character options under Unix, the corresponding examples
X for (1)-(3) are as follows:
X
X     -f (1)
X     -f+ (2)
X     -f- (3)
X
X As with Unix, the boolean argument ("on" or "off") MUST be part of the
X same argv[] element as the long-option itself.
X
X For single character options under MS-DOS and OS/2, the corresponding
X examples for (1)-(3) are as follows:
X
X     /f (1)
X     /f+ (2)
X     /f- (3)
X
X With single character options, any boolean argument must be a  single
X character and must be in the character immediately following the the
X option character. If the character following the option character is
X NOT one of '-', '+', '0', ment) then the default action will be taken
X (set, clear or toggle depending upon the type of boolean flag) and the
X character immediately following the boolean option is assumed to be
X another option-specification (e.g. -fc4 and -f+c4 are both allowed
X where 'f' is a boolean flag and 'c' is an integer (argInt) flag).
X
X With all supported operating systems, the following arguments may be
X used as Boolean arguments (differences between uppercase/lowercase are
X ignored):
X
X      Arg        Effect
X     =====  ====================
X       ^    Toggles flag (single character options only)
X       ~    Toggles flag (single character options only)
X       1    Sets flag
X       0    Unsets flag
X       +    Sets flag
X       -    Unsets flag
X       T    Sets flag
X       F    Unsets flag
X      YES   Sets flag
X       NO   Unsets flag
X       ON   Sets flag
X      OFF   Unsets flag
X     TRUE   Sets flag
X    FALSE   Unsets flag
X
X With single character options under Unix and IBM-PCs, only '+', '-',
X '0', '1', '^' and '~' may be used.
X
X
X CHANGES TO ARGTYPE RETURN VALUES
X ================================
X In order to allow only a single character to be consumed for arguments
X to boolean and character options, I  had to change the way return
X values from an argtype function were handled. Previously, the argtype
X function merely returned TRUE (1) upon success and FALSE (0) upon
X failure. I changed this slightly. Now, an argument type function
X returns:
X
X     FALSE (0) if the argument was NOT successfully interpreted
X
X     TRUE (1) if the argument was successfully interpreted and ALL
X             characters of the argument were used.
X
X     -N (<0) if the argument was successfully interpreted AND only
X             the first N characters of the argument were used.
X
X At this time, only the Boolean and argChar argument type functions
X return any value other than TRUE or FALSE.
X
X
X NEW ARGUMENT LISTS
X ==================
X Arglists have been enhanced with a new type called arg-vectors (and
X use the ARGVEC flag instead of the ARGLIST flag). Arg-vectors are a
X structure containing an argv/argc pair. There are two macros in
X parseargs.h which are used for arg-vectors. ARGVEC_T may be used to
X declare a vector structure or a vector type; ARGVEC_EMPTY may be used
X to initialize the structure. It is strongly recommended that ARGVEC_T
X be used to declare vector types in a typedef statement (particularly
X if one is using function prototypes) but for those who insist, it may
X be used to directly declare a  structure. An example of both uses (as
X well as an example use of ArgLists) may be found in the documentation.
X
X
X MISCELLANEOUS FIXES/ENHANCEMENTS
X ================================
X unix_args.c did not consider '-' or '+' to be valid arguments unless
X '--' had already been specified. This has been fixed.
X
X The compile-time interactive option seemed to have been removed from
X parseargs so I put it back in and made it a run-time option (that is
X selected using the pa_PROMPT function-code to parsecntl()). I  also
X made it prompt repeatedly for arglists (a blank line ends the list).
X No characters are escaped or trimmed (such as whitespace, quotes, or
X special characters) when a prompted argument is read from the user!
X
X amiga_args.c will now check to see if an argument matches a  keyword
X before assigning it as a keyword argument. If 'STRING' is an argStr
X and 'REP' is an argInt then: "cmd STRING REP=4" will leave string
X without a  value and assign REP to be 4. Previously, this would have
X resulted in assigning the value of optional keyword arguments.
X
X Arglists are no longer stored in LIFO order and then reversed at the
X last minute, they are now always stored in FIFO order (the order given
X on the command-line).
X
X I also provided extensive updating to the manual pages so that they
X now reflect the current capabilities of parseargs!
X
X
X MODIFICATIONS TO parseargs.h
X ============================
X I hacked parseargs.h up a bit so that certain items may be excluded or
X included by #defining certain names before including the file.
X
X If PARSEARGS_PRIVATE is #defined, then various type and macro
X definitions which are specific to the implementation of parseargs (but
X not to its use) are included. This is my hack at C++ friend functions;
X A file declares itself to be a  "friend" by #defining PARSEARGS_PRIVATE
X before #including the file parseargs.h
X
X If PARSEARGS_NEXTERNS is #defined, then the external function declarations
X for the various parseargs functions (parseargs, parsecntl, fparseargs,
X etc ...) are NOT included. This is really only useful to the files that
X actually implement the various parseargs functions.
X
X If PARSEARGS_NARGTYPES is #defined, then the external function
X declarations for the various argtype functions (argInt, argStr,
X listStr, etc ..) are NOT included. This is really only useful to the
X files that actually implement the various argtype functions.
X
X Also, ARGDESC is now a typedef instead of a #define. On the same note,
X arglists may be declared by using the "ArgList" typedef or by using
X the "struct arglist" structure declaration.
X
X
X MODIFICATIONS TO THE ARGDESC ARRAY
X ==================================
X Before I got my hands on it - parseargs had no parsecntl() or means of
X parsing arguments from a file or a string. Any and all arguments to be
X parsed would be handled in a single invocation of parseargs. In order
X to allow arguments to be parsed using multiple passes (which would be
X required if we were to parse arguments in a file for example) I  added
X the notion of parse-flags to modify parsing behavior. Because of this,
X I also required certain local variables to now be static. In order to
X allow parsing for multiple commands - I put the parse-flags and the
X static variables into the argument descriptor array itself. This way -
X each arg-descriptor has its own set of flags and state variables to
X record its own context.
X
X To implement this without changing the existing syntax, I put all this
X stuff into the FIRST & LAST argument descriptors in the array. If an
X argdesc-array is declared using the CMD_XXXXX macros, then this is
X already taken care of. If an argdesc array is used using the old-style
X syntax, ENDOFARGS will now define two arg-descs at the end of the
X array. Parseargs needs to recognize the old syntax and shift each
X element in the array down by one position (creating room for a new one
X at the top). I would have preferred to just swap the first and last
X entries in this case but I have to preserve the original order of any
X positionally-matched parameters! This means that extra pre-processing
X (to shift the array) needs to be performed for argdesc-arrays that are
X declared using the old syntax! To avoid this overhead - users of the
X old syntax could use the pre#defined macro STARTOFARGS and make it the
X first entry in the argdesc-array.
X
X Also, each arg-descriptor is now precompiled so that the argument
X prompt and the argument description are stored in two separate strings
X (the first of which is pointed to by the "ad_prompt" field). This
X avoids the need to constantly write code to "locate" the description
X every time it is desired by the programmer.
X
X In order to ease the use of the various attributes of arg-descriptors,
X (including the argument-prompt and the argument description) a set of
X macros is available for extracting the corresponding attributes of a
X command, or one of its argument entries.  Public macros are documented
X in the manual pages, private ones are listed here:
X
X     cmd_name(Args) -- the given command-name
X     cmd_flags(Args) -- the command parse flags
X     cmd_context(Args) -- pointer to the command-context
X                          (which is stored in the last argument-descriptor)
X     cmd_state(Args) -- the command-state flags
X     cmd_list(Args) -- pointer to currently active arg-list
X     cmd_prev(Args) -- pointer to previously matched arg (Amiga only)
X     cmd_defargs(Args) -- pointer to default argdesc for this command
X     cmd_argv0(Args) -- pointer to argv[0] from command-line
X     cmd_purpose(Args) -- one-line description of command
X     cmd_description(Args) -- multi-line description of command
SHAR_EOF
true || echo 'restore of parseargs/README failed'
fi
echo 'End of  part 1'
echo 'File parseargs/README is continued in part 2'
echo 2 > _shar_seq_.tmp
exit 0
exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent at sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent at uunet.uu.net.



More information about the Comp.sources.misc mailing list