[comp.sources.misc] v17i049: parseargs - functions to parse command line arguments, Part04/12

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 49
Archive-name: parseargs/part04

This is part 4 of parseargs

#!/bin/sh
# this is Part.04 (part 4 of a multipart archive)
# do not concatenate these parts, unpack them in order with /bin/sh
# file parseargs/doc/parseargs.man1 continued
#
if test ! -r _shar_seq_.tmp; then
	echo 'Please unpack part 1 first!'
	exit 1
fi
(read Scheck
 if test "$Scheck" != 4; 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/doc/parseargs.man1'
else
echo 'x - continuing file parseargs/doc/parseargs.man1'
sed 's/^X//' << 'SHAR_EOF' >> 'parseargs/doc/parseargs.man1' &&
.TP 14
\fB\-F\fP \fIstring\fP
string to use for false boolean arguments  (\fIdefault=``\^''\fP\|)
.TP 14
\fB\-A\fP
modify array behavior for the specified shell.
.TP 14
\fB\-a\fP \fIarg-spec\fP
argument specification string
.TP 14
\fB\-e\fP\ \fIname\fP
read the arg-spec string from the environment variable named \fIname\fP
.TP 14
\fB\-f\fP \fIfile\fP
read the arg-spec from \fIfile\fP  (\fIdefault=stdin\fP)
.TP 14
\fB\-l\fP
Long-options only. Disable the parsing of (single-character) options.
.TP 14
\fB\-o\fP
Options only. Disable the parsing of long-options (keywords).
.TP 14
\fB\-s\fP \fIshell\fP
use \fIshell\fP command syntax\|  (\fIdefault=``sh''\fP\|)
.TP 14
\fB\-u\fP
unset positional parameters before assigning variables
.TP 14
\fB\-p\fP
prompt the user for missing required arguments
.TP 14
\fB\-i\fP
ignore bad command-line syntax and continue processing (instead of aborting)
.\"-----------------------------------------------------------
.SH ARGUMENTS
.TP 14
\fI\-\^\-\fP
Indicates that any remaining options are intended for the calling program.
.TP 14
\fIname\fP
name of calling program
.TP 14
\fIarguments\fP
arguments to calling program
.\"-----------------------------------------------------------
.so parseargs1.inc
.\"-----------------------------------------------------------
.PP
The argument specification string contains one entry for each possible flag.
Entries in the arguments specification string are separated by commas.
Each entry has five comma-separated fields:
a name, some flags, a type, a variable-name, and a prompt.
Each of these fields are described below:
.TP 10
\fIname\fP
The single character name of the associated flag.
For example, to indicate that the program is expecting a ``\-x'' flag,
this field would contain \'x\'.
Positional arguments (those without a ``\-\fIx\fP'' prefix)
are indicated by passing a ``space'' character.
.TP 10
\fIflags\fP
Flags modifying the semantics of this entry.
These should have one of
\s-1ARGREQ\s+1
to indicate a required argument or
\s-1ARGOPT\s+1
to indicate an optional argument
(\s-1ARGOPT\s+1 is the default unless \s-1ARGREQ\s+1 is specified).
\s-1ARGPOS\s+1
can be ``ored'' in to indicate a positional argument that may also
be keyword matched.
\s-1ARGNOVAL\s+1
can be ``ored'' in to indicate that an argument is an option
or a keyword that does not use an accompanying argument (such as
a boolean flag). This flag is only required for corresponding argument
types that are implemented by the programmer; \fBparseargs\fP already
knows which pre-defined argument types take an argument.
\s-1ARGVALOPT\s+1
can be ``ored'' in to indicate that an argument to the option may be
optionally supplied on the command-line, but is not required.
\s-1ARGVALREQ\s+1
can be ``ored'' in to indicate that an argument to the option is required
(this is the default behavior for options that take arguments).
\s-1ARGLIST\s+1
can be ``ored'' in (using the `\^|\^' character) to indicate that an argument
is actually a list of one or more arguments from the command line.
\s-1ARGHIDDEN\s+1
can be ``ored'' in to indicate a flag that should not be printed
in usage messages \(em
for example, flags intended for internal debugging purposes.
.TP 10
\fItype\fP
The type of the argument.
Existing types include
\fIargUsage\fP (print usage message and exit),
\fIargBool\fP and \fIargSBool\fP (set Boolean flags),
\fIargUBool\fP (unset Boolean flags),
\fIargStr\fP (string-valued arguments),
\fIargChar\fP (char-valued arguments),
\fIargInt\fP (native integer arguments),
\fIargShort\fP (short integer arguments),
\fIargLong\fP (long integer arguments),
\fIargFloat\fP (short floating point arguments),
\fIargDouble\fP (long floating point arguments), and
\fIargDummy\fP (only used as part of usage message,
not matched on command-line).
.TP 10
\fIvariable\fP
The name of the shell variable that should receive the converted value.
.TP 10
\fIprompt\fP
The string used when prompting interactively for argument values,
and printed in usage messages. This string may be followed by a
textual description that is enclosed in parentheses, square brackets,
curly braces, or angle brackets.
.PP
The argument specification string must be terminated by the single string:
``ENDOFARGS''.
.PP
Note that the comma character (',') is used to separate all fields
within an entry, and to separate the entries themselves.
For this reason, \fIno field in any entry may contain a comma unless
it appears inside of double or single quotes\fP.
.PP
.B Parseargs
will parse all command-line arguments for the calling script and match
them against the argument specification string provided. The argument
specification string is read from standard input by default but may not
come from a terminal. The argument specification string may be supplied as
a single string argument by using the \fB\-a\fP ``\fIstring\fP'' flag.
Long argument specification strings however, may limit the number of arguments
to the script if there is a limit to the number of arguments and/or characters
that may appear on the command line.
For this reason, the argument specification string may be stored: in an
environment variable using the \fB-e\fP \fIname\fP option; in a file
and read using the \fB\-f\fP \fIfile\fP option; or read from standard input.
When using the \fB\-e\fP option, the user must remember to use the name
of an environment variable (not a mere shell variable)!
The default behavior is to read the argument specification from standard input.
.\"-----------------------------------------------------------
.so shells.inc
.\"-----------------------------------------------------------
.PP
The double-dash (``\fB\-\^\-\fP'') which precedes the name and arguments of
the calling program is needed in order for \fBparseargs\fP to be able to
distinguish options to itself from options for the calling program.
.PP
The default behavior of parseargs is allow both single-character options and
long-options (keywords) on the command-line. The user may specify that only
options (long-options) are to be permitted by specifying the \fB\-o\fP
(\fB\-l\) option on the command-line.
.\"----------------------------------------------------------------
.so argvalopt.inc
.\"----------------------------------------------------------------
.so sh_arrays.inc
.\"----------------------------------------------------------------
.so env_args.inc
.\"----------------------------------------------------------------
.so env_parse.inc
.\"----------------------------------------------------------------
.so env_usage.inc
.\"----------------------------------------------------------------
.SH EXAMPLES
.PP
As a first example, consider the following argument specification for a
Bourne shell script:
.PP
.nf
.\" *** font 4 is the "typewriter-style" non-proportional font on my machine ***
.ft 4
.sp 8p
#!/bin/sh
.sp 8p
RepCount=2;
Verbose="";
.sp 8p
ARGSPEC="
X    'c', ARGOPT,         argInt,  RepCount, 'count {# times to repeat}',
X    'v', ARGOPT,         argBool, Verbose,  'verbose {turn on verbose mode}',
X    ' ', ARGREQ,         argStr,  InFile,   'input {file to read from}',
X    ' ', ARGOPT,         argStr,  OutFile,  'output {file to write to}',
X    'X', ARGHIDDEN,      argBool, XRated,   'xrated {naughty! naughty!}',
X    ' ', ARGOPT|ARGLIST, listStr, Files,    'files {files to process}',
ENDOFARGS
"
.sp 8p
eval `echo "$ARGUMENTS" | parseargs \-s sh \-\|\- $0 "$@"`
.sp 8p
.ft R
.fi
.PP
This describes a Bourne shell script accepting up to three flag arguments and
one or two positional arguments, plus a list of additional file arguments.
Only the first positional argument is required.
The possible flags (in UNIX) are:
.RS
.TP 10
\fB\-c\fP \fIcount\fP
An integer repetition count.
This defaults to two.
.TP 10
\fB\-v\fP
A Boolean ``verbose'' flag.
It defaults to \s-1FALSE\s+1 (an empty string).
.TP 10
\fB\-X\fP
A Boolean ``X Rated'' flag.
This is not printed in the usage message.
.RE
.PP
The two positional arguments are both strings, as is the final list.
If we were to invoke the above script with the following command line:
.sp 8p
.RS
\f4cmdname  \-v  input_file  output_file  file1  file2\fP
.RE
.sp 8p
Then, after invoking \fBparseargs\fP, the following shell variables would
contain the following values:
.sp 8p
.RS
\f4$RepCount\fP would evaluate to ``\f42\fP\^''
.sp 4p
\f4$Verbose\fP would evaluate to ``\f4\s-1TRUE\s+1\fP\^''
.sp 4p
\f4$InFile\fP would evaluate to ``\f4input_file\fP\^''
.sp 4p
\f4$OutFile\fP would evaluate to ``\f4output_file'\fP\^'
.sp 4p
\f4$Files\fP would evaluate to ``\f4file1  file2\fP\^''
.sp 4p
\f4$XRated\fP would be unset and would evaluate to an empty string (``\^'').
.RE
.sp
.PP
Now let's present a more complete example. The following page shows a
Bourne shell script which uses \fBparseargs\fP to parse its command line,
echoes the settings of all its associated command line variables, and
then prints its command usage.
X
.nf
.\" *** font 4 is the "typewriter-style" non-proportional font on my machine ***
.ft 4
.so ../test.sh
.ft R
.fi
.\"-----------------------------------------------------------
.SH DIAGNOSTICS
\fBParseargs\fP may exit with one of the following status codes:
X
.TP 5
-1
Some type of system error occurred during execution, causing the program
to exit prematurely.
.TP 5
\|\|0
Normal exit status (no problems were encountered).
.TP 5
\|\|1
The calling program specified the \fB\-U\fP or the \fB\-M\fP option to
\fBparseargs\fP, or specified an \fIargUsage\fP flag on the command line.
Only the appropriate message is displayed.
.TP 5
\|\|2
A command line syntax error was encountered by \fBparseargs\fP. The offending
command line argument may have been intended for either \fBparseargs\fP or
for the calling program.
.TP 5
\|\|3
The environment variable that was specified with the \fB\-e\fP option
is either \s-1NULL\s+1 (has an empty value) or does not exist. Perhaps
the user specified a shell variable and/or forgot to export it.
.TP 5
\|\|4
A syntax error was encountered in the argument specification string that was
specified to \fBparseargs\fP.
.\"-----------------------------------------------------------
.SH FILES
.IP "\fI/usr/local/parseargs.pl\fP"
This file defines a \fIperl\fP function named \fIparseargs\fP to parse
arguments more conveniently for perl-scripts. The function is 
both documented and implemented in this file. The user should
``require'' this file in his/her perl-script before invoking the
function.
.IP "\fI/usr/local/parseargs.awk\fP"
This file defines an \fIawk\fP function named \fIparseargs\fP to parse
arguments more conveniently for awk-scripts. The function is 
both documented and implemented in this file. The user should
include this file in his/her awk-script before invoking the
function.
.\"-----------------------------------------------------------
.SH SEE ALSO
.IR argtype (3),
.IR parseargs (3),
.IR parsecntl (3)
.\"-----------------------------------------------------------
.so caveats.inc
.\"-----------------------------------------------------------
.so bugs.inc
.\"-----------------------------------------------------------
.SH AUTHOR
.nf
Brad Appleton  (\fIbrad@ssd.csd.harris.com\fP)
Harris Computer Systems, Fort Lauderdale, FL USA
.fi
SHAR_EOF
echo 'File parseargs/doc/parseargs.man1 is complete' &&
chmod 0664 parseargs/doc/parseargs.man1 ||
echo 'restore of parseargs/doc/parseargs.man1 failed'
Wc_c="`wc -c < 'parseargs/doc/parseargs.man1'`"
test 12151 -eq "$Wc_c" ||
	echo 'parseargs/doc/parseargs.man1: original size 12151, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= parseargs/doc/parseargs.man3 ==============
if test -f 'parseargs/doc/parseargs.man3' -a X"$1" != X"-c"; then
	echo 'x - skipping parseargs/doc/parseargs.man3 (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting parseargs/doc/parseargs.man3 (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/parseargs.man3' &&
.\" $Header: parseargs.3,v 2.0 89/12/24 00:56:26 eric Exp $
.TH PARSEARGS 3
.\"-----------------------------------------------------------
.SH NAME
parseargs, usage \- parse command line argument vectors
.\"-----------------------------------------------------------
.SH SYNOPSIS
#include <parseargs.h>
.PP
.nf
int  parseargs(  char *argv[],  ARGDESC *argd  )
int  fparseargs(  FILE *fp,  ARGDESC *argd  )
int  lparseargs(  ArgList *argls,  ARGDESC *argd  )
int  sparseargs(  char *str,  ARGDESC *argd  )
int  vparseargs(  ARGDESC *argd,  ...  )
void  usage(  const ARGDESC *argd  )
.fi
.\"-----------------------------------------------------------
.SH DESCRIPTION
.so parseargs3.inc
.so fparseargs3.inc
.so lparseargs3.inc
.so sparseargs3.inc
.so vparseargs3.inc
.so usage3.inc
.\"-----------------------------------------------------------
.so argdesc.inc
.\"-----------------------------------------------------------
.SH DEFINING ARGDESC ARRAYS
When defining an argdesc array, the first item in the list should
be the item STARTOFARGS. Normal arguments (defined by the programmer)
may then be specified as documented in this manual.
The list of arguments is terminated using ENDOFARGS.
.PP
For example, consider the description:
.sp 4p
.in +2
.nf
.ft 4
int	RepCount =	2;
BOOL	Verbose =	FALSE;
char	*InFile;
char	*OutFile =	CHARNULL;
BOOL	XRated =	FALSE;
struct namelist *Files = NULL;
X
ARGDESC Args[] =
{
X  STARTOFARGS,
X  'c', ARGOPT,    argInt,  _\|_ &RepCount, "REPcount {# of repetitions}",
X  'v', ARGOPT,    argBool, _\|_ &Verbose,  "Verbose {set verbose mode}",
X  ' ', ARGREQ,    argStr,  _\|_ &InFile,   "INPUTfile {input file}",
X  ' ', ARGOPT,    argStr,  _\|_ &OutFile,  "OUTPUTfile {output file}",
X  'X', ARGHIDDEN, argBool, _\|_ &XRated,   "XratedMODE {naughty stuff!}",
X  ' ', ARGOPT\^|\^ARGLIST, argStr, _\|_ &Files, "File {files to be read}",
X  ENDOFARGS
};
.ft R
.fi
.in -2
.PP
This describes a program accepting up to three flag arguments and
one or two positional arguments, plus a list of additional file arguments.
Only the first positional argument is required.
The possible flags (in UNIX) are:
.TP 10
\fB\-c\fP \fIcount\fP
An integer repetition count.
This defaults to two.
.TP 10
\fB\-v\fP
A Boolean ``verbose'' flag.
It defaults to FALSE.
.TP 10
\fB\-X\fP
A Boolean ``X Rated'' flag.
This is not printed in the usage message.
.PP
The two positional arguments are both strings, as is the final list.
In AmigaDOS, the options would be
\fBREP\fP \fBcount\fP,
\fBV\fP, and
\fB\s-1XMODE\s+1\fP.
In \s-1VAX/VMS\s+1, the qualifiers would be
\fB\s-1/REP\s+1\fP=\fIcount\fP,
\fB\s-1/V\s+1\fP, and
\fB\s-1/XMODE\s+1\fP.
.\"-----------------------------------------------------------
.so argflags.inc
.\"-----------------------------------------------------------
.so arg_macros.inc
.\"-----------------------------------------------------------
.so cmd_macros.inc
.\"-----------------------------------------------------------
.so defargs.inc
.\"-----------------------------------------------------------
.so env_args.inc
.\"-----------------------------------------------------------
.so env_parse.inc
.\"-----------------------------------------------------------
.so env_usage.inc
.\"-----------------------------------------------------------
.so multivals.inc
.\"-----------------------------------------------------------
.SH ARGUMENT TYPE FUNCTIONS
The argument types recognized by
.I parseargs
can be extended by adding new type functions.
Argument type functions are declared as:
.RS
.PP
.nf
.ft 4
BOOL  argXxx(  ARGDESC *ad,  char *vp,  BOOL copyf  )
.ft R
.fi
.RE
.PP
The
.I argd
argument points to the descriptor for the argument being converted.
Its main use is to find the location in which to store the converted value,
located in argd\(->ad_valp.
The string value to be converted is passed in
.IR argp
(which will be \s-1NULL\s+1 if the \s-1ARGNOVAL\s+1 flag was set for the
corresponding entry in the arg-descriptor table).
The
.I copyf
flag is TRUE if the
.I argp
string value must be copied when saved.
Most non-string types are copied implicitly
(for example, integer arguments are stored in binary form,
so the original string value need not be saved),
so this argument can usually be ignored.
Put simply, this flag is
TRUE
when
.I argp
points to a temporary buffer area.
.PP
If the type function successfully converts the value,
and uses the entire value,
it should return TRUE.
If the type function successfully converts the value,
and uses only \fIN\fP characters of the value,
it should return -\fIN\fP.
Otherwise,
it should print a message using
.IR usrerr (3)
and return FALSE. This message should be of the form
\fB"invalid xxxx option 'yyyy' for Zzzz"\fP, where xxxx is the type of the
option, yyyy is the string passed in vp, and zzzz is the name (taken from
\fBad\(->ad_prompt\fP).
The \fIargXxxx\fP function is responsible for detecting if the given argument
descriptor is an \s-1ARGVEC\s+1 argument and for taking the appropriate action.
.PP
For example, a type function that took a filename
and stored an open file pointer might be coded as:
.RS
.PP
.nf
.ft 4
#define REALLOC(ptr,size)  ((! ptr) ? malloc(size) : realloc(ptr, size))
.sp 8p
typedef ARGVEC_T(FILE *)  FILEvec_t;
.sp 8p
BOOL  argReadFile(  ARGDESC *\|ad,  char *\|vp,  BOOL copyf  )
{
X	register FILE *fp;
.sp 4p
X	fp = fopen(vp, "r");
.sp 4p
X	if ( ! fp ) {
X		usrerr("cannot open '%s' for reading", vp);
X		return (FALSE);
X	}
.sp 4p
X	if ( BTEST(arg_flags(ad), ARGVEC) ) {
X		FILEvec_t  *vec = (FILEvec_t *) arg_valp(ad);
X		size_t  size  = (1 + vec->count) * (sizeof (FILE *));
.sp 4p
X		vec->array = (FILE **) REALLOC(vec->array, size);
X		if ( ! vec->array )
X			syserr( "(m|re)alloc failed in argReadFile" );
.sp 4p
X		vec->flags = (FILE **) REALLOC(vec->flags, size);
X		if ( ! vec->flags )
X			syserr( "(m|re)alloc failed in argReadFile" );
.sp 4p
X		vec->flags[ vec->count ] = arg_flags(ad);
X		vec->array[ (vec->count)++ ] = fp;
X	}
X	else
X		*(FILE *) arg_valp(ad) = fp;
.sp 4p
X	return (TRUE);
}
.ft R
.fi
.RE
.RE
.\"------------------------------------------------------------------
.SH LONG OPTIONS
.PP
Under \s-1UNIX\s+1, Parseargs also allows for long options in addition to
single character options. Long options are denoted by a `\fB+\fP' character
(which may be changed using \fIkeywordprefix\fP). The keyword that is
used is the first word in the prompt field of an argument descriptor entry.
Long options are case insensitive! An argument to a long option may be
separated from the long option by an equal sign (`=') or by one or more
whitespace characters.  Thus, if an entry looks like:
.RS
.sp 4p
.nf
.ft 4
\^'c', ARGOPT, argInt, _\|_ &count, "repCOUNT (# of times to repeat)",
.ft R
.fi
.sp 4p
.RE
then ``\fB\-c4\fP'', ``\fB+repcount=4\fP'', ``\fB+count=4\fP'',
``\fB+repcount\04\fP'', and ``\fB+count\04\fP'' will all have the same effect.
.PP
The long option names for ``\fB\-?\fP'' in the default argument descriptor
are ``\fB+help\fP'' and ``\fB+?\fP'' (respectively). In addition, ``\fB++\fP''
or ``\fB+endopts\fP'' may be used to indicate the end of options so that
all remaining arguments will be interpreted as positional parameters
(even if one begins with a `\fB+\fP' or a `\fB\-\fP').
.PP
Under VAX/VMS and AmigaDOS, single-character options are not used and the
``long'' name (in the prompt field of an argument descriptor) is always used
to match for possible arguments (or keywords, or qualifiers).
.PP
For all supported operating systems, a long option may be matched in one of
two ways: it may match all uppercase characters in the prompt field, or it may
match all characters in the prompt field (as in ``\fB+count=4\fP'' and
``\fB+repcount=4\fP'').
.PP
Under \s-1UNIX\s+1 and \s-1VAX/VMS\s+1,
only the number of characters required to uniquely identify the desired argument
are needed, but at least two characters must be given (unless the prompt field
is itself less than two characters long). This means that using the above
example, that ``\fB+rep=4\fP'' and
``\fB+cou=4\fP'' would also work but ``\fB+c=4\fP'' would \s-1NOT\s+1 (in other words, if
you only want to use one character, use ``\fB\-c4\fP'' instead).
.PP
Under VAX/VMS, the possibilities using the above example would be:
``\fB/REPCOUNT=4\fP'', ``\fB/COUNT=4\fP'', ``\fB/REP=4\fP'', and ``\fB/COU=4\fP'',
.PP
Under AmigaDOS, no ``shortened'' keywords are accepted and the possibilities
using the above example would be:
``\fBREPCOUNT 4\fP'', and ``\fBCOUNT 4\fP''
.\"------------------------------------------------------------------
.so returns.inc
.\"------------------------------------------------------------------
.SH SEE ALSO
.IR argtype (3),
.IR parseargs (1),
.IR syserr (3)
.br
The ``C Advisor'' column in
.ul
UNIX Review
Vol. 7 No. 11.
.\"-----------------------------------------------------------
.so caveats.inc
.\"-----------------------------------------------------------
.so lib_bugs.inc
.\"-----------------------------------------------------------
.SH AUTHOR
Eric Allman, University of California, Berkeley
.SH MODIFICATIONS
.PP
Modified to accept a vector of arguments, better error messages,
Unix keyword matching, and AmigaDOS version by Peter da Silva.
.PP
Rewritten by Brad Appleton.
Parseargs(1);
functions parsecntl, sparseargs, fparseargs, lparseargs, and vparseargs;
argument types argUsage, argDummy, argUBool, and argTBool;
argument flags \s-1ARGPOS\s+1, \s-1ARGVALOPT\s+1, \s-1ARGVALREQ\s+1,
\s-1ARGVALGIVEN\s+1, \s-1ARGNOVAL\s+1, and \s-1ARGVEC\s+1; and
\s-1VAX/VMS\s+1 version and IBM-PC version by Brad Appleton
SHAR_EOF
chmod 0664 parseargs/doc/parseargs.man3 ||
echo 'restore of parseargs/doc/parseargs.man3 failed'
Wc_c="`wc -c < 'parseargs/doc/parseargs.man3'`"
test 9554 -eq "$Wc_c" ||
	echo 'parseargs/doc/parseargs.man3: original size 9554, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= parseargs/doc/parseargs1.inc ==============
if test -f 'parseargs/doc/parseargs1.inc' -a X"$1" != X"-c"; then
	echo 'x - skipping parseargs/doc/parseargs1.inc (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting parseargs/doc/parseargs1.inc (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/parseargs1.inc' &&
.\"----------------------------------------------------------------------------
.\"-- This text was extracted using the following command:
.\"--   xdoc -man -n -p '[ \t]*' -I DESCRIPTION ../parseargs.c
.\"----------------------------------------------------------------------------
.SH DESCRIPTION
Given a command name, a vector of string-valued arguments
such as that passed to a shell script,
and a specification string describing the possible arguments,
.B parseargs
matches actual arguments to possible arguments,
converts values to the desired type,
and diagnoses problems such as
missing arguments,
extra arguments,
and argument values that are syntactically incorrect.
Other behavior such as prompting the user for missing arguments and
ignoring as command-line syntax may be specified on the command-line
through the use of various options, or through the use of the
``\s-1PARSECNTL\s+1'' environment variable.
.PP
Given the command name and the argument specification string,
.B parseargs \-U
prints a reasonably friendly version of the usage of the
calling program on standard diagnostic output. The ``verbosity''
of the usage message may be controlled through the use of the
``\s-1USAGECNTL\s+1'' environment variable.
.PP
Given the command name and the argument specification string,
.B parseargs \-M
prints a template of the command-syntax on standard output that is
suitable for input to \fInroff\fP or \fItroff\fP using the \-man 
macro package.
SHAR_EOF
chmod 0664 parseargs/doc/parseargs1.inc ||
echo 'restore of parseargs/doc/parseargs1.inc failed'
Wc_c="`wc -c < 'parseargs/doc/parseargs1.inc'`"
test 1461 -eq "$Wc_c" ||
	echo 'parseargs/doc/parseargs1.inc: original size 1461, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= parseargs/doc/parseargs3.inc ==============
if test -f 'parseargs/doc/parseargs3.inc' -a X"$1" != X"-c"; then
	echo 'x - skipping parseargs/doc/parseargs3.inc (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting parseargs/doc/parseargs3.inc (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/parseargs3.inc' &&
.\"----------------------------------------------------------------------------
.\"-- This text was extracted using the following command:
.\"--   xdoc -man -n -p '[ \t]*' -I DESCRIPTION -f parseargs ../xparse.c
.\"----------------------------------------------------------------------------
.PP
Given a vector of string-valued arguments such as that passed to \fImain\fP
and a vector describing the possible arguments, \fIparseargs\fP matches
actual arguments to possible arguments, converts values to the desired type,
and diagnoses problems such as missing arguments, extra arguments,
and argument values that are syntactically incorrect.
SHAR_EOF
chmod 0664 parseargs/doc/parseargs3.inc ||
echo 'restore of parseargs/doc/parseargs3.inc failed'
Wc_c="`wc -c < 'parseargs/doc/parseargs3.inc'`"
test 642 -eq "$Wc_c" ||
	echo 'parseargs/doc/parseargs3.inc: original size 642, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= parseargs/doc/parsecntl.man3 ==============
if test -f 'parseargs/doc/parsecntl.man3' -a X"$1" != X"-c"; then
	echo 'x - skipping parseargs/doc/parsecntl.man3 (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting parseargs/doc/parsecntl.man3 (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/parsecntl.man3' &&
.\"---------- TO PRINT, USE: {n,t}roff -man file ----------
.TH PARSECNTL 3
.\"-----------------------------------
.SH NAME
parsecntl \- get and set attributes of an argument descriptor array
.\"-----------------------------------
.SH SYNOPSIS
#include <parseargs.h>
.PP
.nf
int  parsecntl( ARGDESC argd[\|],  parsecntl_t func,  parsemode_t mode,  ... )
.fi
X
.\"-----------------------------------
.so parsecntl3.inc
.\"-----------------------------------
.so parsecntls.inc
.\"-----------------------------------
.so parsemodes.inc
.\"-----------------------------------
.so parseflags.inc
.\"-----------------------------------
.so argflags.inc
.\"-----------------------------------
.so returns.inc
.\"-----------------------------------
.SH SEE ALSO
.nf
.IR argtype (3),
.IR parseargs (3),
.IR parseargs (1)
.fi
.\"-----------------------------------
.SH AUTHOR
.PP
.nf
Brad Appleton  (\fIbrad@ssd.csd.harris.com\fP)
Harris Computer Systems, Fort Lauderdale, FL USA
.fi
SHAR_EOF
chmod 0664 parseargs/doc/parsecntl.man3 ||
echo 'restore of parseargs/doc/parsecntl.man3 failed'
Wc_c="`wc -c < 'parseargs/doc/parsecntl.man3'`"
test 974 -eq "$Wc_c" ||
	echo 'parseargs/doc/parsecntl.man3: original size 974, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= parseargs/doc/parsecntl3.inc ==============
if test -f 'parseargs/doc/parsecntl3.inc' -a X"$1" != X"-c"; then
	echo 'x - skipping parseargs/doc/parsecntl3.inc (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting parseargs/doc/parsecntl3.inc (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/parsecntl3.inc' &&
.\"----------------------------------------------------------------------------
.\"-- This text was extracted using the following command:
.\"--   xdoc -man -n -p '[ \t]*' -I DESCRIPTION -f parsecntl ../xparse.c
.\"----------------------------------------------------------------------------
.SH "DESCRIPTION"
.PP
.I Parsecntl
will read and/or write the desired attributes of the given
command-object. The attributes to be operated upon are specified by
the second parameter to
.I parsecntl.
The desired mode (read, write, or both) are specified by the third parameter to
.I parsecntl.
If the operation to be performed is
.I pc_\s-1ARGFLAGS\s+1,
then the fourth argument to
.I parsecntl
should be the keyword name of the argument whose flags
are to be retrieved.  The last parameter to
.I parsecntl
is always the object to contain the attribute(s) to be read/written.
If the attribute(s) are to be read (regardless of whether or not they are 
also being changed) then the last argument should be a pointer to
an object, otherwise the last argument should be the object itself.
.PP
If mode is
.I pc_\s-1READ\s+1,
then the desired attributes are copied into
the object pointed to by the last parameter. If the mode is
.I pc_\s-1WRITE\s+1,
then the attributes from the last parameter are copied to the command-
object. If mode is
.I pc_\s-1RDWR\s+1,
then the attributes pointed to by the last
parameter are copied to the command-object, and then the previous value
of these attributes (before they were overwritten) is copied into the
object pointed to by the last parameter.
.PP
If cntl is
.I pc_\s-1ARGFLAGS\s+1,
then the only valid mode is
.I pc_\s-1READ\s+1.
All other attributes may be written or read by
.I parsecntl.
SHAR_EOF
chmod 0664 parseargs/doc/parsecntl3.inc ||
echo 'restore of parseargs/doc/parsecntl3.inc failed'
Wc_c="`wc -c < 'parseargs/doc/parsecntl3.inc'`"
test 1721 -eq "$Wc_c" ||
	echo 'parseargs/doc/parsecntl3.inc: original size 1721, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= parseargs/doc/parsecntls.inc ==============
if test -f 'parseargs/doc/parsecntls.inc' -a X"$1" != X"-c"; then
	echo 'x - skipping parseargs/doc/parsecntls.inc (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting parseargs/doc/parsecntls.inc (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/parsecntls.inc' &&
.\"----------------------------------------------------------------------------
.\"-- This text was extracted using the following command:
.\"--   xdoc -man -p '[ \t]*' -s PARSE-CNTLS ../parseargs.h
.\"----------------------------------------------------------------------------
.SH "FUNCTION CODES"
.PP
Each of the following function codes specifies an attribute that
is to be manipulated by \fIparsecntl\fP.  The function code is the
second parameter to \fIparsecntl\fP. With the exception of
.I pc_\s-1ARGFLAGS\s+1,
each of the function codes corresponds to a call to \fIparsecntl\fP
using four parameters (
.I pc_\s-1ARGFLAGS\s+1
uses 5 parameters). In each case,
the last parameter is either the address of a buffer to write the
attribute to, or the actual buffer to read the attribute from 
(depending upon the mode \- the third parameter to \fIparsecntl\fP).
.\"---------------------------------------------
.IP "\fIpc_\s-1PARSEFLAGS\s+1"
This function code is used to read and/or modify the existing parsing 
parsing behavior. The fourth parameter to \fIparsecntl\fP should be a 
combination of pc_XXXX bitmasks if the parse-flags are only being
written, otherwise it should be a pointer to an \fIargMask_t\fP variable.
.\"---------------------------------------------
.IP "\fIpc_\s-1ARGFLAGS\s+1"
This function code may only be used to read the argument-flags of
a named argument. It is an error to specify a mode that attempts
to write the argument-flags with this function code. The fourth
parameter to \fIparsecntl\fP should be the keyword name of the argument
whose flags are to be read. The fifth (and final) argument should
be a pointer to the \fIargMask_t\fP variable which will receive the resulting
argument-flags.
.\"---------------------------------------------
.IP "\fIpc_\s-1DEFARGS\s+1"
This function code is used to query or modify the current default
argument-descriptor list for the given command. The fourth parameter
to \fIparsecntl\fP should be the argument-descriptor array to assign as the
new default-list (or the address of an argdesc-array if the default
list is being retrieved).
X
If a given option/qualifier does not appear to match any items in the
argdesc-array, a  default argdesc-array is then searched to match the
option. If it is STILL unmatched then it is flagged as such. The
default-argdesc array is automatically used by all programmer-defined
argdesc-array but may be unset or reset using the
.I pc_\s-1DEFARGS\s+1
function of
.I parsecntl.
In such a  manner, a  programmer could specify a
different set of default-arguments to search for. Furthermore, default
argdesc-arrays may also be assigned default argdesc-arrays, thus
allowing the programmer to define a whole search-list of default
argdesc-arrays for a given command.
X
This could prove useful in a situation where a set of commands have a
few common-options and differ in their remaining ones. If the same
\fImain()\fP were used for each command, then main could define one common
argdesc-array and then a set of argdesc-arrays for each command. \fIMain\fP
could then figure out which argdesc-array to used based on the name in
\fIargv[0]\fP, and set its default argdesc-array to be the common
argdesc-array, as in the following:
X
.nf
.ft 4
#include <parseargs.h>
X     .
X     .  \fIvariable declarations\fP
X     .
X
static ARGDESC common_args[] = {
X   STARTOFARGS,
X   { 'L', ARGOPT, argBool, __ &lflag, "list (list the items)" },
X   { 'I', ARGOPT, argStr, __ &item, "item (item to use)" },
X   ENDOFARGS
};
X
static ARGDESC cmd1_args[] = {
X   STARTOFARGS,
X   { 's', ARGOPT, argBool, __ &sflag, "S (set S)" },
X   { 't', ARGOPT, argBool, __ &tflag, "T (set T)" },
X   ENDOFARGS
};
X
static ARGDESC cmd2_args[] = {
X   STARTOFARGS,
X   { 'x', ARGOPT, argBool, __ &xflag, "X (set X)" },
X   { 'y', ARGOPT, argBool, __ &yflag, "Y (set Y)" },
X   ENDOFARGS
};
X
main( int argc, char *argv[] )
{
X   ARGDESC *cmd = cmd1_args;
X   int  rc;
X
X   if ( strcmp(*argv, "cmd2") == 0 )
X      cmd = cmd2_args;
X
X   rc = parsecntl( cmd, pc_DEFARGS, pc_WRITE, common_args );
X   if ( rc != pe_SUCCESS )
X      syserr( "unable to set default args" );
X
X   rc = parseargs( argv, cmd );
X      .
X      .
X      .
}
.ft R
.fi
X
Note that in the above call to
.IR parsecntl(3),
that zero will be
returned upon success and non-zero upon failure. If pe_DEFARGS is
returned, then cmd is already on common_args's list of defaults (and
would result in an infinite loop while parsing).
.\"---------------------------------------------
.IP "\fIpc_\s-1NAME\s+1\fP"
.IP "\fIpc_\s-1PURPOSE\s+1\fP"
.IP "\fIpc_\s-1DESCRIPTION\s+1\fP"
Each of these last three function codes are used to modify or query the
name, purpose, or description associated with a command. The fourth
parameter to \fIparsecntl\fP should be the new string to use (or the address
of the string, a \fIchar**\fP variable, to recieve the current value).
SHAR_EOF
chmod 0664 parseargs/doc/parsecntls.inc ||
echo 'restore of parseargs/doc/parsecntls.inc failed'
Wc_c="`wc -c < 'parseargs/doc/parsecntls.inc'`"
test 4875 -eq "$Wc_c" ||
	echo 'parseargs/doc/parsecntls.inc: original size 4875, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= parseargs/doc/parseflags.inc ==============
if test -f 'parseargs/doc/parseflags.inc' -a X"$1" != X"-c"; then
	echo 'x - skipping parseargs/doc/parseflags.inc (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting parseargs/doc/parseflags.inc (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/parseflags.inc' &&
.\"----------------------------------------------------------------------------
.\"-- This text was extracted using the following command:
.\"--   xdoc -man -p '[ \t]*' -s PARSE-FLAGS ../parseargs.h
.\"----------------------------------------------------------------------------
.SH "PARSE FLAGS"
.PP
The following bitmasks may be combined in order to modify the
behavior of the parseargs library. The parse flags for a given
may be set through the use of the \fIparsecntl\fP(3) function.
.\"---------------------------------------------
.IP "\fIpa_\s-1PROMPT\s+1\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 "\fIpa_\s-1IGNORE\s+1\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 "\fIpa_\s-1OPTSONLY\s+1\fP"
Under \s-1UNIX\s+1, 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 "\fIpa_\s-1KWDSONLY\s+1\fP"
Under \s-1UNIX\s+1, 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 "\fIpa_\s-1FLAGS1ST\s+1\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 \s-1UNIX\s+1, if this flag is \s-1SET\s+1 then
.I parseargs
will consider the command line "\fBcmd \-x\fI arg\fR" to consist of one
option and one positional argument; however the command line
"\fBcmd\fI arg -x\fR" would be considered to consist of two positional
arguments (the \fB\-x\fP option will be unmatched).
X
If this flag is \s-1UNSET\s+1, then both of the previous examples are
considered to consist of one option and one positional argument.
.\"---------------------------------------------
.IP "\fIpa_\s-1ANYCASE\s+1\fP"
Setting this flag will cause character-case to be ignored when attempting
to match single-character argument names (i.e. causes "\fB\-i\fP" and
"\fB\-I\fP" will be considered equivalent).
.\"---------------------------------------------
.IP "\fIpa_\s-1ARGV0\s+1\fP"
Normally, the parseargs library will assume that the first argument
on the command-line is the name of the command. Setting this flag
tells parseargs that this is \s-1NOT\s+1 the case and that the very first
argument on the command-line is a bona-fide argument to the command.
.\"---------------------------------------------
.IP "\fIpa_\s-1NOCHECK\s+1\fP"
Setting this flag will prevent parseargs from checking for any 
required arguments that were not given on the command-line. This
is useful when more than one call to the parseargs library is needed
to parse all the command-line arguments (which could occur if the
command-line argument came from a file or from two argv-vectors).
X
Keeping this flag on until the final set of arguments is parsed will
cause parseargs to not check for missing arguments until the last set
of arguments has been parsed (by the final call to *parseargs).
.\"---------------------------------------------
.IP "\fIpa_\s-1CONTINUE\s+1\fP"
Setting this flag will cause subsequent calls to the parseargs library
to \s-1NOT\s+1 reset the current command-state. Hence, all arguments will not
be initially set to "\s-1NOT GIVEN\s+1" and other (normal) initializations are
not be performed.  This is useful in conjunction with the
\fIpa_\s-1NOCHECK\s+1\fP flag when more than one call to
.I parseargs
is required to parse all the command arguments. In this scenario,
\fIpa_\s-1CONTINUE\s+1\fP should be unset (the default setting) for the very
first call to
.I parseargs,
but should then be set before any subsequent calls to
.I parseargs
are made.
.\"---------------------------------------------
.IP "\fIpa_\s-1NOCMDENV\s+1\fP"
Setting this flag prevents parseargs from checking the
\s-1\fICMD-NAME\fP_ARGS\s+1 environment variable (or symbol) for any
user-defined default command arguments.
.\"---------------------------------------------
.IP "\fIpa_\s-1COPYF\s+1\fP"
When this flag is \s-1OFF\s+1 (the default), a value of \s-1FALSE\s+1 is
provided as the \fIcopyf\fP argument to all the arg-type
.I (argXxxxx)
functions when an argument is matched. Setting this flag will cause a value of
\s-1TRUE\s+1 to be provided as the \fIcopyf\fP argument to all the arg-type
.I (argXxxxx)
functions when an argument is matched.
.\"---------------------------------------------
SHAR_EOF
chmod 0664 parseargs/doc/parseflags.inc ||
echo 'restore of parseargs/doc/parseflags.inc failed'
Wc_c="`wc -c < 'parseargs/doc/parseflags.inc'`"
test 5108 -eq "$Wc_c" ||
	echo 'parseargs/doc/parseflags.inc: original size 5108, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= parseargs/doc/parsemodes.inc ==============
if test -f 'parseargs/doc/parsemodes.inc' -a X"$1" != X"-c"; then
	echo 'x - skipping parseargs/doc/parsemodes.inc (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting parseargs/doc/parsemodes.inc (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/parsemodes.inc' &&
.\"----------------------------------------------------------------------------
.\"-- This text was extracted using the following command:
.\"--   xdoc -man -p '[ \t]*' -s PARSE-MODES ../parseargs.h
.\"----------------------------------------------------------------------------
.SH "PARSE MODES"
.PP
\fIParsecntl\fP may be used to read current command attributes, write
(assign) new command attributes, or both. The mode argument to
parsecntl determines the which of these three alternatives are
desired. If the programmer merely wishes to assign new attributes,
then invoking \fIparsecntl\fP in \fIpc_\s-1WRITE\s+1\fP mode and passing
the new attributes will do the job. If the programmer wishes simply to query
attributes, then invoking \fIparsecntl\fP in \fIpc_\s-1READ\s+1\fP mode and
passing a pointer to the desired object in which to write the attribute
settings will suffice.
X
If the programmer wishes to assign new attributes and at the same time
find out what the attributes were before making the assignment, then
programmer must invoke \fIparsecntl\fP for \fIpc_\s-1RDWR\s+1\fP mode
and pass a pointer to the object containing the new attribute settings;
When \fIparsecntl\fP returns, then (assuming it returns 0) the desired
attributes will have been assigned and the object that contained the
new attribute settings will now contain the attribute settings that
were in effect before \fIparsecntl\fP was invoked.
SHAR_EOF
chmod 0664 parseargs/doc/parsemodes.inc ||
echo 'restore of parseargs/doc/parsemodes.inc failed'
Wc_c="`wc -c < 'parseargs/doc/parsemodes.inc'`"
test 1427 -eq "$Wc_c" ||
	echo 'parseargs/doc/parsemodes.inc: original size 1427, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= parseargs/doc/returns.inc ==============
if test -f 'parseargs/doc/returns.inc' -a X"$1" != X"-c"; then
	echo 'x - skipping parseargs/doc/returns.inc (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting parseargs/doc/returns.inc (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/returns.inc' &&
.\"----------------------------------------------------------------------------
.\"-- This text was extracted using the following command:
.\"--   xdoc -man -p '[ \t]*' -s RETURN-CODES ../parsearegs.h
.\"----------------------------------------------------------------------------
.SH "RETURN VALUE"
.PP
The functions in the \fIparseargs\fP library will return a value of zero
upon succesful completion. They may however, return any of
the following status codes (which are defined in <parseargs.h>):
.\"---------------------------------------------
.IP "\fIpe_\s-1SYSTEM\s+1\fP"
A system error occurred. The global variable \fIerrno\fP may indicate
the problem (then again, it may not).
.\"---------------------------------------------
.IP "\fIpe_\s-1SUCCESS\s+1\fP"
Success, no errors encountered (zero is returned).
.\"---------------------------------------------
.IP "\fIpe_\s-1SYNTAX\s+1\fP"
A command-line syntax error was encountered
.\"---------------------------------------------
.IP "\fIpe_\s-1DEFARGS\s+1\fP"
An attempt (using \fIparsecntl\fP) was made to change the
default arg-search list of a command to point to an argdesc-array
which already has the given command on its default arg-search list
(which would cause an infinite loop when attempting to match an
unknown command-line argument).
.\"---------------------------------------------
.IP "\fIpe_\s-1NOMATCH\s+1\fP"
Unable to match the named argument. This occurs
when the argument keyword name passed to \fIparsecntl\fP (using the 
\fIpc_\s-1ARGFLAGS\s+1\fP functions code) was found in the given argdesc-array
or in its default-list.
.\"---------------------------------------------
.IP "\fIpe_\s-1BADMODE\s+1\fP"
Bad mode for given command in \fIparsecntl\fP. This occurs when 
\fIpc_\s-1WRITE\s+1\fP or \fIpc_\s-1RDWR\s+1\fP mode is passed to
.I parsecntl
in conjunction with the \fIpc_ARGFLAGS\fP functions code.
.I Parsecntl
will not modify existing arguments.
.\"---------------------------------------------
.IP "\fIpe_\s-1BADCNTL\s+1\fP"
Bad command for parsecntl. This occurs if an unknown function-code
was passed to \fIparsecntl\fP.
SHAR_EOF
chmod 0664 parseargs/doc/returns.inc ||
echo 'restore of parseargs/doc/returns.inc failed'
Wc_c="`wc -c < 'parseargs/doc/returns.inc'`"
test 2118 -eq "$Wc_c" ||
	echo 'parseargs/doc/returns.inc: original size 2118, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= parseargs/doc/sh_arrays.inc ==============
if test -f 'parseargs/doc/sh_arrays.inc' -a X"$1" != X"-c"; then
	echo 'x - skipping parseargs/doc/sh_arrays.inc (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting parseargs/doc/sh_arrays.inc (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/sh_arrays.inc' &&
.\"----------------------------------------------------------------------------
.\"-- This text was extracted using the following command:
.\"--   xdoc -man -n -p '[ \t]*' -I DESCRIPTION -f put_argvector ../parseargs.c
.\"----------------------------------------------------------------------------
.SH ARGUMENT LISTS
.PP
.B Parseargs
treats \s-1ARGLIST\s+1 arguments in a special way. The method used for
setting up an argument list depends largely upon the syntax of shell
that was specified on the command line via the \fB\-s\fP option
(although \s-1ARGLIST\s+1 arguments are treated exactly the same as
\s-1ARGVEC\s+1 arguments).
.\"---------------
.SS "Resetting the Positional Parameters to an Argument List"
.PP
For the Bourne, Bourne-Again, and Korn shells,
if the variable name corresponding to the \s-1ARGLIST\s+1 argument is
``\fB\-\^\-\fP'', then the positional parameters of the calling program
will be re-assigned to the contents of the argument list ($1 will be the
first item, $2 the second item, and so on). In this particular case, the
calling program may wish to use the \fB\-u\fP option to reset the positional
parameters to \s-1NULL\s+1 before making any shell-variable assignments
(this way, the positional parameters will be unset if the associated list
of command line arguments is not encountered).
.PP
Similarly for the C and TC shells,
if the variable name corresponding to the \s-1ARGLIST\s+1 argument is
``\fBargv\fP'', then the positional parameters of the calling program
will be re-assigned to the contents of the argument list.
.PP
For the Plan 9 shell (rc),
if the variable name corresponding to the \s-1ARGLIST\s+1 argument is
``\fB*\fP'', then the positional parameters of the calling program
will be re-assigned to the contents of the argument list.
.PP
For the \fIawk\fP and \fIperl\fP,
if the variable name corresponding to the \s-1ARGLIST\s+1 argument is
``\fBARGV\fP'', then the positional parameters of the calling program
will be re-assigned to the contents of the argument list.
.SS "Bourne Shell Argument Lists"
.PP
For the Bourne shell, if the associated variable name is \s-1NOT\s+1
``\fB\-\^\-\fP'' and the \fB\-A\fP option was \s-1NOT\s+1 specified,
then that variable is treated as a regular shell variable and is assigned
using the following syntax:
.sp 2p
.RS
\f4name\^=\^'arg1 arg2\fP  \fI...\fP\f4'\fP
.RE
.sp 2p
After invoking \fBparseargs\fP, if you wish to go through all the
words in the variable \fIname\fP and one of the words in \fIname\fP
contains an \s-1IFS\s+1 character (such as a space or a tab), then
that particular word will be treated by the Bourne shell as two distinct words.
.sp 8p
Also for the Bourne shell,
If the associated variable name is \s-1NOT\s+1 ``\fB\-\^\-\fP'' and the
\fB\-A\fP option \s-1WAS\s+1 specified, then that variable is treated as
the root name of an array that is set using the following syntax:
.sp 2p
.RS
.nf
\f4name1\^=\^'arg1'\fP
\f4name2\^=\^'arg2'\fP
\0\0\0 ...
.fi
.RE
.sp 2p
and the variable ``\f4name_count\fP'' will be set to contain the number of
items in the array.  The user may then step through all the items in the array
using the following syntax:
.sp 2p
.RS
.nf
.ft 4
i=1
while [ $i -le $name_count ] ; do
X  eval echo "item #$i is: " \\$name$i
X  i=`expr $i + 1`
done
.ft R
.fi
.RE
.SS "Korn Shell Argument Lists"
.PP
For the Korn shell, if the associated variable name is \s-1NOT\s+1
``\fB\-\^\-\fP'', then that variable is treated as an array and is assigned
using the \fB\-A\fP option of the set command. The first item will be in
\f4${name[0]}\fP, the second item will be in \f4${name[1]}\fP, etc ...,
and all items may be given by \f4${name[*]}\fP or \f4${name[@]}\fP.
If the associated variable name is \s-1NOT\s+1 ``\fB\-\^\-\fP'' and the
\fB\-A\fP option \s-1WAS\s+1 specified, then that variable is assigned
using the \fB+A\fP option of the set command (which preserves any array
elements that were not overwritten by the set command).
.sp 2p
It should be noted that there is a bug in versions of the Korn shell
earlier than 11/16/88a, in which the following:
.sp 2p
.RS
\f4set  \-A  name  'arg1'  'arg2'\fP  \fI...\fP
.RE
.sp 2p
causes the positional parameters to be overwritten as an unintentional
side-effect. If your version of the Korn shell is earlier than this and you
wish to keep the contents of your positional parameters after invoking
\fBparseargs\fP than you must save them yourself before you call
\fBparseargs\fP. This may be accomplished by the following:
.sp 2p
.RS
\f4set  \-A  save_parms  "$@"\fP
.RE
.SS "C and TC Shell Argument Lists"
.PP
For the C and TC shells, \s-1ARGLIST\s+1 variables are treated as word-lists
and are assigned using the following syntax:
.sp 2p
.RS
\f4set  name = ( 'arg1'  'arg2'\fP  \fI...\fP\f4 )\fP
.RE
.sp 2p
The first item will be in \f4$name[1]\fP, the second item will be in
\f4$name[2]\fP, etc ..., and all items may be given by \f4$name\fP.
Notice that Korn shell arrays start at index zero whereas C and TC shell
word-lists start at index one.
.SS "Bourne-Again Shell Argument Lists"
.PP
At present, the Free Software Foundation's Bourne-Again shell is treated
exactly the same as the Bourne Shell. This will change when \fIbash\fP
supports arrays.
.SS "Plan 9 Shell Argument Lists"
.PP
For the Plan 9 shell, if the associated variable name is not ``*'' then
it is considered to be word-list and set using the following syntax:
.nf
.RS
.ft 4
name=( 'arg1'  'arg2'  ... )
.ft R
.RE
.fi
.SS "Awk Argument Lists"
For \fIawk\fP, if the \fB\-A\fP option is not given, then the output for thes
variable-list will be a line with the variable name, followed by a line with
each of the values (each value will be separated with the field separator
specified using the \fB\-S\fP option - which defaults to a space). 
.nf
.RS
.ft 4
name
arg1  arg2  ...
.ft R
.RE
.fi
If the \fB\-A\fP option is given, then the associated variable is considered
the root name of an array. The ouput for the array
will consist of two lines for each item in the list (as in the following
expample):
.nf
.RS
.ft 4
name1
arg1
X
name2
arg2
X
\...
.ft R
.RE
.fi
and the variable ``\f4name_count\fP'' will have an output line showing the
number of items in the array.
.PP
.SS "Perl Argument Lists"
.PP
For \fIperl\fP, each argument list is considered an array and is set using 
the following syntax:
.nf
.RS
.ft 4
@name=( arg1 , arg2 ,  ... )
.ft R
.RE
.fi
.SS ""A Final Note on Argument Lists"
.PP
The word-lists used by the C shell, the arrays used by the Korn shell, the 
Plan 9 shell, \fIawk\fP, \fIperl\fP, and the positional parameters used by
all shells (if overwritten by \fBparseargs\fP) will preserve any \s-1IFS\s+1
characters in their contents.  That is to say that if an item in one of the
aforementioned multi-word lists contains any \s-1IFS\s+1 characters, it will
not be split up into multiple items but will remain a single item which
contains \s-1IFS\s+1 characters.
SHAR_EOF
chmod 0664 parseargs/doc/sh_arrays.inc ||
echo 'restore of parseargs/doc/sh_arrays.inc failed'
Wc_c="`wc -c < 'parseargs/doc/sh_arrays.inc'`"
test 6926 -eq "$Wc_c" ||
	echo 'parseargs/doc/sh_arrays.inc: original size 6926, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= parseargs/doc/shells.inc ==============
if test -f 'parseargs/doc/shells.inc' -a X"$1" != X"-c"; then
	echo 'x - skipping parseargs/doc/shells.inc (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting parseargs/doc/shells.inc (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/shells.inc' &&
.\"----------------------------------------------------------------------------
.\"-- This text was extracted using the following command:
.\"--   xdoc -man -p '[ \t]*' -s SHELLS ../parseargs.c
.\"----------------------------------------------------------------------------
.SH SHELLS
.PP
After the command line has been parsed, \fBparseargs\fP will print on
standard output, a script to set the shell variables which correspond to
arguments that were present on the command-line.
This script may be evaluated by redirecting it to a file and then executing
the file, or by directly evaluating the output from \fBparseargs\fP
(under most \s-1UNIX\s+1 shells, this could be done using \fBeval\fP).
If any arguments on the command line contained any special characters that
needed to be escaped from the shell, these characters will remain intact
(not be evaluated by the shell) in the corresponding shell variable.
.PP
The \fB\-s\fP \fIshell\fP option may be used to tell \fBparseargs\fP which
shell syntax to use. At present, \fBparseargs\fP only recognizes
``sh'', ``csh'', ``ksh'', ``tcsh'', ``bash'', ``rc'', ``awk'', and ``perl''
as valid command interpreters. \fIAwk\fP output is slightly different from 
that of the other shells in that the actual variable setting are not
printed but each line of an associative array is printed (the first field
is the array index, the second is the value for that index).
If no shell is specified, then the Bourne shell (``sh'') will be assumed.
.PP
If the user wishes to use a value other than ``\s-1TRUE\s+1'' for a boolean
flag that is true, this may be done using the \fB\-T\fP \fIstring\fP option.
The same may also be done for a boolean flag that is false using the
\fB\-F\fP \fIstring\fP option.
.PP
.B Parseargs
will only set the values of variables that correspond to arguments that
were given on the command line. If a particular argument was not supplied
on the command line, then no assignment is made for the corresponding
shell variable and it will have the same value that it had before
.B parseargs
was invoked. The only exception to this is that if the \fB\-u\fP option is
specified, then the positional parameters are unset before any shell variable
assignments (which may reset the positional parameters) are made.
SHAR_EOF
chmod 0664 parseargs/doc/shells.inc ||
echo 'restore of parseargs/doc/shells.inc failed'
Wc_c="`wc -c < 'parseargs/doc/shells.inc'`"
test 2275 -eq "$Wc_c" ||
	echo 'parseargs/doc/shells.inc: original size 2275, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= parseargs/doc/sparseargs3.inc ==============
if test -f 'parseargs/doc/sparseargs3.inc' -a X"$1" != X"-c"; then
	echo 'x - skipping parseargs/doc/sparseargs3.inc (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting parseargs/doc/sparseargs3.inc (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/sparseargs3.inc' &&
.\"----------------------------------------------------------------------------
.\"-- This text was extracted using the following command:
.\"--   xdoc -man -n -p '[ \t]*' -I DESCRIPTION -f sparseargs ../xparse.c
.\"----------------------------------------------------------------------------
.PP
Given a single string and an argdesc array, \fIsparseargs\fP
will parse arguments from a string in much the same manner as \fIparseargs\fP.
.I Sparseargs
will split the given string up into a vector of whitespace
separated tokens and then attempt to parse the resultant vector as
if it were given as \fIargv[]\fP on the command-line.
NO special treatment is given to characters such as single-quotes,
double-quotes, or anything else. \fISparseargs\fP will always assume that
any whitespace characters are intended as argument separators.
X
SHAR_EOF
chmod 0664 parseargs/doc/sparseargs3.inc ||
echo 'restore of parseargs/doc/sparseargs3.inc failed'
Wc_c="`wc -c < 'parseargs/doc/sparseargs3.inc'`"
test 836 -eq "$Wc_c" ||
	echo 'parseargs/doc/sparseargs3.inc: original size 836, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= parseargs/doc/usage3.inc ==============
if test -f 'parseargs/doc/usage3.inc' -a X"$1" != X"-c"; then
	echo 'x - skipping parseargs/doc/usage3.inc (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting parseargs/doc/usage3.inc (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/usage3.inc' &&
.\"----------------------------------------------------------------------------
.\"-- This text was extracted using the following command:
.\"--   xdoc -man -n -p '[ \t]*' -I DESCRIPTION -f usage ../xparse.c
.\"----------------------------------------------------------------------------
.PP
Given an argdesc array, \fIusage\fP will print the usage for the given
command in the format specified by the user's \s-1USAGECNTL\s+1 environment
variable.
SHAR_EOF
chmod 0664 parseargs/doc/usage3.inc ||
echo 'restore of parseargs/doc/usage3.inc failed'
Wc_c="`wc -c < 'parseargs/doc/usage3.inc'`"
test 449 -eq "$Wc_c" ||
	echo 'parseargs/doc/usage3.inc: original size 449, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= parseargs/doc/vparseargs3.inc ==============
if test -f 'parseargs/doc/vparseargs3.inc' -a X"$1" != X"-c"; then
	echo 'x - skipping parseargs/doc/vparseargs3.inc (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting parseargs/doc/vparseargs3.inc (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'parseargs/doc/vparseargs3.inc' &&
.\"----------------------------------------------------------------------------
.\"-- This text was extracted using the following command:
.\"--   xdoc -man -n -p '[ \t]*' -I DESCRIPTION -f vparseargs ../xparse.c
.\"----------------------------------------------------------------------------
.PP
.I Vparseargs
takes an argdesc array, the number of arguments to parse, and a
(possibly NULL terminated) list of argument-strings
and parses them in much the same manner as \fIparseargs\fP.
Unlike
.I sparseargs,
.I vparseargs
assumes that all parameters are already split up into tokens, hence any
whitespace characters contained in any of the string-parameters are used as
is (and will be considered a part of an argument name or value).
X
SHAR_EOF
chmod 0664 parseargs/doc/vparseargs3.inc ||
echo 'restore of parseargs/doc/vparseargs3.inc failed'
Wc_c="`wc -c < 'parseargs/doc/vparseargs3.inc'`"
test 737 -eq "$Wc_c" ||
	echo 'parseargs/doc/vparseargs3.inc: original size 737, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= parseargs/ibm_args.c ==============
if test -f 'parseargs/ibm_args.c' -a X"$1" != X"-c"; then
	echo 'x - skipping parseargs/ibm_args.c (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting parseargs/ibm_args.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'parseargs/ibm_args.c' &&
/*************************************************************************
** ^FILE: ibm_args.c - parse MS-DOS and OS/2 argument vectors
**
** ^DESCRIPTION:
**    This file contains the routines used to parse MS-DOS and OS/2
**    argument vectors and to print MS-DOS and OS/2 usage messages.
**
** ^HISTORY:
**    01/02/91 	Brad Appleton 	<brad@ssd.csd.harris.com>	Created
***^^**********************************************************************/
X
#include <ctype.h>
#include <useful.h>
#include "strfuncs.h"
#include "pgopen.h"
X
#define PARSEARGS_PRIVATE   /* include private definitions */
#include "parseargs.h"
X
EXTERN  VOID  syserr       ARGS((const char *, ...));
EXTERN  VOID  usrerr       ARGS((const char *, ...));
EXTERN  char *getenv       ARGS((const char *));
EXTERN  VOID  get_winsize  ARGS((int, int *, int *));
X
VERSIONID("$Header: parseargs.c,v 2.1 89/12/30 20:59:48 eric Exp $");
X
/***************************************************************************
** ^GLOBAL-VARIABLE: OptPrefix, KwdPrefix
**
** ^VISIBILITY:
**    static-global (visible to all functions in this file).
**
** ^DESCRIPTION:
**    OptPrefix contains the single character prefix used to precede
SHAR_EOF
true || echo 'restore of parseargs/ibm_args.c failed'
fi
echo 'End of  part 4'
echo 'File parseargs/ibm_args.c is continued in part 5'
echo 5 > _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.