[comp.sources.misc] v19i083: parseargs - functions to parse command line argument, Patch05b/5

Brad Appleton <brad@hcx1.ssd.csd.harris.com> (05/18/91)

Submitted-by: Brad Appleton <brad@hcx1.ssd.csd.harris.com>
Posting-number: Volume 19, Issue 83
Archive-name: parseargs/patch05b
Patch-To: parseargs: Volume 17, Issue 45-57

#!/bin/sh
# do not concatenate these parts, unpack them in order with /bin/sh
# file PATCH05 continued
#
if test ! -r _shar_seq_.tmp; then
	echo 'Please unpack part 1 first!'
	exit 1
fi
(read Scheck
 if test "$Scheck" != 2; 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 PATCH05'
else
echo 'x - continuing file PATCH05'
sed 's/^X//' << 'SHAR_EOF' >> 'PATCH05' &&
! takes one parameter: the address of the first item in the arg-list.
X  .PP
X  An alternative to argument-lists is argument vectors (or arg-vectors).
X  Arg-vectors use the \s-1ARGVEC\s+1 flag instead of the \s-1ARGLIST\s+1 flag
X  and do not require a special \fIlistXxxx\fP function for each vector-type.
X  Each of the \fIargXxxx\fP functions is responsible for handling vectors of its
! type (although some \fIargXxx\fP 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 \f4argc,argv\fP pair), and an array of flags,
! one for each element of argv. There are two macros in defined in
X  \f4<parseargs.h>\fR which are used for arg-vectors. \s-1ARGVEC_T\s+1 may be
X  used to declare a vector structure or a vector type;
X  \s-1ARGVEC_EMPTY\s+1 may be used to initialize the structure.
diff -cNr ../patchlevel4/doc/parseargs.man1 ./doc/parseargs.man1
*** ../patchlevel4/doc/parseargs.man1	Thu May  2 11:01:33 1991
--- ./doc/parseargs.man1	Thu May  2 14:35:21 1991
***************
*** 12,31 ****
X  .SH SYNOPSIS
X  .TP 12
X  \fBparseargs\fP
! [\fB\-U\fP]
! [\fB\-M\fP]
X  [\fB\-T\fP\ \fIstring\fP]
X  [\fB\-F\fP\ \fIstring\fP]
- [\fB\-A\fP]
X  [\fB\-a\fP\ \fIarg-spec\fP]
X  [\fB\-e\fP\ \fIname\fP]
X  [\fB\-f\fP\ \fIfile\fP]
- [\fB\-l\fP]
- [\fB\-o\fP]
X  [\fB\-s\fP\ \fIshell\fP\^]
- [\fB\-u\fP]
- [\fB\-i\fP]
- [\fB\-p\fP]
X  \fB\-\^\-\fP
X  \fIname\fP
X  [\fIarguments\fP\ .\^.\^.\^]
--- 12,25 ----
X  .SH SYNOPSIS
X  .TP 12
X  \fBparseargs\fP
! [\fB\-#UMCAlouip1\fP]
! [\fB\-S\fP\ \fIseparator\fP]
X  [\fB\-T\fP\ \fIstring\fP]
X  [\fB\-F\fP\ \fIstring\fP]
X  [\fB\-a\fP\ \fIarg-spec\fP]
X  [\fB\-e\fP\ \fIname\fP]
X  [\fB\-f\fP\ \fIfile\fP]
X  [\fB\-s\fP\ \fIshell\fP\^]
X  \fB\-\^\-\fP
X  \fIname\fP
X  [\fIarguments\fP\ .\^.\^.\^]
***************
*** 32,37 ****
--- 26,34 ----
X  .\"-----------------------------------------------------------
X  .SH OPTIONS
X  .TP 14
+ \fB\-#\fP
+ just print the version and patchlevel, do not parse the command line
+ .TP 14
X  \fB\-U\fP
X  just print program usage, do not parse the command line
X  .TP 14
***************
*** 38,43 ****
--- 35,43 ----
X  \fB\-M\fP
X  just print (n|t)roff \-man manual page template, do not parse the command line
X  .TP 14
+ \fB-S\fP\ \fIseparator\fP
+ field-separator-string used to delimit array elements  (\fIdefault=``\0''\fP\|)
+ .TP 14
X  \fB\-T\fP \fIstring\fP
X  string to use for true boolean arguments\|  (\fIdefault=``\s-1TRUE\s+1\^''\fP\|)
X  .TP 14
***************
*** 44,49 ****
--- 44,53 ----
X  \fB\-F\fP \fIstring\fP
X  string to use for false boolean arguments  (\fIdefault=``\^''\fP\|)
X  .TP 14
+ \fB\-C\fP
+ Ignore the difference between upper and lower case when parsing single
+ character options.
+ .TP 14
X  \fB\-A\fP
X  modify array behavior for the specified shell.
X  .TP 14
***************
*** 73,78 ****
--- 77,86 ----
X  .TP 14
X  \fB\-i\fP
X  ignore bad command-line syntax and continue processing (instead of aborting)
+ .TP 14
+ \fB\-1\fP
+ Force any and all non-positional parameters to be specified before any
+ positional parameters on the command-line.
X  .\"-----------------------------------------------------------
X  .SH ARGUMENTS
X  .TP 14
***************
*** 89,95 ****
X  .\"-----------------------------------------------------------
X  .PP
X  The argument specification string contains one entry for each possible flag.
! Entries in the arguments specification string are separated by commas.
X  Each entry has five comma-separated fields:
X  a name, some flags, a type, a variable-name, and a prompt.
X  Each of these fields are described below:
--- 97,103 ----
X  .\"-----------------------------------------------------------
X  .PP
X  The argument specification string contains one entry for each possible flag.
! Entries in the argument specification string are separated by commas.
X  Each entry has five comma-separated fields:
X  a name, some flags, a type, a variable-name, and a prompt.
X  Each of these fields are described below:
***************
*** 110,134 ****
X  to indicate an optional argument
X  (\s-1ARGOPT\s+1 is the default unless \s-1ARGREQ\s+1 is specified).
X  \s-1ARGPOS\s+1
! can be ``ored'' in to indicate a positional argument that may also
X  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.
X  \s-1ARGVALOPT\s+1
! can be ``ored'' in to indicate that an argument to the option may be
X  optionally supplied on the command-line, but is not required.
X  \s-1ARGVALREQ\s+1
! can be ``ored'' in to indicate that an argument to the option is required
X  (this is the default behavior for options that take arguments).
X  \s-1ARGLIST\s+1
! can be ``ored'' in (using the `\^|\^' character) to indicate that an argument
X  is actually a list of one or more arguments from the command line.
X  \s-1ARGHIDDEN\s+1
! can be ``ored'' in to indicate a flag that should not be printed
X  in usage messages \(em
X  for example, flags intended for internal debugging purposes.
X  .TP 10
--- 118,136 ----
X  to indicate an optional argument
X  (\s-1ARGOPT\s+1 is the default unless \s-1ARGREQ\s+1 is specified).
X  \s-1ARGPOS\s+1
! may be ``ored'' in to indicate a positional argument that may also
X  be keyword matched.
X  \s-1ARGVALOPT\s+1
! may be ``ored'' in to indicate that an argument to the option may be
X  optionally supplied on the command-line, but is not required.
X  \s-1ARGVALREQ\s+1
! may be ``ored'' in to indicate that an argument to the option is required
X  (this is the default behavior for options that take arguments).
X  \s-1ARGLIST\s+1
! may be ``ored'' in (using the `\^|\^' character) to indicate that an argument
X  is actually a list of one or more arguments from the command line.
X  \s-1ARGHIDDEN\s+1
! may be ``ored'' in to indicate a flag that should not be printed
X  in usage messages \(em
X  for example, flags intended for internal debugging purposes.
X  .TP 10
***************
*** 175,181 ****
X  to the script if there is a limit to the number of arguments and/or characters
X  that may appear on the command line.
X  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
X  and read using the \fB\-f\fP \fIfile\fP option; or read from standard input.
X  When using the \fB\-e\fP option, the user must remember to use the name
X  of an environment variable (not a mere shell variable)!
--- 177,183 ----
X  to the script if there is a limit to the number of arguments and/or characters
X  that may appear on the command line.
X  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
X  and read using the \fB\-f\fP \fIfile\fP option; or read from standard input.
X  When using the \fB\-e\fP option, the user must remember to use the name
X  of an environment variable (not a mere shell variable)!
***************
*** 191,197 ****
X  The default behavior of parseargs is to allow both single-character options and
X  long-options (keywords) on the command-line. The user may specify that only
X  options (long-options) are to be permitted by specifying the \fB\-o\fP
! (\fB\-l\) option on the command-line.
X  .\"----------------------------------------------------------------
X  .so argvalopt.inc
X  .\"----------------------------------------------------------------
--- 193,213 ----
X  The default behavior of parseargs is to allow both single-character options and
X  long-options (keywords) on the command-line. The user may specify that only
X  options (long-options) are to be permitted by specifying the \fB\-o\fP
! (\fB\-l\fP) option on the command-line.
! .\"----------------------------------------------------------------
! .SH "SPECIFYING PARSE-BEHAVIOR"
! .PP
! The \fB\-C\fP, \fB\-p\fP, \fB\-i\fP, and \fB\-1\fP switches may be used to
! modify the command-line parsing behavior of the invoking script. Specifying
! \fB\-C\fP will cause case-differences in single-character options to be
! ignored. Specifying \fB\-p\fP will cause the user to be interactively prompted
! for any missing required arguments. Specifying \fB\-i\fP will cause
! syntactically incorrect arguments to be ignored (instead of having a usage
! message printed and execution terminated). Specifying \fB\-1\fP will force
! all non-positional parameters to precede any positional parameters on the
! command-line (hence anything on the command-line after a positional parameter
! that resembles a keyword parameter will nevertheles be interpreted as a
! positional parameter).
X  .\"----------------------------------------------------------------
X  .so argvalopt.inc
X  .\"----------------------------------------------------------------
***************
*** 227,233 ****
X  ENDOFARGS
X  "
X  .sp 8p
! eval `echo "$ARGUMENTS" | parseargs \-s sh \-\|\- $0 "$@"`
X  .sp 8p
X  .ft R
X  .fi
--- 243,249 ----
X  ENDOFARGS
X  "
X  .sp 8p
! eval `echo "$ARGSPEC" | parseargs \-s sh \-\|\- $0 "$@"`
X  .sp 8p
X  .ft R
X  .fi
***************
*** 300,308 ****
X  Normal exit status (no problems were encountered).
X  .TP 5
X  \|\|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.
X  .TP 5
X  \|\|2
X  A command line syntax error was encountered by \fBparseargs\fP. The offending
--- 316,324 ----
X  Normal exit status (no problems were encountered).
X  .TP 5
X  \|\|1
! The calling program specified the \fB\-#\fP, 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.
X  .TP 5
X  \|\|2
X  A command line syntax error was encountered by \fBparseargs\fP. The offending
diff -cNr ../patchlevel4/doc/parseargs.man3 ./doc/parseargs.man3
*** ../patchlevel4/doc/parseargs.man3	Thu May  2 11:01:45 1991
--- ./doc/parseargs.man3	Thu May  2 14:35:24 1991
***************
*** 2,19 ****
X  .TH PARSEARGS 3
X  .\"-----------------------------------------------------------
X  .SH NAME
! parseargs, usage \- parse command line argument vectors
X  .\"-----------------------------------------------------------
X  .SH SYNOPSIS
X  #include <parseargs.h>
X  .PP
X  .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, int argc,  ...  )
! void  usage(  const ARGDESC *argd  )
X  .fi
X  .\"-----------------------------------------------------------
X  .SH DESCRIPTION
--- 2,20 ----
X  .TH PARSEARGS 3
X  .\"-----------------------------------------------------------
X  .SH NAME
! parseargs \- parse command line argument vectors
X  .\"-----------------------------------------------------------
X  .SH SYNOPSIS
X  #include <parseargs.h>
X  .PP
X  .nf
! int  parseargs(  char *argv\f4[]\fP,  ARGDESC *argd  );
! int  fparseargs(  FILE *fp,  ARGDESC *argd  );
! int  lparseargs(  ArgList *argls,  ARGDESC *argd  );
! int  sparseargs(  char *str,  ARGDESC *argd  );
! int  vparseargs(  ARGDESC *argd, int argc,  ...  );
! void  usage(  const ARGDESC *argd  );
! extern  const char *ProgName;
X  .fi
X  .\"-----------------------------------------------------------
X  .SH DESCRIPTION
***************
*** 23,28 ****
--- 24,34 ----
X  .so sparseargs3.inc
X  .so vparseargs3.inc
X  .so usage3.inc
+ .PP
+ After returning from any of the aforementioned functions, the global
+ string \fIProgName\fP will contain the name of the command corresponding
+ to the argument-descriptor array that was most recently operated upon by
+ one the functions in the \fIparseargs\fP(3) function library.
X  .\"-----------------------------------------------------------
X  .so argdesc.inc
X  .\"-----------------------------------------------------------
***************
*** 42,48 ****
X  char	*InFile;
X  char	*OutFile =	CHARNULL;
X  BOOL	XRated =	FALSE;
! struct namelist *Files = NULL;
X  
X  ARGDESC Args[] =
X  {
--- 48,54 ----
X  char	*InFile;
X  char	*OutFile =	CHARNULL;
X  BOOL	XRated =	FALSE;
! ArgList *Files =    ARGLISTNULL;
X  
X  ARGDESC Args[] =
X  {
***************
*** 52,58 ****
X    ' ', ARGREQ,    argStr,  _\|_ &InFile,   "INPUTfile {input file}",
X    ' ', ARGOPT,    argStr,  _\|_ &OutFile,  "OUTPUTfile {output file}",
X    'X', ARGHIDDEN, argBool, _\|_ &XRated,   "XratedMODE {naughty stuff!}",
!   ' ', ARGOPT\^|\^ARGLIST, argStr, _\|_ &Files, "File {files to be read}",
X    ENDOFARGS
X  };
X  .ft R
--- 58,64 ----
X    ' ', ARGREQ,    argStr,  _\|_ &InFile,   "INPUTfile {input file}",
X    ' ', ARGOPT,    argStr,  _\|_ &OutFile,  "OUTPUTfile {output file}",
X    'X', ARGHIDDEN, argBool, _\|_ &XRated,   "XratedMODE {naughty stuff!}",
!   ' ', ARGLIST,   listStr, _\|_ &Files,    "File {files to be read}",
X    ENDOFARGS
X  };
X  .ft R
***************
*** 116,158 ****
X  .fi
X  .RE
X  .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 vp
X  (which will be \s-1NULL\s+1 if the \s-1ARGNOVAL\s+1 flag was set for the
X  corresponding entry in the arg-descriptor table).
! The
! .I copyf
! flag is TRUE if the
! .I vp
! 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 vp
! 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
X  .IR usrerr (3)
X  and return FALSE. This message should be of the form
X  \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).
X  The \fIargXxxx\fP function is responsible for detecting if the given argument
X  descriptor is an \s-1ARGVEC\s+1 argument and for taking the appropriate action.
X  .PP
--- 122,148 ----
X  .fi
X  .RE
X  .PP
! The \f4ad\fP 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 ad\(->ad_valp.
! The string value to be converted is passed in \f4vp\fP
X  (which will be \s-1NULL\s+1 if the \s-1ARGNOVAL\s+1 flag was set for the
X  corresponding entry in the arg-descriptor table).
! The \f4copyf\fP flag is TRUE if the \f4vp\fP 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 \f4vp\fP 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
X  .IR usrerr (3)
X  and return FALSE. This message should be of the form
X  \fB"invalid xxxx option 'yyyy' for Zzzz"\fP, where xxxx is the type of the
! option, yyyy is the string passed in \f4vp\fP, and zzzz is the name (taken
! from \f4ad\(->ad_prompt\fP).
X  The \fIargXxxx\fP function is responsible for detecting if the given argument
X  descriptor is an \s-1ARGVEC\s+1 argument and for taking the appropriate action.
X  .PP
***************
*** 204,215 ****
X  .\"------------------------------------------------------------------
X  .SH LONG OPTIONS
X  .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
X  whitespace characters.  Thus, if an entry looks like:
X  .RS
X  .sp 4p
--- 194,211 ----
X  .\"------------------------------------------------------------------
X  .SH LONG OPTIONS
X  .PP
! Under \s-1UNIX\s+1, \s-1MS-DOS\s+1, and \s-1OS\s+1/2,
! \fIparseargs\fP also allows for long
! options in addition to single character options.
! Under \s-1UNIX\s+1, long options are denoted by a `\fB+\fP' character.
! Under \s-1MS-DOS\s+1, and \s-1OS\s+1/2, long options are denoted by the second
! character in the \s-1SWITCHAR\s+1 environment variable. If there is no second
! character, then if the first character is `\-', then a `\fB+\fP' is used,
! otherwise a `\fB/\fP' is used.
! The keyword that is used is the first word in the prompt field of an
! argument descriptor entry. Long options are case insensitive!
! Under \s-1UNIX\s+1, an argument to a long option may be separated
! from the long option by an equal sign (`=') or by one or more
X  whitespace characters.  Thus, if an entry looks like:
X  .RS
X  .sp 4p
***************
*** 225,234 ****
X  .PP
X  The long option names for ``\fB\-?\fP'' in the default argument descriptor
X  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
X  all remaining arguments will be interpreted as positional parameters
X  (even if one begins with a `\fB+\fP' or a `\fB\-\fP').
X  .PP
X  Under VAX/VMS and AmigaDOS, single-character options are not used and the
X  ``long'' name (in the prompt field of an argument descriptor) is always used
X  to match for possible arguments (or keywords, or qualifiers).
--- 221,236 ----
X  .PP
X  The long option names for ``\fB\-?\fP'' in the default argument descriptor
X  are ``\fB+help\fP'' and ``\fB+?\fP'' (respectively). In addition, ``\fB++\fP''
! may be used to indicate the end of options so that
X  all remaining arguments will be interpreted as positional parameters
X  (even if one begins with a `\fB+\fP' or a `\fB\-\fP').
X  .PP
+ Under \s-1MS-DOS\s+1, and \s-1OS\s+1/2, an argument to a long-option must be
+ separated from the long option by an equal sign (`=') (unless the first
+ character of $SWITCHAR is a `\-', in which case \s-1UNIX\s+1 syntax is used).
+ The long option names for ``\fB/?\fP'' in the default argument descriptor
+ are ``\fB/help\fP'' and ``\fB/?\fP'' (respectively).
+ .PP
X  Under VAX/VMS and AmigaDOS, single-character options are not used and the
X  ``long'' name (in the prompt field of an argument descriptor) is always used
X  to match for possible arguments (or keywords, or qualifiers).
***************
*** 238,244 ****
X  match all characters in the prompt field (as in ``\fB+count=4\fP'' and
X  ``\fB+repcount=4\fP'').
X  .PP
! Under \s-1UNIX\s+1 and \s-1VAX/VMS\s+1,
X  only the number of characters required to uniquely identify the desired argument
X  are needed, but at least two characters must be given (unless the prompt field
X  is itself less than two characters long). This means that using the above
--- 240,246 ----
X  match all characters in the prompt field (as in ``\fB+count=4\fP'' and
X  ``\fB+repcount=4\fP'').
X  .PP
! Under all systems except AmigaDOS,
X  only the number of characters required to uniquely identify the desired argument
X  are needed, but at least two characters must be given (unless the prompt field
X  is itself less than two characters long). This means that using the above
***************
*** 255,264 ****
X  .\"------------------------------------------------------------------
X  .so returns.inc
X  .\"------------------------------------------------------------------
X  .SH SEE ALSO
X  .IR argtype (3),
X  .IR parseargs (1),
! .IR syserr (3)
X  .br
X  The ``C Advisor'' column in
X  .ul
--- 257,287 ----
X  .\"------------------------------------------------------------------
X  .so returns.inc
X  .\"------------------------------------------------------------------
+ .so effects.inc
+ .\"------------------------------------------------------------------
+ .SH "DOCUMENTING YOUR COMMANDS"
+ .PP
+ The commands that you write with \fIparseargs\fP(3) may be documented
+ using \fIparseargs\fP(1). Just copy the argument descriptor array
+ into a separate file, and invoke \fIparseargs\fP(1) with the \fB\-M\fP
+ option and pass it the command-name (dont forget to redirect input 
+ to come from your newly created file). It is important to note that the
+ only portion of that argdesc array to insert into your file is the portion
+ starting with the very first command-line argument, all the way down to
+ (and including) the \s-1ENDOFARGS\s+1 or \s-1END_ARGUMENTS\s+1 entry.
+ .\"------------------------------------------------------------------
+ .SH FILES
+ .IP "\fI/usr/local/lib/libparse.a\fP"
+ Link library for parseargs.
+ .IP "\fI/usr/local/include/parseargs.h\fP"
+ Include file for parseargs.
+ .IP "\fI/usr/local/include/useful.h\fP"
+ Include file for portability.
+ .\"------------------------------------------------------------------
X  .SH SEE ALSO
X  .IR argtype (3),
X  .IR parseargs (1),
! .IR parsecntl (3)
X  .br
X  The ``C Advisor'' column in
X  .ul
diff -cNr ../patchlevel4/doc/parseargs1.inc ./doc/parseargs1.inc
*** ../patchlevel4/doc/parseargs1.inc	Thu May  2 11:01:54 1991
--- ./doc/parseargs1.inc	Thu May  2 14:35:28 1991
***************
*** 28,32 ****
X  Given the command name and the argument specification string,
X  .B parseargs \-M
X  prints a template of the command-syntax on standard output that is
! suitable for input to \fInroff\fP or \fItroff\fP using the \-man 
X  macro package.
--- 28,37 ----
X  Given the command name and the argument specification string,
X  .B parseargs \-M
X  prints a template of the command-syntax on standard output that is
! suitable for input to \fInroff\fP or \fItroff\fP using the \fI\-man\fP
X  macro package.
+ .PP
+ Given no other arguments
+ \fBparseargs \-#\fP prints on standard output, the current version and
+ patchlevel of the running version of \fBparseargs\fP.
+ 
diff -cNr ../patchlevel4/doc/parsecntl.man3 ./doc/parsecntl.man3
*** ../patchlevel4/doc/parsecntl.man3	Thu May  2 10:56:24 1991
--- ./doc/parsecntl.man3	Thu May  2 14:35:33 1991
***************
*** 8,14 ****
X  #include <parseargs.h>
X  .PP
X  .nf
! int  parsecntl( ARGDESC argd[\|],  parsecntl_t func,  parsemode_t mode,  ... )
X  .fi
X  
X  .\"-----------------------------------
--- 8,14 ----
X  #include <parseargs.h>
X  .PP
X  .nf
! int  parsecntl( ARGDESC argd[\|],  parsecntl_t func,  parsemode_t mode,  ... );
X  .fi
X  
X  .\"-----------------------------------
***************
*** 24,35 ****
X  .\"-----------------------------------
X  .so returns.inc
X  .\"-----------------------------------
X  .SH SEE ALSO
- .nf
X  .IR argtype (3),
X  .IR parseargs (3),
X  .IR parseargs (1)
- .fi
X  .\"-----------------------------------
X  .SH AUTHOR
X  .PP
--- 24,35 ----
X  .\"-----------------------------------
X  .so returns.inc
X  .\"-----------------------------------
+ .so effects.inc
+ .\"-----------------------------------
X  .SH SEE ALSO
X  .IR argtype (3),
X  .IR parseargs (3),
X  .IR parseargs (1)
X  .\"-----------------------------------
X  .SH AUTHOR
X  .PP
diff -cNr ../patchlevel4/doc/parsecntl3.inc ./doc/parsecntl3.inc
*** ../patchlevel4/doc/parsecntl3.inc	Thu May  2 10:56:24 1991
--- ./doc/parsecntl3.inc	Thu May  2 14:35:36 1991
***************
*** 28,35 ****
X  then the desired attributes are copied into
X  the object pointed to by the last parameter. If the mode is
X  .I pc_\s-1WRITE\s+1,
! then the attributes from the last parameter are copied to the command-
! object. If mode is
X  .I pc_\s-1RDWR\s+1,
X  then the attributes pointed to by the last
X  parameter are copied to the command-object, and then the previous value
--- 28,35 ----
X  then the desired attributes are copied into
X  the object pointed to by the last parameter. If the mode is
X  .I pc_\s-1WRITE\s+1,
! then the attributes from the last parameter are copied to the
! command-object. If mode is
X  .I pc_\s-1RDWR\s+1,
X  then the attributes pointed to by the last
X  parameter are copied to the command-object, and then the previous value
diff -cNr ../patchlevel4/doc/parsecntls.inc ./doc/parsecntls.inc
*** ../patchlevel4/doc/parsecntls.inc	Thu May  2 10:56:25 1991
--- ./doc/parsecntls.inc	Thu May  2 14:35:38 1991
***************
*** 108,119 ****
X  .ft R
X  .fi
X  
! Note that in the above call to
! .IR parsecntl(3),
! that zero will be
X  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).
X  .\"---------------------------------------------
X  .IP "\fIpc_\s-1NAME\s+1\fP"
X  .IP "\fIpc_\s-1PURPOSE\s+1\fP"
--- 108,117 ----
X  .ft R
X  .fi
X  
! Note that in the above call to \fIparsecntl\fP\^(3), that zero will be
X  returned upon success and non-zero upon failure. If pe_DEFARGS is
! returned, then \f4cmd\fP is already on \f4common_args\fP's list of defaults
! (and would result in an infinite loop while parsing).
X  .\"---------------------------------------------
X  .IP "\fIpc_\s-1NAME\s+1\fP"
X  .IP "\fIpc_\s-1PURPOSE\s+1\fP"
diff -cNr ../patchlevel4/doc/parseflags.inc ./doc/parseflags.inc
*** ../patchlevel4/doc/parseflags.inc	Thu May  2 10:56:25 1991
--- ./doc/parseflags.inc	Thu May  2 14:35:40 1991
***************
*** 5,11 ****
X  .SH "PARSE FLAGS"
X  .PP
X  The following bitmasks may be combined in order to modify the
! behavior of the parseargs library. The parse flags for a given
X  may be set through the use of the \fIparsecntl\fP(3) function.
X  .\"---------------------------------------------
X  .IP "\fIpa_\s-1PROMPT\s+1\fP"
--- 5,11 ----
X  .SH "PARSE FLAGS"
X  .PP
X  The following bitmasks may be combined in order to modify the
! behavior of the \fIparseargs\fP library. The parse flags for a given
X  may be set through the use of the \fIparsecntl\fP(3) function.
X  .\"---------------------------------------------
X  .IP "\fIpa_\s-1PROMPT\s+1\fP"
***************
*** 17,24 ****
X  .\"---------------------------------------------
X  .IP "\fIpa_\s-1IGNORE\s+1\fP"
X  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
X  program execution is terminated.
X  .\"---------------------------------------------
X  .IP "\fIpa_\s-1OPTSONLY\s+1\fP"
--- 17,24 ----
X  .\"---------------------------------------------
X  .IP "\fIpa_\s-1IGNORE\s+1\fP"
X  Ignore any unrecognized or improperly specified command-line arguments
! and continue execution of the program. Normally, if a required argument is
! unmatched (or an argument is improperly specified), a usage message is printed
X  program execution is terminated.
X  .\"---------------------------------------------
X  .IP "\fIpa_\s-1OPTSONLY\s+1\fP"
***************
*** 28,34 ****
X  .\"---------------------------------------------
X  .IP "\fIpa_\s-1KWDSONLY\s+1\fP"
X  Under \s-1UNIX\s+1, setting this flag disables the parsing of single-character
! options.  This will cause all arguments starting with `-' to always
X  be treated as a positional parameter (instead of an option).
X  .\"---------------------------------------------
X  .IP "\fIpa_\s-1FLAGS1ST\s+1\fP"
--- 28,34 ----
X  .\"---------------------------------------------
X  .IP "\fIpa_\s-1KWDSONLY\s+1\fP"
X  Under \s-1UNIX\s+1, setting this flag disables the parsing of single-character
! options.  This will cause all arguments starting with `\-' to always
X  be treated as a positional parameter (instead of an option).
X  .\"---------------------------------------------
X  .IP "\fIpa_\s-1FLAGS1ST\s+1\fP"
***************
*** 47,70 ****
X  .IP "\fIpa_\s-1ANYCASE\s+1\fP"
X  Setting this flag will cause character-case to be ignored when attempting
X  to match single-character argument names (i.e. causes "\fB\-i\fP" and
! "\fB\-I\fP" will be considered equivalent).
X  .\"---------------------------------------------
X  .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
X  argument on the command-line is a bona-fide argument to the command.
X  .\"---------------------------------------------
X  .IP "\fIpa_\s-1NOCHECK\s+1\fP"
! Setting this flag will prevent parseargs from checking for any 
X  required arguments that were not given on the command-line. This
! is useful when more than one call to the parseargs library is needed
X  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  
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).
X  .\"---------------------------------------------
X  .IP "\fIpa_\s-1CONTINUE\s+1\fP"
X  Setting this flag will cause subsequent calls to the parseargs library
--- 47,73 ----
X  .IP "\fIpa_\s-1ANYCASE\s+1\fP"
X  Setting this flag will cause character-case to be ignored when attempting
X  to match single-character argument names (i.e. causes "\fB\-i\fP" and
! "\fB\-I\fP" to be considered equivalent).
X  .\"---------------------------------------------
X  .IP "\fIpa_\s-1ARGV0\s+1\fP"
! Normally, the \fIparseargs\fP library will assume that the first argument
! on the command-line is the name of the command. Setting this flag tells
! \fIparseargs\fP that this is \s-1NOT\s+1 the case and that the very first
X  argument on the command-line is a bona-fide argument to the command.
X  .\"---------------------------------------------
X  .IP "\fIpa_\s-1NOCHECK\s+1\fP"
! Setting this flag will prevent \fIparseargs\fP from checking for any 
X  required arguments that were not given on the command-line. This
! is useful when more than one call to the \fIparseargs\fP library is needed
X  to parse all the command-line arguments (which could occur if the
! command-line argument came from a file or from two \f4argv\fP-vectors).
! When this flag is set, then each call to parseargs will check for missing
! required arguments (and will prompt the user for them if desired).
X  
X  Keeping this flag on until the final set of arguments is parsed will
! cause \fIparseargs\fP to not check for missing arguments until the last set
! of arguments has been parsed (by the final call to one of the functions 
! in the \fIparseargs\fP library).
X  .\"---------------------------------------------
X  .IP "\fIpa_\s-1CONTINUE\s+1\fP"
X  Setting this flag will cause subsequent calls to the parseargs library
diff -cNr ../patchlevel4/doc/parsemodes.inc ./doc/parsemodes.inc
*** ../patchlevel4/doc/parsemodes.inc	Thu May  2 10:56:26 1991
--- ./doc/parsemodes.inc	Thu May  2 14:35:43 1991
***************
*** 6,12 ****
X  .PP
X  \fIParsecntl\fP may be used to read current command attributes, write
X  (assign) new command attributes, or both. The mode argument to
! parsecntl determines the which of these three alternatives are
X  desired. If the programmer merely wishes to assign new attributes,
X  then invoking \fIparsecntl\fP in \fIpc_\s-1WRITE\s+1\fP mode and passing
X  the new attributes will do the job. If the programmer wishes simply to query
--- 6,12 ----
X  .PP
X  \fIParsecntl\fP may be used to read current command attributes, write
X  (assign) new command attributes, or both. The mode argument to
! parsecntl determines which of these three alternatives are
X  desired. If the programmer merely wishes to assign new attributes,
X  then invoking \fIparsecntl\fP in \fIpc_\s-1WRITE\s+1\fP mode and passing
X  the new attributes will do the job. If the programmer wishes simply to query
***************
*** 21,24 ****
X  When \fIparsecntl\fP returns, then (assuming it returns 0) the desired
X  attributes will have been assigned and the object that contained the
X  new attribute settings will now contain the attribute settings that
! were in effect before \fIparsecntl\fP was invoked.
--- 21,24 ----
X  When \fIparsecntl\fP returns, then (assuming it returns 0) the desired
X  attributes will have been assigned and the object that contained the
X  new attribute settings will now contain the attribute settings that
! were in effect immediately before \fIparsecntl\fP was invoked.
diff -cNr ../patchlevel4/doc/sh_arrays.inc ./doc/sh_arrays.inc
*** ../patchlevel4/doc/sh_arrays.inc	Thu May  2 11:01:59 1991
--- ./doc/sh_arrays.inc	Thu May  2 14:35:48 1991
***************
*** 9,15 ****
X  setting up an argument list depends largely upon the syntax of shell
X  that was specified on the command line via the \fB\-s\fP option
X  (although \s-1ARGLIST\s+1 arguments are treated exactly the same as
! \s-1ARGVEC\s+1 arguments).
X  .\"---------------
X  .SS "Resetting the Positional Parameters to an Argument List"
X  .PP
--- 9,18 ----
X  setting up an argument list depends largely upon the syntax of shell
X  that was specified on the command line via the \fB\-s\fP option
X  (although \s-1ARGLIST\s+1 arguments are treated exactly the same as
! \s-1ARGVEC\s+1 arguments). With the exception of \fIperl\fP which always
! uses a comma to separate array elements, all shells will use the string
! specified with the \fB\-S\fP option as the field separator between elements
! of an array (the default field separator is a space character).
X  .\"---------------
X  .SS "Resetting the Positional Parameters to an Argument List"
X  .PP
***************
*** 23,29 ****
X  (this way, the positional parameters will be unset if the associated list
X  of command line arguments is not encountered).
X  .PP
! Similarly for the C and TC shells,
X  if the variable name corresponding to the \s-1ARGLIST\s+1 argument is
X  ``\fBargv\fP'', then the positional parameters of the calling program
X  will be re-assigned to the contents of the argument list.
--- 26,32 ----
X  (this way, the positional parameters will be unset if the associated list
X  of command line arguments is not encountered).
X  .PP
! Similarly for the C & Z shells (\fIzsh, csh, tcsh, itcsh\fP),
X  if the variable name corresponding to the \s-1ARGLIST\s+1 argument is
X  ``\fBargv\fP'', then the positional parameters of the calling program
X  will be re-assigned to the contents of the argument list.
***************
*** 109,117 ****
X  .RS
X  \f4set  \-A  save_parms  "$@"\fP
X  .RE
! .SS "C and TC Shell Argument Lists"
X  .PP
! For the C and TC shells, \s-1ARGLIST\s+1 variables are treated as word-lists
X  and are assigned using the following syntax:
X  .sp 2p
X  .RS
--- 112,121 ----
X  .RS
X  \f4set  \-A  save_parms  "$@"\fP
X  .RE
! .SS "C Shell Argument Lists"
X  .PP
! For the C shells (\fIcsh, tcsh, itcsh\fP),
! \s-1ARGLIST\s+1 variables are treated as word-lists
X  and are assigned using the following syntax:
X  .sp 2p
X  .RS
***************
*** 120,126 ****
X  .sp 2p
X  The first item will be in \f4$name[1]\fP, the second item will be in
X  \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
X  word-lists start at index one.
X  .SS "Bourne-Again Shell Argument Lists"
X  .PP
--- 124,130 ----
X  .sp 2p
X  The first item will be in \f4$name[1]\fP, the second item will be in
X  \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 shell
X  word-lists start at index one.
X  .SS "Bourne-Again Shell Argument Lists"
X  .PP
***************
*** 130,136 ****
X  .SS "Plan 9 Shell Argument Lists"
X  .PP
X  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:
X  .nf
X  .RS
X  .ft 4
--- 134,140 ----
X  .SS "Plan 9 Shell Argument Lists"
X  .PP
X  For the Plan 9 shell, if the associated variable name is not ``*'' then
! it is considered to be a word-list and set using the following syntax:
X  .nf
X  .RS
X  .ft 4
***************
*** 138,145 ****
X  .ft R
X  .RE
X  .fi
X  .SS "Awk Argument Lists"
! For \fIawk\fP, if the \fB\-A\fP option is not given, then the output for thes
X  variable-list will be a line with the variable name, followed by a line with
X  each of the values (each value will be separated with the field separator
X  specified using the \fB\-S\fP option - which defaults to a space). 
--- 142,162 ----
X  .ft R
X  .RE
X  .fi
+ .SS "Z Shell Argument Lists"
+ .PP
+ For the Z shell, \s-1ARGLIST\s+1 variables are treated as word-lists
+ and are assigned using the following syntax:
+ .sp 2p
+ .RS
+ \f4name = ( '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 Z and C shell
+ word-lists start at index one.
X  .SS "Awk Argument Lists"
! For \fIawk\fP, if the \fB\-A\fP option is not given, then the output for the
X  variable-list will be a line with the variable name, followed by a line with
X  each of the values (each value will be separated with the field separator
X  specified using the \fB\-S\fP option - which defaults to a space). 
***************
*** 154,160 ****
X  If the \fB\-A\fP option is given, then the associated variable is considered
X  the root name of an array. The ouput for the array
X  will consist of two lines for each item in the list (as in the following
! expample):
X  .nf
X  .RS
X  .ft 4
--- 171,177 ----
X  If the \fB\-A\fP option is given, then the associated variable is considered
X  the root name of an array. The ouput for the array
X  will consist of two lines for each item in the list (as in the following
! example):
X  .nf
X  .RS
X  .ft 4
***************
*** 178,191 ****
X  .nf
X  .RS
X  .ft 4
! @name=( arg1 , arg2 ,  ... );
X  .ft R
X  .RE
X  .fi
X  .SS "A Final Note on Argument Lists"
X  .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
X  all shells (if overwritten by \fBparseargs\fP) will preserve any \s-1IFS\s+1
X  characters in their contents.  That is to say that if an item in one of the
X  aforementioned multi-word lists contains any \s-1IFS\s+1 characters, it will
--- 195,208 ----
X  .nf
X  .RS
X  .ft 4
! @name=( 'arg1' , 'arg2' ,  ... );
X  .ft R
X  .RE
X  .fi
X  .SS "A Final Note on Argument Lists"
X  .PP
! The word-lists used by the C and Z shells, the arrays used by the Korn shell,
! the Plan 9 shell, \fIawk\fP, \fIperl\fP, and the positional parameters used by
X  all shells (if overwritten by \fBparseargs\fP) will preserve any \s-1IFS\s+1
X  characters in their contents.  That is to say that if an item in one of the
X  aforementioned multi-word lists contains any \s-1IFS\s+1 characters, it will
diff -cNr ../patchlevel4/doc/shells.inc ./doc/shells.inc
*** ../patchlevel4/doc/shells.inc	Thu May  2 11:02:07 1991
--- ./doc/shells.inc	Thu May  2 14:35:51 1991
***************
*** 15,23 ****
X  (not be evaluated by the shell) in the corresponding shell variable.
X  .PP
X  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 
X  that of the other shells in that the actual variable settings are not
X  printed but each line of an associative array is printed (the first field
X  is the array index, the second is the value for that index).
--- 15,40 ----
X  (not be evaluated by the shell) in the corresponding shell variable.
X  .PP
X  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 the following
! shells as valid command-interpreters:
! 
! .RS
! .nf
! sh
! bash
! ksh
! csh
! tcsh
! itcsh
! zsh
! rc
! awk
! perl
! .fi
! .RE
! 
! .PP
! \fIAwk\fP output is slightly different from 
X  that of the other shells in that the actual variable settings are not
X  printed but each line of an associative array is printed (the first field
X  is the array index, the second is the value for that index).
diff -cNr ../patchlevel4/doc/sparseargs3.inc ./doc/sparseargs3.inc
*** ../patchlevel4/doc/sparseargs3.inc	Thu May  2 10:56:29 1991
--- ./doc/sparseargs3.inc	Thu May  2 14:35:53 1991
***************
*** 4,15 ****
X  .\"----------------------------------------------------------------------------
X  .PP
X  Given a single string and an argdesc array, \fIsparseargs\fP
! will parse arguments from a string in much the same manner as \fIparseargs\fP.
X  .I Sparseargs
X  will split the given string up into a vector of whitespace
X  separated tokens and then attempt to parse the resultant vector as
! if it were given as \fIargv[]\fP on the command-line.
X  NO special treatment is given to characters such as single-quotes,
X  double-quotes, or anything else. \fISparseargs\fP will always assume that
X  any whitespace characters are intended as argument separators.
- 
--- 4,14 ----
X  .\"----------------------------------------------------------------------------
X  .PP
X  Given a single string and an argdesc array, \fIsparseargs\fP
! will parse arguments from a string in much the manner as \fIparseargs\fP.
X  .I Sparseargs
X  will split the given string up into a vector of whitespace
X  separated tokens and then attempt to parse the resultant vector as
! if it were given as \f4argv[]\fP on the command-line.
X  NO special treatment is given to characters such as single-quotes,
X  double-quotes, or anything else. \fISparseargs\fP will always assume that
X  any whitespace characters are intended as argument separators.
diff -cNr ../patchlevel4/doc/vparseargs3.inc ./doc/vparseargs3.inc
*** ../patchlevel4/doc/vparseargs3.inc	Thu May  2 10:56:30 1991
--- ./doc/vparseargs3.inc	Thu May  2 14:35:58 1991
***************
*** 6,12 ****
X  .I Vparseargs
X  takes an argdesc array, the number of arguments to parse, and a
X  (possibly NULL terminated) list of argument-strings
! and parses them in much the same manner as \fIparseargs\fP.
X  Unlike
X  .I sparseargs,
X  .I vparseargs
--- 6,12 ----
X  .I Vparseargs
X  takes an argdesc array, the number of arguments to parse, and a
X  (possibly NULL terminated) list of argument-strings
! and parses them in the same manner as \fIparseargs\fP.
X  Unlike
X  .I sparseargs,
X  .I vparseargs
***************
*** 13,16 ****
X  assumes that all parameters are already split up into tokens, hence any
X  whitespace characters contained in any of the string-parameters are used as
X  is (and will be considered a part of an argument name or value).
- 
--- 13,15 ----
diff -cNr ../patchlevel4/ibm_args.c ./ibm_args.c
*** ../patchlevel4/ibm_args.c	Thu May  2 11:06:08 1991
--- ./ibm_args.c	Thu May  2 14:36:02 1991
***************
*** 208,213 ****
--- 208,214 ----
X     get_prefixes();
X  
X     while ( av  &&  (p = *av++) ) {
+       /* is this a keyword */
X        if ( isKWD(p) &&
X            ( (OptPrefix != KwdPrefix) || *(p+2) && !strchr(s_ARG_SEP, *(p+2)) )
X           ) {
***************
*** 251,256 ****
--- 252,262 ----
X              continue;
X           }
X  
+          /* reset the argument flags - if this arg was already given, some
+          ** of its flags may be set to indicate how it was given before.
+          ** we need to know how it was given now (but save the old ones
+          ** just in case the new one fails).
+          */
X           flags = arg_flags(ad);
X           if ( ARG_isGIVEN(ad) ) {
X              BCLEAR( arg_flags(ad), ARGVALSEP | ARGKEYWORD );
***************
*** 260,266 ****
X           BSET( arg_flags(ad), ARGKEYWORD );
X  
X           if( ARG_isMULTIVAL(ad) ) {
!             cmd_list(cmd) = ad;
X           }
X           else {
X              cmd_list(cmd) = ARGDESCNULL;
--- 266,272 ----
X           BSET( arg_flags(ad), ARGKEYWORD );
X  
X           if( ARG_isMULTIVAL(ad) ) {
!             cmd_list(cmd) = ad;  /* we matched a lst or a vector */
X           }
X           else {
X              cmd_list(cmd) = ARGDESCNULL;
***************
*** 330,337 ****
X              continue;
X           }
X  
!             /* flag argument */
!          while (*p) {
X  
X                 /* find the flag in the list */
X              is_match = FALSE;
--- 336,348 ----
X              continue;
X           }
X  
!          /* We have a flag argument;
!          ** remember that in the case of single character keywords,
!          ** the conversion function (ad_type) tells us how many characters
!          ** were used. We need that information to decide how many 
!          ** characters to skip before the next iteration of the while loop.
!          */
!          while (*p) {  /* while not end of switch-chars */
X  
X                 /* find the flag in the list */
X              is_match = FALSE;
***************
*** 363,368 ****
--- 374,384 ----
X                    continue;
X              }/* if unknown-option */
X  
+             /* reset the argument flags - if this arg was already given, some
+             ** of its flags may be set to indicate how it was given before.
+             ** we need to know how it was given now (but save the old ones
+             ** just in case the new one fails).
+             */
X              flags = arg_flags(ad);
X              if ( ARG_isGIVEN(ad) ) {
X                 BCLEAR( arg_flags(ad), ARGVALSEP | ARGKEYWORD );
***************
*** 370,376 ****
X              }
X  
X              if ( ARG_isMULTIVAL(ad) ) {
!                cmd_list(cmd) = ad;
X              }
X              else {
X                 cmd_list(cmd) = ARGDESCNULL;
--- 386,392 ----
X              }
X  
X              if ( ARG_isMULTIVAL(ad) ) {
!                cmd_list(cmd) = ad;  /* we matched a list (or a vector) */
X              }
X              else {
X                 cmd_list(cmd) = ARGDESCNULL;
***************
*** 448,456 ****
X        }/*elif option*/
X        else {
X              /* parsing a list of arguments */
!          if ( cmd_list(cmd) ) {
X              ad = cmd_list(cmd);
!             flags = arg_flags(ad);
X              if ( ARG_isGIVEN(ad) ) {
X                 BCLEAR( arg_flags(ad), ARGVALSEP | ARGKEYWORD );
X              }
--- 464,472 ----
X        }/*elif option*/
X        else {
X              /* parsing a list of arguments */
!          if ( cmd_list(cmd) ) {  /* we're in the middle of a list/vector */
X              ad = cmd_list(cmd);
!             flags = arg_flags(ad);  /* reset flags for this argv-item */
X              if ( ARG_isGIVEN(ad) ) {
X                 BCLEAR( arg_flags(ad), ARGVALSEP | ARGKEYWORD );
X              }
***************
*** 495,500 ****
--- 511,517 ----
X              cmd_list(cmd) = ad;
X           }
X  
+          /* if FLAGS1ST is set then first positional marks end-of-flags */
X           if ( BTEST(cmd_flags(cmd), pa_FLAGS1ST) ) {
X              BSET( cmd_state(cmd), ps_NOFLAGS );
X           }
diff -cNr ../patchlevel4/parseargs.c ./parseargs.c
*** ../patchlevel4/parseargs.c	Thu May  2 11:06:09 1991
--- ./parseargs.c	Thu May  2 14:36:12 1991
***************
*** 1,13 ****
X  /*************************************************************************
X  ** ^FILE: parseargs.c - command line interface to parseargs()
X  **
- ** ^DESCRIPTION:
X  **    This file implements the command-line interface to the parseargs
X  **    library. Under Unix, the user may use parseargs(1) (this program)
X  **    to parse command-line arguments for shell scripts.  At the present,
X  **    time, VMS/DCL is not yet supported (nor are MS-DOS Batch-files).
X  **
! **
X  **    Given a command name, a vector of string-valued arguments such as that
X  **    passed to a shell script, and a specification string describing the
X  **    possible arguments, parseargs matches actual arguments to possible
--- 1,12 ----
X  /*************************************************************************
X  ** ^FILE: parseargs.c - command line interface to parseargs()
X  **
X  **    This file implements the command-line interface to the parseargs
X  **    library. Under Unix, the user may use parseargs(1) (this program)
X  **    to parse command-line arguments for shell scripts.  At the present,
X  **    time, VMS/DCL is not yet supported (nor are MS-DOS Batch-files).
X  **
! ** ^DESCRIPTION:
X  **    Given a command name, a vector of string-valued arguments such as that
X  **    passed to a shell script, and a specification string describing the
X  **    possible arguments, parseargs matches actual arguments to possible
***************
*** 158,176 ****
X  
X  /**************************************************************************
X  ** ^SECTION: SHELLS
! **    After the command line has been parsed, parseargs will print on stan-
! **    dard 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,
X  **    or by directly evaluating the output from parseargs (under most UNIX
! **    shells, this could be done using eval).  If any arguments on the com-
! **    mand 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.
X  **
X  **    The -s shell option may be used to tell parseargs which shell syntax
! **    to use. At present, parseargs only recognizes "sh", "csh", "ksh",
! **    "tcsh", "bash", "rc", "awk", and "perl" as valid command interpreters.
X  **    Awk output is slightly different from that of the other shells in that
X  **    the actual variable settings are not printed but each line of an
X  **    associative array is printed (the first field is the array index, the
--- 157,187 ----
X  
X  /**************************************************************************
X  ** ^SECTION: SHELLS
! **    After the command line has been parsed, parseargs 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,
X  **    or by directly evaluating the output from parseargs (under most UNIX
! **    shells, this could be done using eval).  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.
X  **
X  **    The -s shell option may be used to tell parseargs which shell syntax
! **    to use. At present, parseargs only recognizes the following shells as
! **    valid command-interpreters:
! **
! **         sh
! **         bash
! **         ksh
! **         csh
! **         tcsh
! **         itcsh
! **         zsh
! **         rc
! **         awk
! **         perl
! **
X  **    Awk output is slightly different from that of the other shells in that
X  **    the actual variable settings are not printed but each line of an
X  **    associative array is printed (the first field is the array index, the
***************
*** 178,254 ****
X  **    the Bourne shell ("sh") will be assumed.
X  **
X  **    If the user wishes to use a value other than "TRUE" for a boolean
! **    flag that is true, this may be done using the "-T string" option.
! **    The same may also be done for a boolean flag that is false using the
! **    "-F string" option.
X  **
X  **    Parseargs will only set the values of variables that correspond to
! **    arguments that were given on the command line. If a particular argu-
! **    ment 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 parseargs was invoked. The only exception to this
! **    is that if the -u option is specified, then the positional parameters
! **    are unset before any shell variable assignments (which may reset the
! **    positional parameters) are made.
X  ***^^*********************************************************************/
X  
!       /* #defines for possible shell names and corresponding types */
! typedef short  shell_t;
! #define  BASH  ((shell_t) 0)
! #define  TCSH  ((shell_t) 1)
! #define  CSH   ((shell_t) 2)
! #define  KSH   ((shell_t) 3)
! #define  SH    ((shell_t) 4)
! #define  RC    ((shell_t) 5)
! #define  AWK   ((shell_t) 6)
! #define  PERL  ((shell_t) 7)
! 
! #define  BOURNE_AGAIN_SHELL  "bash"
! #define  BOURNE_SHELL        "sh"
! #define  KORN_SHELL          "ksh"
! #define  C_SHELL             "csh"
! #define  RC_SHELL            "rc"
! #define  TC_SHELL            "tcsh"
! #define  AWK_LANG            "awk"
! #define  PERL_LANG           "perl"
X  
X     /* structure for shell-specific info */
X  typedef struct {
!    char  *varname;   /* name of variable containing the positional parameters */
!    char  *setcmd;    /* formatted string (%s is replaced with variable name) */
!    char  *prefix;    /* beginning for variable setting */
!    char  *suffix;    /* ending for variable setting */
X     char  *escape;    /* format to escape chars (%c is the char to escape) */
X     char  *metachars; /* special characters that need to be escaped */
X  } shell_info;
X  
!    /* array of shell info - indexed by the #define for the shell type */
X  static CONST shell_info  Shell[] = {
X  
!    /* BASH : Positional parms in -- ; Assignment Syntax: name="value"; */
!    { "--", "%s=",   "'",   "';\n",   "'\\%c'",   "'" },
X  
-    /* TCSH : Positional parms in argv ; Assignment Syntax: set name="value"; */
-    { "argv", "set %s=", "'",   "';\n",  "'\\%c'",   "'" },
- 
-    /* CSH : Positional parms in argv ; Assignment Syntax: set name="value"; */
SHAR_EOF
true || echo 'restore of PATCH05 failed'
fi
echo 'End of  part 2'
echo 'File PATCH05 is continued in part 3'
echo 3 > _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.