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