brad@hcx1.ssd.csd.harris.com (Brad Appleton) (03/18/91)
Submitted-by: Brad Appleton <brad@hcx1.ssd.csd.harris.com> Posting-number: Volume 17, Issue 48 Archive-name: parseargs/part03 This is part 3 of parseargs #!/bin/sh # this is Part.03 (part 3 of a multipart archive) # do not concatenate these parts, unpack them in order with /bin/sh # file parseargs/argtype3.txt continued # if test ! -r _shar_seq_.tmp; then echo 'Please unpack part 1 first!' exit 1 fi (read Scheck if test "$Scheck" != 3; then echo Please unpack part "$Scheck" next! exit 1 else exit 0 fi ) < _shar_seq_.tmp || exit 1 if test ! -f _shar_wnt_.tmp; then echo 'x - still skipping parseargs/argtype3.txt' else echo 'x - continuing file parseargs/argtype3.txt' sed 's/^X//' << 'SHAR_EOF' >> 'parseargs/argtype3.txt' && X end). X X ArgStr ensures that the very last item in a vector of X strings (the one accessed as vec.array[ vec.count ]) will X always be NULL. X X X X X Page 2 X X X X X X ARGTYPE(3) ARGTYPE(3) X X X CHARACTER-TYPES X ArgChar assigns the given character to the value referenced X by arg_valp(ad) (unless the argument is a vector in which X case the given character is appended to the end). X X ArgChar ensures that the very last item in a vector of char- X acter (the one accessed as vec.array[ vec.count ]) will X always be a NULL byte so that the resulting vector may also X be used as a NULL terminated string. X X Unlike argStr, argChar will translate character escape X sequences such as `\n' and `\012'. X INTEGER-TYPES X Each of these functions converts the given string to the X desired integral type. The value may be specified as an X octal number by specifying the first digit to be 0. Simi- X larly, If the first two characters are `0x' then the number X is treated as hexadecimal. X FLOATING-POINT-TYPES X Each of these functions converts the given string to the X desired floating-point type. X BOOLEAN-TYPES X ArgBool and argSBool set a boolean value (if no value is X given). ArgUBool unsets a boolean value (if no value is X given). ArgTBool toggles a boolean value (if no value is X given). If a value is supplied to any of these routines, X then the string is looked up in a table and assigned the X corresponding value. X X If a value is supplied for an argument that was matched via X its single character name and is part of the same argv ele- X ment as the argument-name (so that both ARGKEYWORD and X ARGVALSEP are not set), then only the first character of the X value is used (unless it is not found in our table, in which X case the value is ignored and the default action is taken). X The table used for single-character-options is the follow- X ing: X X `0' or `-' X The corresponding boolean flag is set to FALSE. X X `1' or `+' X The corresponding boolean flag is set to TRUE. X X `^' or `~' X The corresponding boolean flag is toggled. X X The possible argument strings for long-options (keywords) X are as follows (case-insensitive): X X X Page 3 X X X X X X ARGTYPE(3) ARGTYPE(3) X X X X ``0'', ``-'', ``OFF'', or ``FALSE'' X The corresponding boolean flag is set to FALSE. X X ``1'', ``+'', ``ON'', or ``TRUE'' X The corresponding boolean flag is set to TRUE. X LIST TYPES X The listStr argument translation routine is only intended X for use on behalf of arguments that have the ARGLIST flag X enabled. It will allocate space for a new node (and for the X new string if copyf is set) and append it to the end of the X list. The argument-list may later be deallocated by invoking X the function listFree and passing it the address of the X first item in the list. X X X VecFree is a macro that is used to deallocate argument- X vectors. It will free the array and flags fields of a vec- X tor, set them to NULL, and set the count field to zero. Vec- X DeepFree is a macro that is similar to vecFree but will X additionally look at each item in the array; any component X of the array that had ARGCOPYF enabled will also be deallo- X cated. Both macros are given the vector structure to free X followed by the type of the items in the vector. X SEE ALSO X parseargs(3), parseargs(1), X X X X X X X X X X X X X X X X X X X X X X X X X X X X Page 4 X X X SHAR_EOF echo 'File parseargs/argtype3.txt is complete' && chmod 0664 parseargs/argtype3.txt || echo 'restore of parseargs/argtype3.txt failed' Wc_c="`wc -c < 'parseargs/argtype3.txt'`" test 7427 -eq "$Wc_c" || echo 'parseargs/argtype3.txt: original size 7427, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= parseargs/doc/Makefile ============== if test ! -d 'parseargs/doc'; then echo 'x - creating directory parseargs/doc' mkdir 'parseargs/doc' fi if test -f 'parseargs/doc/Makefile' -a X"$1" != X"-c"; then echo 'x - skipping parseargs/doc/Makefile (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting parseargs/doc/Makefile (Text)' sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/Makefile' && # $Header: Man.mk,v 1.0 90/03/05 09:21:28 brad Exp $ X ### # target directories ### MAN1= man1 MAN3= man3 LOCALMAN= local_man MANDIR= /usr/man/${LOCALMAN} CATMANDIR= /usr/catman/${LOCALMAN} X ### # commands ### COL= col COLFLAGS= -b SOELIM= /usr/ucb/soelim MANTOCATMAN= /usr/ucb/mantocatman TROFF= roff TRFLAGS= -man -dimagen1 NROFF= nroff NRFLAGS= -man SPELL= spell COPY= /bin/cp DEL= /bin/rm -f X ### # files used ### INCS= *.inc SRCS= argtype.man3 parseargs.man1 parseargs.man3 parsecntl.man3 MANIFEST= Manifest MAN3FILES= argtype.3 parseargs.3 parsecntl.3 MAN1FILES= parseargs.1 CATMAN3FILES= argtype.3.z parseargs.3.z parsecntl.3.z CATMAN1FILES= parseargs.1.z X ### # target dependencies ### .SUFFIXES: .man1 .man3 .1 .3 X .man1.1: X ${SOELIM} $< >$*.1 X ${MANTOCATMAN} $*.1 X .man3.3: X ${SOELIM} $< >$*.3 X ${MANTOCATMAN} $*.3 X ### # give a usage message if no target is given ### usage: X @echo "Usage: make <target>" X @echo " " X @echo "where <target> is one of the following: " X @echo " " X @echo " install -- to install the documentation" X @echo " print -- to print the documentation" X @echo " view -- to view the documentation" X @echo " text -- to build text copies of the documentation" X @echo " spell -- to spell check the documentation" X @echo " clean -- to remove files" X ### # installation dependencies ### install: man1 man3 X man1: ${MAN1FILES} X ${COPY} ${MAN1FILES} ${MANDIR}/${MAN1} X ${COPY} ${CATMAN1FILES} ${CATMANDIR}/${MAN1} X man3: ${MAN3FILES} X ${COPY} ${MAN3FILES} ${MANDIR}/${MAN3} X ${COPY} ${CATMAN3FILES} ${CATMANDIR}/${MAN3} X ### # include dependencies ### argtype.3: parseargs.1: parseargs.3: parsecntl.3: X X ### # maintenance dependencies ### clean: X ${DEL} ${MAN1FILES} ${MAN3FILES} ${CATMAN1FILES} ${CATMAN3FILES} X clobber: clean X ${DEL} *.txt X spell: ${INCS} ${SRCS}} X ${SPELL} ${SPELLFLAGS} ${INCS} ${SRCS} X print: ${MANFILES} ${INCS} X ${TROFF} ${TRFLAGS} ${SRCS} X text: ascii txt: ascii ascii: X ${NROFF} ${NRFLAGS} argtype.man3 | ${COL} ${COLFLAGS} >argtype3.txt X ${NROFF} ${NRFLAGS} parseargs.man1 | ${COL} ${COLFLAGS} >parseargs1.txt X ${NROFF} ${NRFLAGS} parseargs.man3 | ${COL} ${COLFLAGS} >parseargs3.txt X ${NROFF} ${NRFLAGS} parsecntl.man3 | ${COL} ${COLFLAGS} >parsecntl3.txt X view: ${MANFILES} ${INCS} X ${NROFF} ${NRFLAGS} ${SRCS} X SHAR_EOF chmod 0664 parseargs/doc/Makefile || echo 'restore of parseargs/doc/Makefile failed' Wc_c="`wc -c < 'parseargs/doc/Makefile'`" test 2300 -eq "$Wc_c" || echo 'parseargs/doc/Makefile: original size 2300, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= parseargs/doc/arg_macros.inc ============== if test -f 'parseargs/doc/arg_macros.inc' -a X"$1" != X"-c"; then echo 'x - skipping parseargs/doc/arg_macros.inc (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting parseargs/doc/arg_macros.inc (Text)' sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/arg_macros.inc' && .\"---------------------------------------------------------------------------- .\"-- This text was extracted using the following command: .\"-- xdoc -man -p '[ \t]*' -s ARGDESC-MACROS ../parseargs.h .\"---------------------------------------------------------------------------- .SH "ARGDESC MACROS" .PP The following macros are used to extract and query the attributes of a pointer to a preprocessed arg-descriptor: .\"--------------------------------------------- .IP "\fIarg_cname\fP(ad)" Return the single-character name of an argument. .\"--------------------------------------------- .IP "\fIarg_flags\fP(ad)" Return the argument flags of an argument. The flags themselves may be manipulated using the \s-1BTEST\s+1, \s-1BSET\s+1, and \s-1BCLEAR\s+1 macros defined in <useful.h>. .\"--------------------------------------------- .IP "\fIarg_type\fP(ad)" Return the pointer to the value-translation-routine of an argument. .\"--------------------------------------------- .IP "\fIarg_valp\fP(ad)" Return the pointer to the value of this argument. .\"--------------------------------------------- .IP "\fIarg_sname\fP(ad)" Return the string name of an argument. .\"--------------------------------------------- .IP "\fIarg_sdesc\fP(ad)" Return the description of an argument. If a description was supplied, the \fI\s-1ARGDESCRIBED\s+1\fP flag will be set and the description will immediately follow the terminating NUL byte of the string name. .\"--------------------------------------------- .IP "\fIARG_isDESCRIBED\fP(ad)" Evaluates to \s-1TRUE\s+1 only if an argument description was provided. .\"--------------------------------------------- .IP "\fIarg_description\fP(ad)" Return the description string (or an empty string if no description was given) for this argument. .\"--------------------------------------------- .IP "\fIARG_isPOSITIONAL\fP(ad)" Evaluates to \s-1TRUE\s+1 if this argument may be positionally matched. .\"--------------------------------------------- .IP "\fIARG_isPOSONLY\fP(ad)" Evaluates to \s-1TRUE\s+1 if this argument may only be positionally matched. .\"--------------------------------------------- .IP "\fIARG_isLIST\fP(ad)" Evaluates to \s-1TRUE\s+1 if this argument is an arglist. .\"--------------------------------------------- .IP "\fIARG_isVEC\fP(ad)" Evaluates to \s-1TRUE\s+1 if this argument is a vector. .\"--------------------------------------------- .IP "\fIARG_isMULTIVAL\fP(ad)" Evaluates to \s-1TRUE\s+1 if this argument is an arglist or a vector. .\"--------------------------------------------- .IP "\fIARG_isVALTAKEN\fP(ad)" Evaluates to \s-1TRUE\s+1 if this argument does NOT take a value. .\"--------------------------------------------- .IP "\fIARG_isGIVEN\fP(ad)" Evaluates to \s-1TRUE\s+1 if this argument was given on the command-line. .\"--------------------------------------------- .IP "\fIARG_isVALGIVEN\fP(ad)" Evaluates to \s-1TRUE\s+1 if the argument value was given on the command-line. .\"--------------------------------------------- .IP "\fIARG_isREQUIRED\fP(ad)" Evaluates to \s-1TRUE\s+1 if this argument is required. .\"--------------------------------------------- .IP "\fIARG_isVALOPTIONAL\fP(ad)" Evaluates to \s-1TRUE\s+1 if the argument value is optional. .\"--------------------------------------------- .IP "\fIARG_isVALSEPARATE\fP(ad)" Evaluates to \s-1TRUE\s+1 if the argument value is optional. .\"--------------------------------------------- .IP "\fIARG_isHIDDEN\fP(ad)" Evaluates to \s-1TRUE\s+1 if this argument is omitted from usage messages. .\"--------------------------------------------- SHAR_EOF chmod 0664 parseargs/doc/arg_macros.inc || echo 'restore of parseargs/doc/arg_macros.inc failed' Wc_c="`wc -c < 'parseargs/doc/arg_macros.inc'`" test 3591 -eq "$Wc_c" || echo 'parseargs/doc/arg_macros.inc: original size 3591, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= parseargs/doc/argdesc.inc ============== if test -f 'parseargs/doc/argdesc.inc' -a X"$1" != X"-c"; then echo 'x - skipping parseargs/doc/argdesc.inc (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting parseargs/doc/argdesc.inc (Text)' sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/argdesc.inc' && .\"---------------------------------------------------------------------------- .\"-- This text was extracted using the following command: .\"-- xdoc -man -p '[ \t]*' -t STRUCT=ARGDESC ../parseargs.h .\"---------------------------------------------------------------------------- .SH "THE ARGUMENT STRUCTURE" The basic type used by the \fIparseargs\fP library is the argument descriptor (or "argdesc" for short). An \s-1ARGDESC\s+1 structure is used to describe a command-line argument. Each command line argument contains various fields which need to be set and/or queried by the programmer. The individual fields of an \s-1ARGDESC\s+1 structure are desribed below: .\"--------------------------------------------- .IP "\fIchar ad_name;\fP" This is a single character which corresponds to the option-letter (case-sensitive) from the command-line that matches the argument described by this structure. Positional-arguments are denoted by putting a a space character in this field. .\"--------------------------------------------- .IP "\fIargMask_t ad_flags;\fP" This field contains the various bitflags that describe the semantics of this argument. See the \fB\s-1ARGUMENT FLAGS\s+1\fP section for more information on the possible combinations of bitmasks for this field. .\"--------------------------------------------- .IP "\fIargTypePtr_t ad_type;\fP" This field is a pointer to a type conversion function (such as the ones provided in \fIargtype\fP(3). The type conversion function is responsible for verifying the validity of the argument, allocating any necessary storage for its internal representation, and converting the command-line argument into its required internal form. The type conversion function used may be one of the pre-defined \fIargtype\fP(3) functions. The function is given three parameters: The first is a pointer to the \s-1ARGDESC\s+1 struct in question, the second is the string-value (if any) supplied on the command-line, and the third is a boolean value that is \s-1TRUE\s+1 only if the second parameter points to temporary storage (and hence may need to be copied). In the case of \fIparseargs\fP(1) this field must correspond to the name of one of the argument type functions described in \fIargtype\fP(3). .\"--------------------------------------------- .IP "\fIARBPTR ad_valp;\fP" This field is a generic pointer to the storage used to represent the internal value of the command-line argument. It may be a pointer to a number, a boolean value, a string, a list, or anything else for which there exists a corresponding arg-type function to use in the \fIad_type\fP field. In the case of of \fIparseargs\fP(1) this field must be the name of the corresponding shell variable which eventually hold the value of the argument given on the command-line. .\"--------------------------------------------- .IP "\fIconst char *ad_prompt;\fP" This field contains the long-name of the argument and an optional description (the description must be separated from the long-name by at least one whitespace characters and may optionally be enclosed in a set of balanced delimiters (such as parentheses, curly-braces, square-brackets, or angle-brackets. If the long-name contains any uppercase characters, then the substring of long-name consisting of all uppercase characters is used as the argument name and the entire long-name is used as the name of the argument-value (if a value my be supplied). The long-name may be matched by supplying a unique prefix of either the argument name or the argument-value name. SHAR_EOF chmod 0664 parseargs/doc/argdesc.inc || echo 'restore of parseargs/doc/argdesc.inc failed' Wc_c="`wc -c < 'parseargs/doc/argdesc.inc'`" test 3543 -eq "$Wc_c" || echo 'parseargs/doc/argdesc.inc: original size 3543, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= parseargs/doc/argflags.inc ============== if test -f 'parseargs/doc/argflags.inc' -a X"$1" != X"-c"; then echo 'x - skipping parseargs/doc/argflags.inc (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting parseargs/doc/argflags.inc (Text)' sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/argflags.inc' && .\"---------------------------------------------------------------------------- .\"-- This text was extracted using the following command: .\"-- xdoc -man -p '[ \t]*' -s ARG-FLAGS ../parseargs.h .\"---------------------------------------------------------------------------- .SH "ARGUMENT FLAGS" .PP These are the possible bitmasks that may be turned ON or OFF in the \fIad_flags\fP field of an \fI\s-1ARGDESC\s+1\fP structure. .\"--------------------------------------------- .IP "\fI\s-1ARGOPT\s+1\fP" This flag is actually a dummy flag (i.e. it is the default). This flag specifies that the command-line argument is optional (need not appear on the command-line). It is only needed if no other flags are used to define the given argument. If other flags are given and \fI\s-1ARGREQ\s+1\fP is \s-1NOT\s+1 one of them, then \fI\s-1ARGOPT\s+1\fP is always assumed. .\"--------------------------------------------- .IP "\fI\s-1ARGREQ\s+1\fP" The associated command argument is required on the command-line. .\"--------------------------------------------- .IP "\fI\s-1ARGPOS\s+1\fP" The associated command argument is positonal. The difference between using this flag to indicate a positional argument and between using a blank in the \fIad_name\fP field to indicate a positional arguments is the following: If this flag is set but the \fIad_name\fP of the argument is non-blank, then this argument may be matched either positionally or by keyword. If the \fIad_name\fP field is blank, then this argument may only be matched positionally. .\"--------------------------------------------- .IP "\fI\s-1ARGNOVAL\s+1\fP" The associated command argument takes no value (as in "\fB\-x\fI value\fR"); Its mere presence (or lack thereof) on the command-line is sufficient to determine the necessary action(s) to take (as in "\fB\-x\fP"). Boolean argument types and Pseudo-argument types automatically default to \fI\s-1ARGNOVAL\s+1\fP. .\"--------------------------------------------- .IP "\fI\s-1ARGVALOPT\s+1\fP" This flag is used to indicate that the command-line argument takes a value (as in "\fB\-s\fI string\fR" or "\fB/str\fP=\fIstring\fP") but that the value to this command-line argument is \s-1NOT\s+1 required (hence simply "\fB\-s\fP" or "\fB/str\fP" is also permissable). .\"--------------------------------------------- .IP "\fI\s-1ARGVALREQ\s+1\fP" Another "dummy" flag. Unless \fI\s-1ARGNOVAL\s+1\fP or \fI\s-1ARGVALOPT\s+1\fP is specified, \fI\s-1ARGVALREQ\s+1\fP is always assumed. This flag indicates that the value to a command-line argument is required (hence "\fB\-s\fI string\fR" is okay but just "\fB\-s\fP" is not). .\"--------------------------------------------- .IP "\fI\s-1ARGHIDDEN\s+1\fP" Don't display this argument in usage messages but still attempt to match it against strings given on the command-line. .\"--------------------------------------------- .IP "\fI\s-1ARGLIST\s+1\fP" A variable number of values are used for this argument (and hence may use more than one or two argv elements from the command-line as in "\fB\-l\fI val1 val2\fR ..."). The list of values must be stored in an .I ArgList structure (\s-1NOT\s+1 a vector structure), an the corresponding argument-type function should be one of the \fIlistXxxx\fP functions. .\"--------------------------------------------- .IP "\fI\s-1ARGVEC\s+1\fP" A variable number of values are used for this argument (and hence may use more than one or two argv elements from the command-line as in in "\fB\-v\fI val1 val2\fR ..."). The list of values must be stored in a vector structure (\s-1NOT\s+1 an \fIArgList\fP structure). .\"--------------------------------------------- .PP The following bitmasks may also be present, but, unlike the above masks which must be specified by the programmer at initialization time, the following masks must only be read (never set) by the programmer. They may be queried by using the \fIpc_\s-1ARGFLAGS\s+1\fP function code and the mode \fIpc_\s-1READ\s+1\fP with \fIparsecntl\fP(3). .\"--------------------------------------------- .IP "\fI\s-1ARGGIVEN\s+1\fP" The argument \s-1WAS\s+1 given on the command-line. .\"--------------------------------------------- .IP "\fI\s-1ARGVALGIVEN\s+1\fP" The value for this argument was given on the command-line. .\"--------------------------------------------- .IP "\fI\s-1ARGVALSEP\s+1\fP" The value to this argument was supplied in a separate argv element from the argument itself (as in "\fB\-x\fI value\fR" as opposed to "\fB\-x\fIvalue\fR"). .\"--------------------------------------------- .IP "\fI\s-1ARGKEYWORD\s+1\fP" This argument was matched as a keyword (long-form) on the command-line and not as a single character. .\"--------------------------------------------- .IP "\fI\s-1ARGDESCRIBED\s+1\fP" This argument was given a description by the programmer at initialization. .\"--------------------------------------------- .IP "\fI\s-1ARGCOPYF\s+1\fP" This flag is only used for lists and vectors (multivalued arguments) and is used on a per-item basis. If it is set, it means that the corresponding value in the vector/list required space to be allocated (such as the duplication of a temporary string). .\"--------------------------------------------- SHAR_EOF chmod 0664 parseargs/doc/argflags.inc || echo 'restore of parseargs/doc/argflags.inc failed' Wc_c="`wc -c < 'parseargs/doc/argflags.inc'`" test 5228 -eq "$Wc_c" || echo 'parseargs/doc/argflags.inc: original size 5228, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= parseargs/doc/argtype.man3 ============== if test -f 'parseargs/doc/argtype.man3' -a X"$1" != X"-c"; then echo 'x - skipping parseargs/doc/argtype.man3 (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting parseargs/doc/argtype.man3 (Text)' sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/argtype.man3' && .\" $Header: argtype.3,v 1.0 90/11/17 11:34:06 brad Exp $ .TH ARGTYPE 3 .SH NAME argtype \- argument type functions used by parseargs(3) .SH SYNOPSIS #include <parseargs.h> .PP .nf \s-1BOOL\s+1 argUsage( argdesc, argstr, copyf ); \s-1BOOL\s+1 argEnd( argdesc, argstr, copyf ); \s-1BOOL\s+1 argDummy( argdesc, argstr, copyf ); \s-1BOOL\s+1 argBool( argdesc, argstr, copyf ); \s-1BOOL\s+1 argSBool( argdesc, argstr, copyf ); \s-1BOOL\s+1 argUBool( argdesc, argstr, copyf ); \s-1BOOL\s+1 argTBool( argdesc, argstr, copyf ); \s-1BOOL\s+1 argChar( argdesc, argstr, copyf ); \s-1BOOL\s+1 argStr( argdesc, argstr, copyf ); \s-1BOOL\s+1 argInt( argdesc, argstr, copyf ); \s-1BOOL\s+1 argShort( argdesc, argstr, copyf ); \s-1BOOL\s+1 argLong( argdesc, argstr, copyf ); \s-1BOOL\s+1 argFloat( argdesc, argstr, copyf ); \s-1BOOL\s+1 argDouble( argdesc, argstr, copyf ); \s-1BOOL\s+1 listStr( argdesc, argstr, copyf ); \s-1void\s+1 listFree( arglist ); \s-1void\s+1 vecFree( argvec, type ); \s-1void\s+1 vecDeepFree( argvec, type ); X \s-1ARGDESC\s+1 *argdesc; char *argstr; \s-1BOOL\s+1 copyf; ArgList *arglist; .fi .SH "DESCRIPTION" .PP Each of these converts a parameter value to the internal form, including validity checking. Their parameters and return values all behave similarly. One of these routines are called when an argunent of that particular type is matched by one of the argument parsing function in \fIparseargs\fP(3). When such an argument is matched, its argument translation routines is invoked and is passed (1) the address of the argument descriptor for the matched argument, (2) the possible argument string for that matched argument, and (3) a boolean filed that is \s-1TRUE\s+1 only if the second parameter points to temporary storage (indicating that some copying may need to be done instead of just pointing to the same object). X Once the argument translation routine is invoked, it is responsible for converting the argument string to the desired internal form (perhaps a number), and assigning the resultant value to the \fIarg_valp(ad)\fP field of the argument descriptor (this includes handling any necessary (re)allocation if the matched argument has the \s-1ARGVEC\s+1 flag enabled). If the argument is an \s-1ARGVEC\s+1 or \s-1ARGLIST\s+1 then the routine is responsible for allocating any space, copying the arg-flags to the value-specific flags, and setting the \s-1ARGCOPYF\fP flag for the value if it needs to be allocated as well. X .SH "RETURN VALUE" .IP "TRUE" 8 The conversion was successful and the entire value was used. X .IP "FALSE" 8 The conversion failed. The reason for failure should be diagnosed using \fIusrerr\fP(3). X .IP "-\fIN\fP" 8 The conversion was successful but only \fIN\fP characters of the value were used, the remaining characters may still match other arguments. X .SH "PSEUDO-TYPES" .PP .I ArgUsage is used to specify an argument that causes the command usage to be printed. X .I ArgDummy is used to force an item to show up in usage-messages but the item itself is never matched against any argumenmts from the command-line. X .I ArgEnd is used by Amiga style command-lines to indicate an argument that forces all remaining arguments to be considered positional args. X These three are dummy functions. The routines themselves do nothing of importance, we just need to have their addresses available for identification in the corresponding command-line styles. .SH "STRING-TYPES" .PP \fIArgStr\fP is one of the few argument translation routines that actually uses the \fIcopyf\fP flag. If \fIcopyf\fP is true then the string is duplicated. X \fIArgStr\fP assigns the given string (or a copy of it) to the value referenced by \fIarg_valp(ad)\fP (unless the argument is a vector in which case the given string is appended to the end). X \fIArgStr\fP ensures that the very last item in a vector of strings (the one accessed as \f4vec.array[ vec.count ]\fP) will always be \s-1NULL\s+1. .SH "CHARACTER-TYPES" .PP .I ArgChar assigns the given character to the value referenced by \fIarg_valp(ad)\fP (unless the argument is a vector in which case the given character is appended to the end). X .I ArgChar ensures that the very last item in a vector of character (the one accessed as \f4vec.array[ vec.count ]\fP) will always be a \s-1NULL\s+1 byte so that the resulting vector may also be used as a \s-1NULL\s+1 terminated string. X Unlike \fIargStr\fP, \fIargChar\fP will translate character escape sequences such as `\\n' and `\\012'. .SH "INTEGER-TYPES" .PP Each of these functions converts the given string to the desired integral type. The value may be specified as an octal number by specifying the first digit to be 0. Similarly, If the first two characters are `0x' then the number is treated as hexadecimal. .SH "FLOATING-POINT-TYPES" .PP Each of these functions converts the given string to the desired floating-point type. .SH "BOOLEAN-TYPES" .PP \fIArgBool\fP and \fIargSBool\fP set a boolean value (if no value is given). \fIArgUBool\fP unsets a boolean value (if no value is given). \fIArgTBool\fP toggles a boolean value (if no value is given). If a value is supplied to any of these routines, then the string is looked up in a table and assigned the corresponding value. X If a value is supplied for an argument that was matched via its single character name and is part of the same argv element as the argument-name (so that both \fBARGKEYWORD\fP and \fBARGVALSEP\fP are not set), then only the first character of the value is used (unless it is not found in our table, in which case the value is ignored and the default action is taken). The table used for single-character-options is the following: .IP "`0' or `-'" The corresponding boolean flag is set to \s-1FALSE\s+1. .IP "`1' or `+'" The corresponding boolean flag is set to \s-1TRUE\s+1. .IP "`^' or `~'" The corresponding boolean flag is toggled. .PP The possible argument strings for long-options (keywords) are as follows (case-insensitive): .IP "``0'', ``-'', ``OFF'', or ``FALSE''" The corresponding boolean flag is set to \s-1FALSE\s+1. .IP "``1'', ``+'', ``ON'', or ``TRUE''" The corresponding boolean flag is set to \s-1TRUE\s+1. .SH LIST TYPES .PP The \fIlistStr\fP argument translation routine is only intended for use on behalf of arguments that have the \s-1ARGLIST\s+1 flag enabled. It will allocate space for a new node (and for the new string if \fIcopyf\fP is set) and append it to the end of the list. The argument-list may later be deallocated by invoking the function \fIlistFree\fP and passing it the address of the first item in the list. X .PP \fIVecFree\fP is a macro that is used to deallocate argument-vectors. It will free the array and flags fields of a vector, set them to \s-1NULL\s+1, and set the count field to zero. \fIVecDeepFree\fP is a macro that is similar to \fIvecFree\fP but will additionally look at each item in the array; any component of the array that had \s-1ARGCOPYF\s+1 enabled will also be deallocated. Both macros are given the vector structure to free followed by the type of the items in the vector. .SH SEE ALSO .IR parseargs (3), .IR parseargs (1), SHAR_EOF chmod 0664 parseargs/doc/argtype.man3 || echo 'restore of parseargs/doc/argtype.man3 failed' Wc_c="`wc -c < 'parseargs/doc/argtype.man3'`" test 7204 -eq "$Wc_c" || echo 'parseargs/doc/argtype.man3: original size 7204, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= parseargs/doc/argvalopt.inc ============== if test -f 'parseargs/doc/argvalopt.inc' -a X"$1" != X"-c"; then echo 'x - skipping parseargs/doc/argvalopt.inc (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting parseargs/doc/argvalopt.inc (Text)' sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/argvalopt.inc' && .\"---------------------------------------------------------------------------- .\"-- This text was extracted using the following command: .\"-- xdoc -man -p '[ \t]*' -s ARGVALOPT ../parseargs.c .\"---------------------------------------------------------------------------- .SH OPTIONS WITH OPTIONAL ARGUMENTS .PP Options that may take an optional argument need special consideration. The shell programmer needs to know whether or not the option was given, and (if given) if it was accompanied by an argument. In order to accommodate this need, \fBparseargs\fP will set an additional shell variable for each argument that is given the \s-1ARGVALOPT\s+1 flag if it is supplied on the command line \fIregardless of whether or not it was accompanied by its optional argument\fP. If the user has defined an option which may optionally take an argument and the option appears on the command line \fIwith or without\fP its associated argument, then the shell variable \fI<name>\fP\f4_flag\fP will be assigned the value ``\f4TRUE\fP'' (or the value supplied with the \fB\-T\fP option to \fBparseargs\fP) where \fI<name>\fP is the name of the shell variable associated with the option in the argument description string. SHAR_EOF chmod 0664 parseargs/doc/argvalopt.inc || echo 'restore of parseargs/doc/argvalopt.inc failed' Wc_c="`wc -c < 'parseargs/doc/argvalopt.inc'`" test 1216 -eq "$Wc_c" || echo 'parseargs/doc/argvalopt.inc: original size 1216, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= parseargs/doc/bugs.inc ============== if test -f 'parseargs/doc/bugs.inc' -a X"$1" != X"-c"; then echo 'x - skipping parseargs/doc/bugs.inc (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting parseargs/doc/bugs.inc (Text)' sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/bugs.inc' && .\"---------------------------------------------------------------------------- .\"-- This text was extracted using the following command: .\"-- xdoc -man -n -p '[ \t]*' -I BUGS ../parseargs.c .\"---------------------------------------------------------------------------- .SH BUGS .PP It does not make sense to use any arguments of type \fIargTBool\fP since \fBparseargs\fP currently has no way of knowing what the initial value of the variable is. For this reason, \fIargTBool\fP is not recognized as a valid argument type (even though it is used by \fIparseargs\fP\s-1\^(3)\s+1\|). By the same token, since the user cannot create their own arguments types on the fly from a shell-script, \fI\s-1ARGNOVAL\s+1\fP is not recognized as a valid argument flag. .PP Commas will not be interpreted properly if any field in the argument specification string contains double quotes that are nested inside of double quotes, or single quotes that are nested inside of single quotes. .PP Inside the argument specification string, any repeated string of commas that does not appear inside of double or single quotes will be treated as a single comma. .PP Text descriptions for argument entries are automatically formatted in usage messages. Any attempt by the user to include tabs and/or newlines in the description will cause it to be formatted improperly. .PP \fIParseargs\fP cannot properly preserve any newlines in shell variables if the \fBeval\fP command is used to read its output (this is a shortcoming of the eval command, not of parseargs). If the user is concerned about this particular case, then the user should redirect the output from \fBparseargs\fP to a temporary file and use the \fBsource\fP command in \fIcsh\fP or the dot command (`\fB.\fP') in sh and ksh, to interpret the results; otherwise, newlines will be translated into spaces, or characters following a newline may be lost, in any variables that are set by \fBparseargs\fP. .PP Parseargs(1) is subject to the same caveats as parseargs(3). Refer to the \s-1CAVEATS\s+1 section of the parseargs(3) manual page(s) for more information. SHAR_EOF chmod 0664 parseargs/doc/bugs.inc || echo 'restore of parseargs/doc/bugs.inc failed' Wc_c="`wc -c < 'parseargs/doc/bugs.inc'`" test 2103 -eq "$Wc_c" || echo 'parseargs/doc/bugs.inc: original size 2103, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= parseargs/doc/caveats.inc ============== if test -f 'parseargs/doc/caveats.inc' -a X"$1" != X"-c"; then echo 'x - skipping parseargs/doc/caveats.inc (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting parseargs/doc/caveats.inc (Text)' sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/caveats.inc' && .\"---------------------------------------------------------------------------- .\"-- This text was extracted using the following command: .\"-- xdoc -man -n -p '[ \t]*' -I CAVEATS ../xparse.c .\"---------------------------------------------------------------------------- .SH CAVEATS .PP Because of the way argument parsing is implemented under \s-1UNIX\s+1, \s-1MS-DOS\s+1, and \s-1OS/2\s+1, option arguments which contain a leading dash (`\-') (or whatever the option prefix character is defined to be) may \fInot\fP be specified as a separate argument on the command line, it must be part of the same argument. That is to say that if a program has a \fB\-f\fP option that requires a string argument, then the following: .sp 4p .RS .ft 4 \-f\-arg .ft R .RE .sp 4p will properly assign the string ``\fB\-arg\fP'' to the option whereas the following: .sp 4p .RS .ft 4 \-f\0\-arg .RE .sp 4p will be interpreted by \fIparseargs\fP as two option strings: the first of which (``\fB\-f\fP'') is missing a required argument and the second of which (``\fB\-arg\fP'') will most likely be flagged as an invalid option. .PP Similarly, if the user requires an \s-1\fIARGLIST\fP\s+1 option to take multiple arguments with leading dashes then the following method must be used: It is a ``feature'' of \fIparseargs\fP that \s-1\fIARGLIST\fP\s+1 arguments are always appended to the current list of arguments for the given option. Thus, if ``\fB\-f\fP'' is an option taking a list of arguments, then the following are all equivalent: .sp 8p .RS .ft 4 \-farg1 arg2 .sp 4p \-f arg1 arg2 .sp 4p \-farg1 \-farg2 .sp 4p \-f arg1 \-f arg2 .ft R .RE .sp 8p Hence multiple ``leading dash'' arguments may specified as follows: .sp 4p .RS .ft 4 \-f\-dash_arg1 \-f\-dash_arg2 ... .ft R .RE SHAR_EOF chmod 0664 parseargs/doc/caveats.inc || echo 'restore of parseargs/doc/caveats.inc failed' Wc_c="`wc -c < 'parseargs/doc/caveats.inc'`" test 1768 -eq "$Wc_c" || echo 'parseargs/doc/caveats.inc: original size 1768, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= parseargs/doc/cmd_macros.inc ============== if test -f 'parseargs/doc/cmd_macros.inc' -a X"$1" != X"-c"; then echo 'x - skipping parseargs/doc/cmd_macros.inc (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting parseargs/doc/cmd_macros.inc (Text)' sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/cmd_macros.inc' && .\"---------------------------------------------------------------------------- .\"-- This text was extracted using the following command: .\"-- xdoc -man -p '[ \t]*' -s CMD-MACROS ../parseargs.h .\"---------------------------------------------------------------------------- .SH "CMD MACROS" Parseargs.h defines a set of macros to allow a more "self documenting" approach to declaring argument-descriptor arrays. The "old-style" is still accepted (but if used it is recommended that the \s-1STARTOFARGS\s+1 macro is used in conjunction with \s-1ENDOFARGS\s+1). An example use of these macros (which, with one exception, all begin with ``\s-1CMD\s+1'') follows: .RS .nf .ft 4 #include <parseargs.h> X static BOOL bflag = FALSE; static char *arg1 = CHARNULL; static char *arg2 = CHARNULL; X static X CMD_OBJECT X MyCmd X X CMD_NAME X "mycmd -- one line statement of purpose" X X CMD_DESCRIPTION X "Mycmd will try really really hard to run without errors \\ and do whatever the heck it is supposed to do. If (God forbid) \\ something should actually go wrong it will say so." X X CMD_ARGUMENTS X 'H', ARGOPT, argUsage, __ NULL, X "Help -- display usage and quit", X X 'b', ARGOPT, argSBool, __ &bflag, X "bflag -- turn on `b'-mode (whatever that is)", X X ' ', ARGREQ, argStr, __ &arg1, X "arg1 -- first argument to this spiffy program", X X ' ', ARGOPT, argStr, __ &arg2, X "arg2 -- optional second argument to this spiffy program", X X END_ARGUMENTS X CMD_END X main( int argc, char *argv[] ) { X (void) parseargs( argv, MyCmd ); X (void) dostuff(); X exit( 0 ); } .ft R .fi .RE SHAR_EOF chmod 0664 parseargs/doc/cmd_macros.inc || echo 'restore of parseargs/doc/cmd_macros.inc failed' Wc_c="`wc -c < 'parseargs/doc/cmd_macros.inc'`" test 1627 -eq "$Wc_c" || echo 'parseargs/doc/cmd_macros.inc: original size 1627, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= parseargs/doc/defargs.inc ============== if test -f 'parseargs/doc/defargs.inc' -a X"$1" != X"-c"; then echo 'x - skipping parseargs/doc/defargs.inc (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting parseargs/doc/defargs.inc (Text)' sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/defargs.inc' && .\"---------------------------------------------------------------------------- .\"-- This text was extracted using the following command: .\"-- xdoc -man -p '[ \t]*' -s DEFAULT-ARGUMENT ../xparse.c .\"---------------------------------------------------------------------------- .SH "DEFAULT ARGUMENT DESCRIPTOR" .PP Each argdesc-array has an initial default argument list (which may be reset using the pc_DEFARGS function code with parsecntl). This initial default argument-list contains `?' and `H' which may be used as single character keywords to display command-usage for all command-line styles. Similarly, ``?'', ``H'', and ``Help'' may be used as long-keywords to display command-usage for all command-line styles. In Addition, for \s-1VMS\s+1 style commands, the qualifiers \fB\s-1/INPUT\s+1=\fIfile\fR, \fB\s-1/OUTPUT\s+1=\fIfile\fR, and \fB\s-1/ERROR\s+1=\fIfile\fR, may be used to redirect stdin, stdout, and stderr (respectively) to a file. For Amiga\s-1DOS\s+1 style commands, the keyword ``ENDKWDS'' may be used to disable parsing for any more keywords on the command-line. SHAR_EOF chmod 0664 parseargs/doc/defargs.inc || echo 'restore of parseargs/doc/defargs.inc failed' Wc_c="`wc -c < 'parseargs/doc/defargs.inc'`" test 1093 -eq "$Wc_c" || echo 'parseargs/doc/defargs.inc: original size 1093, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= parseargs/doc/env_args.inc ============== if test -f 'parseargs/doc/env_args.inc' -a X"$1" != X"-c"; then echo 'x - skipping parseargs/doc/env_args.inc (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting parseargs/doc/env_args.inc (Text)' sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/env_args.inc' && .\"---------------------------------------------------------------------------- .\"-- This text was extracted using the following command: .\"-- xdoc -man -n -p '[ \t]*' -I DESCRIPTION -f get_user_defaults ../xparse.c .\"---------------------------------------------------------------------------- .SH "SUPPLYING DEFAULT ARGUMENTS" Programs that use \fIparseargs\fP may be given default arguments under UNIX and PCs through the use of environment variables (symbols are used for VMS systems). If a C-program or shell-script uses parseargs to implement a command named ``\fIcmd\fP'' then the environment variable ``\s-1CMD_ARGS\s+1'' will be parsed for any "default" arguments before the command-line is parsed. The command-line will over-ride any options that are specified in this environment variable (except that \s-1ARGLIST\s+1s and \s-1ARGVEC\s+1s set in ``\s-1CMD_ARGS\s+1'' will be appended from the command-line X It is important to note that the contents of the ``\s-1\fICMD\fP_ARGS\s+1'' environment variable are NOT expanded by the shell and hence any special characters (such as quotes or back-slashes) will NOT be escaped or removed by \fIparseargs\fP. Furthermore, it will not be possible to try and use a tab, space, or newline character in the environment variable as anything other than an argument separator. X Lastly, parts of an option specification in ``\s-1CMD_ARGS\s+1'' may NOT be continued on the command-line. As an example, if \fB\-f\fP requires an argument and \s-1CMD_ARGS\s+1="\-f", then the command-line "\fIcmd bah\fP" will NOT assign "\fIbah\fP" as the argument to \fB\-f\fP but will instead complain about a missing argument for \fB\-f\fP. Similarly, if \fB\-l\fP takes a list of arguments and \s-1CMD_ARGS\s+1="\-l item1 item2", then the command-line "\fIcmd bah\fP", will NOT assign "\fIbah\fP" to the end of the list containing "item1" and "item2" but will instead treat "\fIbah\fP" as the first positional parameter on the command-line. SHAR_EOF chmod 0664 parseargs/doc/env_args.inc || echo 'restore of parseargs/doc/env_args.inc failed' Wc_c="`wc -c < 'parseargs/doc/env_args.inc'`" test 1979 -eq "$Wc_c" || echo 'parseargs/doc/env_args.inc: original size 1979, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= parseargs/doc/env_parse.inc ============== if test -f 'parseargs/doc/env_parse.inc' -a X"$1" != X"-c"; then echo 'x - skipping parseargs/doc/env_parse.inc (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting parseargs/doc/env_parse.inc (Text)' sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/env_parse.inc' && .\"---------------------------------------------------------------------------- .\"-- This text was extracted using the following command: .\"-- xdoc -man -n -p '[ \t]*' -I DESCRIPTION -f get_parse_env ../xparse.c .\"---------------------------------------------------------------------------- .SH PARSING BEHAVIOR The programmer may control parsing behavior through the use of .IR parsecntl (3). The user may set his (or her) own desired parsing behavior through the use of the ``\s-1PARSECNTL\s+1'' environment variable. By indicating any number of flags (possibly negated) the user will directly modify the behavior of the parseargs library. Flags may be combined by placing a `+' or `|' character in between flags. A switch is negated by immediately preceding it with a `!' or `-' character. The possible ``flags'' are given by the following table. Flags are case-insensitive. .sp 4p .IP "\fIPrompt\fP" Prompt the user for any missing arguments that are required on the command-line. No special escaping or quoting is performed on the user input. Required arguments that expect a list of values will be repeatedly prompted for (one item per line) until a blank line (followed by a carriage return) is entered. .\"---------------------- .IP "\fIIgnore\fP" Ignore any unrecognized or improperly specified command-line arguments and continue execution of the program. Normally, if an argument is unmatched (or is improperly specified), a usage message is printed program execution is terminated. .\"---------------------- .IP "\fIOptsOnly\fP" Under UNIX, setting this flag will disable the parsing of long-option syntax. This will cause all arguments starting with '+' to always be treated as a positional parameter (instead of a long-option). .\"---------------------- .IP "\fIKwdsOnly\fP" Under UNIX, setting this flag disables the parsing of single-character options. This will cause all arguments starting with '-' to always be treated as a positional parameter (instead of an option). .\"---------------------- .IP "\fILoptsOnly\fP" Same as \fIKwdsOnly\fP. .\"---------------------- .IP "\fIFlags1st\fP" Setting this flag causes the parseargs library to force any and all non-positional arguments to be specified before any positional ones. As an example, under UNIX, if this flag is SET then parseargs will consider the command line "cmd -x arg" to consist of one option and one positional argument; however the command line "cmd arg -x" would be considered to consist of two positional arguments (the -x option will be unmatched). X If this flag is UNSET, then both of the previous examples are considered to consist of one option and one positional argument. .\"---------------------- .IP "\fICaseIgnore\fP" Setting this flag cause character-case to be ignored when attempting to match single-character argument names (i.e. causes "-i" and "-I" will be considered equivalent). .sp 4p .PP If the environment variable ``\s-1PARSECNTL\s+1'' is empty or undefined, then parsing behavior set by the programmer is used. If the programmer has not explicitly used .IR parsecntl (3) to modify the parsing behavior will be ``!Prompt + !Ignore'' for Unix MS-DOS, OS/2, and AmigaDOS systems, and ``Prompt'' for VMS systems. SHAR_EOF chmod 0664 parseargs/doc/env_parse.inc || echo 'restore of parseargs/doc/env_parse.inc failed' Wc_c="`wc -c < 'parseargs/doc/env_parse.inc'`" test 3224 -eq "$Wc_c" || echo 'parseargs/doc/env_parse.inc: original size 3224, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= parseargs/doc/env_usage.inc ============== if test -f 'parseargs/doc/env_usage.inc' -a X"$1" != X"-c"; then echo 'x - skipping parseargs/doc/env_usage.inc (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting parseargs/doc/env_usage.inc (Text)' sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/env_usage.inc' && .\"---------------------------------------------------------------------------- .\"-- This text was extracted using the following command: .\"-- xdoc -man -n -p '[ \t]*' -I DESCRIPTION -f get_usage_env ../xparse.c .\"---------------------------------------------------------------------------- .SH USAGE MESSAGES Through the use of an environment variable (or a VMS symbol), the user may control the syntax and the verbosity of the command-usage messages that are printed by \fIparseargs\fP. The desired level of verbosity may be set by defining the environment variable ``\s-1USAGECNTL\s+1" to be a combination of strings (case insensitive). The value of each string controls one of three different ``modes'' of behavior in the displaying of usage messages: The first ``mode'' is ``verbose'' mode, which controls whether or not a detailed description of each argument should accompany the usual command-line sysnopsis. If verbose mode is ``off'', then only a command-line synopsis is printed (this is also refferred to as ``terse'' mode). The other two ``modes'' control the displaying of option syntax and long-option syntax. A mode may be explicitly disabled by preceding its corresponding string with the `!' character. The ``modes'' which correspond to the possible values of the ``\s-1USAGECNTL\s+1'' environment variable are given by the following table. .sp 4p .\"--------------------------------------- .IP "\fIQuiet\fP" No usage message of any kind is displayed. .\"--------------------------------------- .IP "\fISilent\fP" Same as \fIQuiet\fP. .\"--------------------------------------- .IP "\fIPaged\fP" The usage message is piped to a pager. The pager used is named by the ``\s-1USAGE_PAGER\s+1'' environment variable. If this variable is unset or empty (or is not the name of an executable program) then the pager named by the ``\s-1PAGER\s+1'' environment variable us used. If this variable is unset or empty (or is not the name of an executable program) then \fI/usr/ucb/more\fP is used. .\"--------------------------------------- .IP "\fIDescription\fP" The command description is printed. .\"--------------------------------------- .IP "\fITerse\fP" Terse mode, just print command-line synopsis. .\"--------------------------------------- .IP "\fIVerbose\fP" Verbose mode, print descriptions for each argument .\"--------------------------------------- .IP "\fIOptions\fP" Option syntax is displayed. .\"--------------------------------------- .IP "\fILongOpts\fP" Long-option syntax is displayed. .\"--------------------------------------- .IP "\fIKeyWords\fP" Same as \fILongOpts\fP. .\"--------------------------------------- .sp 4p .PP If the environment variable ``\s-1USAGECNTL\s+1'' is empty or undefined, then the default usage level (which is presently ``Verbose + Options'') will be used. SHAR_EOF chmod 0664 parseargs/doc/env_usage.inc || echo 'restore of parseargs/doc/env_usage.inc failed' Wc_c="`wc -c < 'parseargs/doc/env_usage.inc'`" test 2820 -eq "$Wc_c" || echo 'parseargs/doc/env_usage.inc: original size 2820, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= parseargs/doc/fparseargs3.inc ============== if test -f 'parseargs/doc/fparseargs3.inc' -a X"$1" != X"-c"; then echo 'x - skipping parseargs/doc/fparseargs3.inc (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting parseargs/doc/fparseargs3.inc (Text)' sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/fparseargs3.inc' && .\"---------------------------------------------------------------------------- .\"-- This text was extracted using the following command: .\"-- xdoc -man -n -p '[ \t]*' -I DESCRIPTION -f fparseargs ../xparse.c .\"---------------------------------------------------------------------------- .PP Given a readable input stream and an argdesc array, \fIfparseargs\fP will parse arguments in a file in much the same manner as \fIparseargs\fP. A maximum-line length of 255 characters is imposed. NO ``escaping'' of any kind is performed. Comments of a limited form are permitted: if the first non-whitespace character on a line is a '#' (or '!' for \s-1VMS\s+1) then that entire line is considered a comment and is ignored. If a value is provided for an argument that is NOT a list or a vector, then the value MUST be on the same line as the argument (in other words, ``\fB\-v\fI val\fR'' is fine but ``\fB\-v\f4\\n\fIval\fR'' is a not). SHAR_EOF chmod 0664 parseargs/doc/fparseargs3.inc || echo 'restore of parseargs/doc/fparseargs3.inc failed' Wc_c="`wc -c < 'parseargs/doc/fparseargs3.inc'`" test 937 -eq "$Wc_c" || echo 'parseargs/doc/fparseargs3.inc: original size 937, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= parseargs/doc/lib_bugs.inc ============== if test -f 'parseargs/doc/lib_bugs.inc' -a X"$1" != X"-c"; then echo 'x - skipping parseargs/doc/lib_bugs.inc (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting parseargs/doc/lib_bugs.inc (Text)' sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/lib_bugs.inc' && .\"---------------------------------------------------------------------------- .\"-- This text was extracted using the following command: .\"-- xdoc -man -n -p '[ \t]*' -I BUGS ../xparse.c .\"---------------------------------------------------------------------------- .SH BUGS .PP When a non-multivalued argument appears more than once on the command-line then only the last value supplied is used. A problem occurs however in the following scenario: suppose `\fB\-s\fP' is an option that takes an optional string argument (nd suppose `\fB\-x\fP' is some boolean flag). Then if the following command-line is issued: X .RS .nf .ft 4 command \-s string \-x \-s .ft R .fi .RE X then, the argument flags will properly correspond to the second instance of the `\fB\-s\fP' option (namely \s-1ARGGIVEN\s+1 will be set but \s-1ARGVALGIVEN\s+1 will be unset) but the value associated with the option will be ``\fIstring\fP'' (because the first instance overwrote the default). Because of this, it may be safest to reassign the default value if \s-1ARGGIVEN\s+1 is set but \s-1ARGVALGIVEN\s+1 is unset. SHAR_EOF chmod 0664 parseargs/doc/lib_bugs.inc || echo 'restore of parseargs/doc/lib_bugs.inc failed' Wc_c="`wc -c < 'parseargs/doc/lib_bugs.inc'`" test 1101 -eq "$Wc_c" || echo 'parseargs/doc/lib_bugs.inc: original size 1101, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= parseargs/doc/lparseargs3.inc ============== if test -f 'parseargs/doc/lparseargs3.inc' -a X"$1" != X"-c"; then echo 'x - skipping parseargs/doc/lparseargs3.inc (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting parseargs/doc/lparseargs3.inc (Text)' sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/lparseargs3.inc' && .\"---------------------------------------------------------------------------- .\"-- This text was extracted using the following command: .\"-- xdoc -man -n -p '[ \t]*' -I DESCRIPTION -f lparseargs ../xparse.c .\"---------------------------------------------------------------------------- .PP Given an ArgList and an argdesc array, \fIlparseargs\fP will parse arguments in a file in much the same manner as \fIparseargs\fP. SHAR_EOF chmod 0664 parseargs/doc/lparseargs3.inc || echo 'restore of parseargs/doc/lparseargs3.inc failed' Wc_c="`wc -c < 'parseargs/doc/lparseargs3.inc'`" test 428 -eq "$Wc_c" || echo 'parseargs/doc/lparseargs3.inc: original size 428, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= parseargs/doc/multivals.inc ============== if test -f 'parseargs/doc/multivals.inc' -a X"$1" != X"-c"; then echo 'x - skipping parseargs/doc/multivals.inc (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting parseargs/doc/multivals.inc (Text)' sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/multivals.inc' && .\"---------------------------------------------------------------------------- .\"-- This text was extracted using the following command: .\"-- xdoc -man -p '[ \t]*' -s MULTI-VALUED_ARGUMENTS ../parseargs.h .\"---------------------------------------------------------------------------- .SH MULTI-VALUED ARGUMENTS .PP .I Parseargs supports two different types of multi-valued arguments: linked-lists and vectors. The linked-lists are called argument lists (or arg-lists) and are specified by supplying the \s-1ARGLIST\s+1 flag along with an associated \fIlistXxxx\fP argument-translation routine. The value associated with an arg-list should be a list structure of type ArgList. The include file \f4<parseargs.h>\fP defines four macros for manipulating ArgList structures: \s-1ARGLISTNULL\s+1, \s-1L_NEXT\s+1, \s-1L_STRING\s+1, and \s-1L_FLAGS\s+1. .PP \s-1ARGLISTNULL\s+1 is simply the \s-1NULL\s+1 argument-list pointer. \s-1L_NEXT\s+1 and \s-1L_STRING\s+1 each take a pointer to a non-\s-1NULL\s+1 ArgList structure. \s-1L_NEXT\s+1 returns the address of the next item in the list and \s-1L_STRING\s+1 returns the string-value of the current list-item. \s-1L_FLAGS\s+1 return the arg-flags for a given item in the list. With non-multivalued, only the flags in the argument descriptor are needed; lists and vectors however need a set of flags for each item they contain. Once an arg-list has been created, it may be deallocated using the function .I listFree. .I ListFree takes two parameters, the first of which is the address of the first item in the arg-list, and the second of which is a boolean value that is \s-1TRUE\s+1 only if each value pointed to by each item should also be deallocated. .PP An alternative to argument-lists is argument vectors (or arg-vectors). Arg-vectors use the \s-1ARGVEC\s+1 flag instead of the \s-1ARGLIST\s+1 flag and do not require a special \fIlistXxxx\fP function for each vector-type. Each of the \fIargXxxx\fP functions is responsible for handling vectors of its type (although some argXxx functions such as the boolean types do not support vectors). An arg-vector is a structure which contains a count, an array of elements (i.e. an argc/argv pair), and an array of flags, one for each element of argv. There are two macros in defined in \f4<parseargs.h>\fR which are used for arg-vectors. \s-1ARGVEC_T\s+1 may be used to declare a vector structure or a vector type; \s-1ARGVEC_EMPTY\s+1 may be used to initialize the structure. It is strongly recommended that \s-1ARGVEC_T\s+1 be used to declare vector types in a typedef statement (particularly if one is using function prototypes) but for those who insist, it may be used to directly declare a structure. String-vectors will always have an extra \s-1NULL\s+1-pointer at the end such that: X .RS .nf .ft 4 ( StrVec.array[ StrVec.count ] == (char *)NULL ) .ft R .fi .RE X is always true, and character-vectors will always have an extra \s-1NUL\s+1-character at the end such that: X .RS .nf .ft 4 ( CharVec.array[ CharVec.count ] == '\\0' ) .ft R .fi .RE X is always true. Integer and floating point vectors contain no extra "null" elements. X Once created, arg-vectors may be deallocated by calling the macro \fIvecFree\fP or the macro \fIvecDeepFree\fP and passing it the arg-vector structure. The differemce between these two macros is that the latter will also free each item in the vector that required space to be allocated (at the expense of traversing the vector). At this writing, the only predefined argument-types that would benefit from \fIvecDeepFree\fP is \fIargStr\fP vectors. .PP An example use of arg-lists, and of arg-vectors follows: X .RS .nf .ft 4 #include <parseargs.h> X typedef ARGVEC_T(char *) strvec_t; X static ArgList *StringList = ARGLISTNULL; static strvec_t StringVec = ARGVEC_EMPTY(char *); static ARGVEC_T(int) NumberVec = ARGVEC_EMPTY(int); X static X CMD_OBJECT Args X CMD_NAME "foo -- do whatever foo does" X CMD_DESCRIPTION "put a brief paragraph here" X CMD_ARGUMENTS X 'l', ARGLIST, listStr, __ &StrList, "LiSt {list of strings}", X 's', ARGVEC, argStr, __ &StrVec, "STRing {vector of strings}", X 'i', ARGVEC, argInt, __ &NumVec, "NUMber {vector of numbers}", X END_ARGUMENTS X CMD_END X main( int argc, char *argv[] ) { X int i, *ls; X X if ( parseargs(argv, Args) ) syserr( "parseargs failed" ); X X for ( ls = StrList, i=1 ; ls ; ls = L_NEXT(ls), i++ ) X printf( "List item %d=%s, flags=%x\\n", X i, L_STRING(ls), L_FLAGS(ls) ); X X for ( i = 0 ; i < StrVec.count ; i++ ) X printf( "String[%d]=%s, flags=%x\\n", X i, StrVec.array[i], StrVec.flags[i] ); X X for ( i = 0 ; i < NumVec.count ; i++ ) X printf( "Number[%d]=%s, flags=%x\\n", X i, NumVec.array[i], NumVec.flags[i] ); X X listFree( StrList ); X StrList = ARGLISTNULL; X X vecDeepFree( StrVec, char * ); X vecFree( NumVec, int ); X X exit( 0 ); } X .ft R .fi .RE SHAR_EOF chmod 0664 parseargs/doc/multivals.inc || echo 'restore of parseargs/doc/multivals.inc failed' Wc_c="`wc -c < 'parseargs/doc/multivals.inc'`" test 4932 -eq "$Wc_c" || echo 'parseargs/doc/multivals.inc: original size 4932, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= parseargs/doc/parseargs.man1 ============== if test -f 'parseargs/doc/parseargs.man1' -a X"$1" != X"-c"; then echo 'x - skipping parseargs/doc/parseargs.man1 (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting parseargs/doc/parseargs.man1 (Text)' sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/parseargs.man1' && .\" $Header: parseargs.1,v 1.0 90/07/24 Brad Appleton $ .de SS .sp 8p \s+1\fB\\$1\fP\s-1 .br .. .TH PARSEARGS 1 .nh .SH NAME parseargs \- parse command line arguments in shell scripts .\"----------------------------------------------------------- .SH SYNOPSIS .TP 12 \fBparseargs\fP [\fB\-U\fP] [\fB\-M\fP] [\fB\-T\fP\ \fIstring\fP] [\fB\-F\fP\ \fIstring\fP] [\fB\-A\fP] [\fB\-a\fP\ \fIarg-spec\fP] [\fB\-e\fP\ \fIname\fP] [\fB\-f\fP\ \fIfile\fP] [\fB\-l\fP] [\fB\-o\fP] [\fB\-s\fP\ \fIshell\fP\^] [\fB\-u\fP] [\fB\-i\fP] [\fB\-p\fP] \fB\-\^\-\fP \fIname\fP [\fIarguments\fP\ .\^.\^.\^] .\"----------------------------------------------------------- .SH OPTIONS .TP 14 \fB\-U\fP just print program usage, do not parse the command line .TP 14 \fB\-M\fP just print (n|t)roff \-man manual page template, do not parse the command line .TP 14 \fB\-T\fP \fIstring\fP string to use for true boolean arguments\| (\fIdefault=``\s-1TRUE\s+1\^''\fP\|) SHAR_EOF true || echo 'restore of parseargs/doc/parseargs.man1 failed' fi echo 'End of part 3' echo 'File parseargs/doc/parseargs.man1 is continued in part 4' echo 4 > _shar_seq_.tmp exit 0 exit 0 # Just in case... -- Kent Landfield INTERNET: kent@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@uunet.uu.net.