v17i052: parseargs - functions to parse command line arguments, Part07/12

Brad Appleton brad at hcx1.ssd.csd.harris.com
Tue Mar 19 01:56:20 AEST 1991


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

This is part 7 of parseargs

#!/bin/sh
# this is Part.07 (part 7 of a multipart archive)
# do not concatenate these parts, unpack them in order with /bin/sh
# file parseargs/parseargs.h continued
#
if test ! -r _shar_seq_.tmp; then
	echo 'Please unpack part 1 first!'
	exit 1
fi
(read Scheck
 if test "$Scheck" != 7; 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/parseargs.h'
else
echo 'x - continuing file parseargs/parseargs.h'
sed 's/^X//' << 'SHAR_EOF' >> 'parseargs/parseargs.h' &&
**    port vectors). An arg-vector is a structure which contains a count, an
**    array of elements (i.e. an argc/argv pair), and an array of flags, one
**    for each element of argv. There are two macros in defined in
**    <parseargs.h> which are used for arg-vectors. ARGVEC_T may be used to
**    declare a vector structure or a vector type; ARGVEC_EMPTY may be used
**    to initialize the structure.  It is strongly recommended that ARGVEC_T
**    be used to declare vector types in a typedef statement (particularly
**    if one is using function prototypes) but for those who insist, it may
**    be used to directly declare a  structure.  String-vectors will always
**    have an extra NULL-pointer at the end such that:
**
**         ( StrVec.array[ StrVec.count ] == (char *)NULL )
**
**    is always true, and character-vectors will always have an extra NUL-
**    character at the end such that:
**
**         ( CharVec.array[ CharVec.count ] == '\0' )
**
**    is always true. Integer and floating point vectors contain no extra
**    "null" elements.
**
**    Once created, arg-vectors may be deallocated by calling the macro vec-
**    Free or the macro vecDeepFree and passing it the arg-vector structure.
**    The differemce between these two macros is that the latter will also
**    free each item in the vector that required space to be allocated (at
**    the expense of traversing the vector).  At this writing, the only
**    predefined argument-type(s) that would benefit from vecDeepFree is
**    argStr vectors.
**
**    An example use of arg-lists, and of arg-vectors follows:
**
**         #include <parseargs.h>
**
**         typedef ARGVEC_T(char *) strvec_t;
**
**         static ArgList  *StringList = ARGLISTNULL;
**         static strvec_t  StringVec = ARGVEC_EMPTY(char *);
**         static ARGVEC_T(int)  NumberVec = ARGVEC_EMPTY(int);
**
**         static
**          CMD_OBJECT  Args
**          CMD_NAME    "foo -- do whatever foo does"
**          CMD_DESCRIPTION  "put a brief paragraph here"
**          CMD_ARGUMENTS
**            'l', ARGLIST, listStr, __ &StrList, "LiSt {list of strings}",
**            's', ARGVEC,  argStr,  __ &StrVec,  "STRing {vector of strings}",
**            'i', ARGVEC,  argInt,  __ &NumVec,  "NUMber {vector of numbers}",
**            END_ARGUMENTS
**          CMD_END
**
**         main( int argc, char *argv[] )
**         {
**            int i, *ls;
**
**            if ( parseargs(argv, Args) )  syserr( "parseargs failed" );
**
**            for ( ls = StrList, i=1 ; ls ; ls = L_NEXT(ls), i++ )
**               printf( "List item %d=%s, flags=%x0\n",
**                       i, L_STRING(ls), L_FLAGS(ls) );
**
**            for ( i = 0 ; i < StrVec.count ; i++ )
**               printf( "String[%d]=%s, flags=%x0\n",
**                       i, StrVec.array[i], StrVec.flags[i] );
**
**            for ( i = 0 ; i < NumVec.count ; i++ )
**               printf( "Number[%d]=%s, flags=%x0\n",
**                       i, NumVec.array[i], NumVec.flags[i] );
**
**            listFree( StrList );
**            StrList = ARGLISTNULL;
**
**            vecDeepFree( StrVec, char * );
**            vecFree( NumVec, int );
**
**            exit( 0 );
**         }
**
**^^***********************************************************************/
X
X   /* definition of an arg-list */
typedef struct arglist {
X   struct arglist  *nl_next;  /* pointer to next item */
X   ARBPTR           nl_val;   /* value of current item */
X   argMask_t        nl_flags; /* flags for current item */
} ArgList;
#define ARGLISTNULL  (ArgList *)NULL
X
X   /* definition of an arg-list-head (the first two fields MUST exactly
X   ** overlay with their corresponding elements in an ArgList struct)
X   */
typedef struct arglisthead {
X   ArgList  *nl_next;  /* pointer to next item */
X   ARBPTR    nl_val;   /* value of current item */
X   argMask_t nl_flags; /* flags for current item */
X   ArgList  *nl_tail;  /* pointer to last item */
} ArgListHead;
#define ARGLISTHEADNULL  (ArgListHead *)NULL
X
X   /*
X   ** macros to manipulate arg-lists
X   */
#define L_STRING(ls)   ((char *)((ls)->nl_val))  /* Item as a string */
#define L_NEXT(ls)     ((ls)->nl_next)           /* Next item of list */
#define L_ADVANCE(ls)  (ls) = (ArgList *)L_NEXT(ls) /* Advance list ptr */
#define L_FLAGS(ls)    ((ls)->nl_flags)          /* flags of current item */
X
X   /*
X   ** macros to declare and initialize arg-vectors
X   **   (NOTE: this wont work for vectors of function pointers)
X   */
#define ARGVEC_T(type) \
X	struct { type  *array; unsigned short  count; argMask_t *flags; }
#define ARGVEC_EMPTY(type) \
X	{ (type *) NULL, (unsigned short) 0, (argMask_t *) NULL }
X
X
/**********************************************************************
** ^SECTION: PARSE-FLAGS
**    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 parsecntl() function.
*/
#define pa_PROMPT    0x0001
/*    -- 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.
*/
#define pa_IGNORE    0x0002
/*    -- 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.
*/
#define pa_OPTSONLY  0x0004
/*    -- Under UNIX, setting this flag will disable the parsing of long-option
**       syntax. This will cause all arguments starting with '+' to always be
**       treated as a positional parameter (instead of a long-option).
*/
#define pa_KWDSONLY  0x0008
/*    -- Under UNIX, setting this flag disables the parsing of single-character
**       options.  This will cause all arguments starting with '-' to always
**       be treated as a positional parameter (instead of an option).
*/
#define pa_FLAGS1ST  0x0010
/*    -- Setting this flag causes the parseargs library to force any and all
**       non-positional arguments to be specified before any positional ones.
**       As an example, under UNIX, if this flag is SET then parseargs will
**       consider the command line "cmd -x arg" to consist of one option and
**       one positional argument; however the command line "cmd arg -x" would
**       be considered to consist of two positional arguments (the -x option
**       will be unmatched).
**
**       If this flag is UNSET, then both of the previous examples are
**       considered to consist of one option and one positional argument.
*/
#define pa_ANYCASE   0x0020
/*    -- Setting this flag cause character-case to be ignored when attempting
**       to match single-character argument names (i.e. causes "-i" and "-I"
**       will be considered equivalent).
*/
#define pa_ARGV0     0x0040
/*    -- 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 NOT the case and that the very first
**       argument on the command-line is a bona-fide argument to the command.
*/
#define pa_NOCHECK   0x0080
/*    -- 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).
**
**       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).
*/
#define pa_CONTINUE  0x0100
/*    -- Setting this flag will cause subsequent calls to the parseargs library
**       to NOT reset the current command-state. Hence, all arguments will not
**       be initially set to "NOT GIVEN" and other (normal) initializations are
**       not be performed.  This is useful in conjunction with the pa_NOCHECK
**       when more than one call to parseargs is required to parse all the
**       command arguments. In this scenario, pa_CONTINUE should be unset (the
**       default setting) for the very first call to parseargs, but should then
**       be set before any subsequent calls to parseargs are made.
*/
#define pa_NOCMDENV  0x0200
/*    -- Setting this flag prevents parseargs from checking the <CMD-NAME>_ARGS
**       environment variable for any user-defined default command arguments.
*/
#define pa_COPYF     0x0400
/*    -- When this flag is OFF (the default), a value of FALSE is provided as
**       the <copyf> argument to all the arg-type (argXxxxx) functions when an
**       argument is matched. Setting this flag will cause a value of TRUE to
**       be provided as the <copyf> argument to all the arg-type (argXxxxx)
**       functions when an argument is matched.
*/
/**^^**********************************************************************/
X
X
/**********************************************************************
** ^SECTION: PARSE-CNTLS - specify which attributes to get/set
**    Each of the following function codes specifies an attribute that
**    is to be manipulated by parsecntl(3).  The function code is the
**    second parameter to parsecntl(3). With the exception of pc_ARGFLAGS,
**    each of the function codes corresponds to a call to parsecntl(3) 
**    using four parameters (pc_ARGFLAGS 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 parsecntl).
*/
typedef enum  {
X   pc_PARSEFLAGS,
/*    -- get/set parse flags
**
**    This function code is used to read and/or modify the existing parsing 
**    parsing behavior. The fourth parameter to parsecntl should be a 
**    combination of pc_XXXX bitmasks if the parse-flags are only being
**    written, otherwise it should be a pointer to an argMask_t variable.
*/
X   pc_ARGFLAGS,
/*    -- get/set argument flags
**
**    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 parsecntl 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 argMask_t variable which will receive the resulting
**    argument-flags.
*/
X   pc_DEFARGS,
/*    -- get/set the default arguments
**
**    This function code is used to query or modify the current default
**    argument-descriptor list for the given command. The fourth parameter
**    to parsecntl 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).
**
**    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 pc_DEFARGS function
**    of parsecntl(3). In such a  manner, a  programmer could specify a dif-
**    ferent 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.
**
**    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
**    main() were used for each command, then main could define one common
**    argdesc-array and then a set of argdesc-arrays for each command. Main
**    could then figure out which argdesc-array to used based on the name in
**    argv[0], and set its default argdesc-array to be the common argdesc-
**    array, as in the following:
**
**         #include <parseargs.h>
**             .
**             . variable declarations
**             .
**
**         static ARGDESC common_args[] = {
**            STARTOFARGS,
**            'L', ARGOPT, argBool, __ &lflag, "list (list available items)"
**            'I', ARGOPT, argStr, __ &item, "item (specify item to use)",
**            ENDOFARGS
**         };
**
**         static ARGDESC cmd1_args[] = {
**            STARTOFARGS,
**            's', ARGOPT, argBool, __ &sflag, "S (set S)",
**            't', ARGOPT, argBool, __ &tflag, "T (set T)",
**            ENDOFARGS
**         };
**
**         static ARGDESC cmd2_args[] = {
**            STARTOFARGS,
**            'x', ARGOPT, argBool, __ &xflag, "X (set X)",
**            'y', ARGOPT, argBool, __ &yflag, "Y (set Y)",
**            ENDOFARGS
**         };
**
**         main( argc, argv ) int argc; char *argv[];
**         {
**            ARGDESC *cmd = cmd1_args;
**            int status;
**
**            if ( strcmp(*argv, "cmd2") == 0 ) cmd = cmd2_args;
**
**            if ( parsecntl( cmd, pc_DEFARGS, pc_WRITE, common_args ) != 0 )
**               syserr( "unable to set default args" );
**
**            status = parseargs( argv, cmd );
**                   .
**                   .
**                   .
**         }
**
**    Note that in the above call to 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).
*/
X   pc_NAME,
/*    -- get/set the command-name
*/
X   pc_PURPOSE,
/*    -- get/set the command-purpose
*/
X   pc_DESCRIPTION
/*    -- get/set the command-description
*/
/*    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 parsecntl should be the new string to use (or the address
**    of the string, a char** variable, to recieve the current value).
*/
} parsecntl_t;
X
/**^^**********************************************************************/
X
X
/**********************************************************************
** ^SECTION: PARSE-MODES - modes to get/set command attributes.
**    Parsecntl 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
**    parsecntl in pc_WRITE mode and passing the new attributes will do the
**    job. If the programmer wishes simply to query attributes, then
**    invoking parsecntl in pc_READ mode and passing a pointer to the
**    desired object in which to write the attribute settings will suffice.
**
**    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 parsecntl for pc_RDWR mode and pass a pointer
**    to the object containing the new attribute settings; When parsecntl
**    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
**    parsecntl was invoked.
*/
typedef enum  {
X   pc_READ,
/*    -- read-mode: attributes are retrieved
*/
X   pc_WRITE,
/*    -- write-mode: attributes are assigned new values
*/
X   pc_RDWR
/*    -- read/write-mode: attributes are retrieved and then assigned
*/
X
} parsemode_t;
/**^^**********************************************************************/
X
X
X   /*
X   ** private (implementation specific) definitions
X   */
#ifdef PARSEARGS_PRIVATE
X
X   /* macros to define command-line style specific character sequences */
# ifdef amiga_style
#   define  s_ARG_SEP  "=:"  /* AmigaDOS argument separator characters */
# endif
# ifdef ibm_style
#   define  s_ARG_SEP  "="  /* MS-DOS and OS/2 argument separator characters */
# endif
# ifdef unix_style
#   define  c_OPT_PFX  '-'   /* Unix option prefix character */
#   define  c_KWD_PFX  '+'   /* Unix keyword prefix character */
#   define  s_ARG_SEP  "=:"  /* Unix keyword-value separator characters */
# endif
# ifdef vms_style
#   define  s_KWD_PFX  "/"   /* VMS qualifier prefix character */
#   define  s_LSI_SEP  ",+"  /* VMS LiSt Item separator characters */
#   define  s_ARG_SEP  "=:"  /* VMS qualifier-value separator characters */
# endif
X
X
X   /* call the function to parse the given argument-value string */
# define HANDLE(ad,vp,pflags) ((*arg_type(ad))(ad, vp, BTEST(pflags, pa_COPYF)))
X
X
X   /* parse-state flags */
# define  ps_OLDSTYLE     0x01  /* force backward compatibility? */
# define  ps_NOFLAGS      0x02  /* opt/kwd parsing in effect? */
# define  ps_NOCMDENV     0x04  /* <CMD>_ARGS environment-variable parsed? */
# define  ps_NOPARSECNTL  0x08  /* PARSECNTL environment-variable parsed? */
X
typedef unsigned char   ps_flags_t;
X
X
X   /*
X   ** structure to hold arg-desc pointers maintained in the command-context
X   */
typedef struct {
X   ARGDESC  *default_argd;   /* pointer to default args */
X   ARGDESC  *current_list;   /* pointer to ad with arglist (or argvector)
X                             ** that is currently being appended.
X                             */
# ifdef amiga_style
X     ARGDESC  *previous_ad;  /* pointer to previously matched ad */
# endif
} ARGDPTRS;
X
X   /*
X   ** structures to replace the first and last argument descriptor
X   ** in a command (each field must exactly overlay its counterpart
X   ** in an ARGDESC struct).
X   */
typedef struct  {
X   char        id;      /* id is ALWAYS '\0' for first and last ad */
X   ps_flags_t  state_flags;  /* current parse-state */
X   CONST char *argv0;   /* argv[0] from the command-line */
X   ARGDPTRS   *argdp;   /* structure with ARGDESC pointers */
X   CONST char *purpose; /* one-line purpose provided with CMD_NAME */
} CTXDESC;  /* the command-context */
X
typedef struct  {
X   char        id;      /* id is ALWAYS '\0' for first and last ad */
X   argMask_t   parse_flags;  /* current parse-flag bitmasks */
X   CONST char *name;    /* command-name provided with CMD_NAME */
X   CTXDESC    *context; /* pointer to command-context */
X   CONST char *description;  /* description provided with CMD_DESCRIPTION */
} CMDDESC; /* the command-descriptor */
X
X   /*
X   ** macros to extract command-line attributes in the command-object
X   */
# define  cmd_desc(cmd)         (CMDDESC *)cmd
# define  cmd_id(cmd)           (cmd_desc(cmd)) -> id
# define  cmd_flags(cmd)        (cmd_desc(cmd)) -> parse_flags
# define  cmd_name(cmd)         (cmd_desc(cmd)) -> name
# define  cmd_description(cmd)  (cmd_desc(cmd)) -> description
# define  cmd_context(cmd)      (cmd_desc(cmd)) -> context
# define  cmd_ctxid(cmd)        (cmd_context(cmd)) -> id
# define  cmd_state(cmd)        (cmd_context(cmd)) -> state_flags
# define  cmd_argv0(cmd)        (cmd_context(cmd)) -> argv0
# define  cmd_purpose(cmd)      (cmd_context(cmd)) -> purpose
# define  cmd_ptrs(cmd)         (cmd_context(cmd)) -> argdp
# define  cmd_defargs(cmd)      (cmd_ptrs(cmd)) -> default_argd
# define  cmd_list(cmd)         (cmd_ptrs(cmd)) -> current_list
# ifdef amiga_style
#   define  cmd_prev(cmd)  (cmd_ptrs(cmd)) -> previous_ad
# endif
X
X   /* macro to determine if a command-object has been initialized */
# define  CMD_isINIT(cmd)  \
X   ( !cmd_id(cmd)  &&  cmd_context(cmd) )
X
X   /*
X   ** macros to help ascertain argument type
X   */
# define ARG_isBOOLEAN(ad)   \
X   ( arg_type(ad) == argBool  || arg_type(ad) == argSBool || \
X     arg_type(ad) == argUBool || arg_type(ad) == argTBool    \
X   )
# define ARG_isPSEUDOARG(ad) \
X   ( arg_type(ad) == argEnd   || \
X     arg_type(ad) == argUsage || \
X     arg_type(ad) == argDummy    \
X   )
X
X   /*
X   ** macros to assist in traversing a command-object
X   */
# define  ARG_FIRST(cmd)   ((cmd) + 1)
# define  ARG_LAST(cmd)    ( ((ARGDESC *)cmd_context(cmd)) - 1 )
# define  ARG_isEND(ad)    ( arg_cname(ad)  ==  '\0' )
# define  ARG_ADVANCE(ad)  (ad)++
# define  ARG_RETREAT(ad)  (ad)--
X
X
/**********************************************************************
** ^SECTION: USAGECNTL
**    Each of the different values in $USAGECNTL corresponds to a
**    bitmask as follows:
*/
# define  usg_NONE         0x0001
/*    -- "Quiet", "Silent", and "None" : dont print usage
*/
# define  usg_VERBOSE      0x0002
/*    -- "Verbose", "!Terse" : print argument descriptions
*/
# define  usg_OPTS         0x0004
/*    -- "Options" -- print option syntax
*/
# define usg_LONGOPTS     0x0008
/*    -- "LongOpts", "KeyWords" : print long-option/keyword syntax
*/
# define  usg_DESCRIPTION  0x0010
/*    -- "Description" : print the command description
*/
# define  usg_PAGED        0x0020
/*    -- "Paged" : pipe the usage message through a paging program
*/
/**^^**********************************************************************/
X
#endif /* PARSEARGS_PRIVATE */
X
X   /*
X   ** pre-defined types available for ad_type
X   */
#ifndef PARSEARGS_NARGTYPES
# define  ARGTYPE(name)  EXTERN  BOOL  name ARGS(( ARGDESC *, char *, BOOL ))
X   ARGTYPE( argUsage );
X   ARGTYPE( argEnd );
X   ARGTYPE( argDummy );
X   ARGTYPE( argBool );
X   ARGTYPE( argSBool );
X   ARGTYPE( argUBool );
X   ARGTYPE( argTBool );
X   ARGTYPE( argChar );
X   ARGTYPE( argStr );
X   ARGTYPE( argInt );
X   ARGTYPE( argShort );
X   ARGTYPE( argLong );
X   ARGTYPE( argFloat );
X   ARGTYPE( argDouble );
X   ARGTYPE( listStr );
X   EXTERN  VOID  listFree ARGS((ArgList *argls));
# define vecFree(vec,type)  \
X	do { \
X		if ( vec.count > 0 ) { \
X			if ( vec.array )  free( vec.array ); \
X			if ( vec.flags )  free( vec.flags ); \
X		} \
X        vec.array = (type *)NULL; \
X        vec.flags = (argMask_t *)NULL; \
X		vec.count = 0; \
X	} while ( 0 )
# define vecDeepFree(vec,type)  \
X	do { \
X		register int i; \
X \
X		for ( i = 0 ; i < vec.count ; i++ ) \
X			if ( BTEST(vec.flags[i], ARGCOPYF) ) \
X				free( (ARBPTR) vec.array[i] ); \
X \
X		if ( vec.count > 0 ) { \
X			if ( vec.array )  free( vec.array ); \
X			if ( vec.flags )  free( vec.flags ); \
X		} \
X        vec.array = (type *)NULL; \
X        vec.flags = (argMask_t *)NULL; \
X		vec.count = 0; \
X	} while ( 0 )
X
# undef ARGTYPE
#endif  /* PARSEARGS_NARGTYPES */
X
X   /*
X   ** parseargs library function-prototypes
X   */
#ifndef  PARSEARGS_NEXTERNS
X   EXTERN int   fparseargs  ARGS(( FILE *, ARGDESC * ));
X   EXTERN int   lparseargs  ARGS(( ArgList *, ARGDESC * ));
X   EXTERN int   sparseargs  ARGS(( char *, ARGDESC * ));
X   EXTERN int   vparseargs  ARGS(( ARGDESC *, int, ...));
X   EXTERN int   parseargs   ARGS(( char **, ARGDESC * ));
X   EXTERN int   parsecntl   ARGS(( ARGDESC *, parsecntl_t, parsemode_t, ...));
X   EXTERN VOID  usage       ARGS(( const ARGDESC * ));
X   EXTERN VOID  init_args   ARGS(( ARGDESC * ));
X   extern CONST char *ProgName;
#endif  /* PARSEARGS_NEXTERNS */
X
#endif  /* PARSEARGS_H */
SHAR_EOF
echo 'File parseargs/parseargs.h is complete' &&
chmod 0664 parseargs/parseargs.h ||
echo 'restore of parseargs/parseargs.h failed'
Wc_c="`wc -c < 'parseargs/parseargs.h'`"
test 42981 -eq "$Wc_c" ||
	echo 'parseargs/parseargs.h: original size 42981, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= parseargs/parseargs.pl ==============
if test -f 'parseargs/parseargs.pl' -a X"$1" != X"-c"; then
	echo 'x - skipping parseargs/parseargs.pl (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting parseargs/parseargs.pl (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'parseargs/parseargs.pl' &&
;#########################################################################
;# ^FILE: parseargs.pl - parseargs for perl programs
;#
;# ^DESCRIPTION:
;#    This file defines a perl function named parseargs to parse
;#    command-line arguments for perl scripts.
;#
;# ^HISTORY:
;#    02/25/91	Brad Appleton	<brad at ssd.csd.harris.com>	Created
;##^^#####################################################################
X
X
;########
;# ^FUNCTION: parseargs - parse command-line argument vectors
;#
;# ^SYNOPSIS:
;#    rc = &parseargs( @argv, $argd )
;#
;# ^PARAMETERS:
;#    argv -- the vector of command-line arguments (usually ARGV).
;#    argd -- the argument-description string
;#
;# ^DESCRIPTION:
;#    Parseargs will invoke parseargs(1) to parse the command-line given
;#    in <argv> for the command defined by <argd>.  The resulting values
;#    will be assigned to the variables indicated by the argument-description
;#    string.
;#
;# ^REQUIREMENTS:
;#    Any desired initial values for variables from the argument-description
;#    string should be assigned BEFORE calling this function.
;#
;#    The following global variables may be assigned before calling parseargs:
;#
;#       PARSEOPTS -- any extra options to pass to parseargs() (default="-u")
;#
;# ^SIDE-EFFECTS:
;#    The global variable PARSEARGS will contain the command-line used to
;#    invoke parseargs(1).
;#
;#    ARGV and ARGC may be reset, all other values are (re)set in <arr>.
;#
;# ^RETURN-VALUE:
;#    The exit code returned by parseargs(1).
;#
;# ^ALGORITHM:
;#    - set defaults for PARSEOPTS
;#    - build the parseargs command (dont forget to quote arguments).
;#    - run parseargs(1) and evaluate the output unless $?
;##^^####
X
sub parseargs {
X    local(@argv) = @_;
X    local($argd);
X    local($parse_output);
X    local($_);
X    local($[) = 0;
X    local($i);
X
X    $argd = pop( @argv );   ## get last arg and remove it
X
X    if ( $PARSEOPTS == "" ) {
X        $PARSEOPTS = '-u';
X    }
X    $PARSEARGS = 'parseargs -s perl ' . $PARSEOPTS . " -- '" . $0 . "'";
X    for ( $i = $[ ; $i <= $#argv ; $i++ ) {
X      $argv[$i] =~ s/'/'\\''/g;
X      $PARSEARGS .= " '" . $argv[$i] . "'";
X    }
X    $parse_output = `echo \'$argd\' | $PARSEARGS`;
X    eval $parse_output unless $?;
X    if ( $? ) {
X      $! = 0;
X      die "\n";
X    }
}
X
1;
SHAR_EOF
chmod 0775 parseargs/parseargs.pl ||
echo 'restore of parseargs/parseargs.pl failed'
Wc_c="`wc -c < 'parseargs/parseargs.pl'`"
test 2311 -eq "$Wc_c" ||
	echo 'parseargs/parseargs.pl: original size 2311, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= parseargs/parseargs1.txt ==============
if test -f 'parseargs/parseargs1.txt' -a X"$1" != X"-c"; then
	echo 'x - skipping parseargs/parseargs1.txt (File already exists)'
	rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting parseargs/parseargs1.txt (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'parseargs/parseargs1.txt' &&
X
X
X
PARSEARGS(1)					     PARSEARGS(1)
X
X
X
NAME
X     parseargs - parse command line arguments in shell scripts
X
SYNOPSIS
X     parseargs	 [-U] [-M] [-T string] [-F string] [-A]	[-a arg-
X		 spec] [-e name] [-f file] [-l]	[-o] [-s shell]
X		 [-u] [-i] [-p]	-- name	[arguments ...]
X
OPTIONS
X     -U		   just	print program usage, do	not parse the
X		   command line
X
X     -M		   just	print (n|t)roff	-man manual page
X		   template, do	not parse the command line
X
X     -T	string	   string to use for true boolean arguments
X		   (default=``TRUE'')
X
X     -F	string	   string to use for false boolean arguments
X		   (default=``'')
X
X     -A		   modify array	behavior for the specified shell.
X
X     -a	arg-spec   argument specification string
X
X     -e	name	   read	the arg-spec string from the environment
X		   variable named name
X
X     -f	file	   read	the arg-spec from file	(default=stdin)
X
X     -l		   Long-options	only. Disable the parsing of
X		   (single-character) options.
X
X     -o		   Options only. Disable the parsing of	long-
X		   options (keywords).
X
X     -s	shell	   use shell command syntax  (default=``sh'')
X
X     -u		   unset positional parameters before assigning
X		   variables
X
X     -p		   prompt the user for missing required	arguments
X
X     -i		   ignore bad command-line syntax and continue
X		   processing (instead of aborting)
X
ARGUMENTS
X     --		   Indicates that any remaining	options	are
X		   intended for	the calling program.
X
X     name	   name	of calling program
X
X
X
X
Page 1
X
X
X
X
X
X
PARSEARGS(1)					     PARSEARGS(1)
X
X
X
X     arguments	   arguments to	calling	program
X
DESCRIPTION
X     Given a command name, a vector of string-valued arguments
X     such as that passed to a shell script, and	a specification
X     string describing the possible arguments, parseargs matches
X     actual arguments to possible arguments, converts values to
X     the desired type, and diagnoses problems such as missing
X     arguments,	extra arguments, and argument values that are
X     syntactically incorrect.  Other behavior such as prompting
X     the user for missing arguments and	ignoring as command-line
X     syntax may	be specified on	the command-line through the use
X     of	various	options, or through the	use of the ``PARSECNTL''
X     environment variable.
X
X     Given the command name and	the argument specification
X     string, parseargs -U prints a reasonably friendly version of
X     the usage of the calling program on standard diagnostic
X     output. The ``verbosity'' of the usage message may	be
X     controlled	through	the use	of the ``USAGECNTL'' environment
X     variable.
X
X     Given the command name and	the argument specification
X     string, parseargs -M prints a template of the command-syntax
X     on	standard output	that is	suitable for input to nroff or
X     troff using the -man macro	package.
X
X     The argument specification	string contains	one entry for
X     each possible flag.  Entries in the arguments specification
X     string are	separated by commas.  Each entry has five comma-
X     separated fields:	a name,	some flags, a type, a variable-
X     name, and a prompt.  Each of these	fields are described
X     below:
X
X     name      The single character name of the	associated flag.
X	       For example, to indicate	that the program is
X	       expecting a ``-x'' flag,	this field would contain
X	       'x'.  Positional	arguments (those without a ``-x''
X	       prefix) are indicated by	passing	a ``space''
X	       character.
X
X     flags     Flags modifying the semantics of	this entry.
X	       These should have one of	ARGREQ to indicate a
X	       required	argument or ARGOPT to indicate an
X	       optional	argument (ARGOPT is the	default	unless
X	       ARGREQ is specified).  ARGPOS can be ``ored'' in
X	       to indicate a positional	argument that may also be
X	       keyword matched.	 ARGNOVAL can be ``ored'' in to
X	       indicate	that an	argument is an option or a
X	       keyword that does not use an accompanying argument
X	       (such as	a boolean flag). This flag is only
X	       required	for corresponding argument types that are
X
X
X
Page 2
X
X
X
X
X
X
PARSEARGS(1)					     PARSEARGS(1)
X
X
X
X	       implemented by the programmer; parseargs	already
X	       knows which pre-defined argument	types take an
X	       argument.  ARGVALOPT can	be ``ored'' in to
X	       indicate	that an	argument to the	option may be
X	       optionally supplied on the command-line,	but is
X	       not required.  ARGVALREQ	can be ``ored''	in to
X	       indicate	that an	argument to the	option is
X	       required	(this is the default behavior for options
X	       that take arguments).  ARGLIST can be ``ored'' in
X	       (using the `|' character) to indicate that an
X	       argument	is actually a list of one or more
X	       arguments from the command line.	 ARGHIDDEN can be
X	       ``ored''	in to indicate a flag that should not be
X	       printed in usage	messages - for example,	flags
X	       intended	for internal debugging purposes.
X
X     type      The type	of the argument.  Existing types include
X	       argUsage	(print usage message and exit),	argBool
X	       and argSBool (set Boolean flags), argUBool (unset
X	       Boolean flags), argStr (string-valued arguments),
X	       argChar (char-valued arguments),	argInt (native
X	       integer arguments), argShort (short integer
X	       arguments), argLong (long integer arguments),
X	       argFloat	(short floating	point arguments),
X	       argDouble (long floating	point arguments), and
X	       argDummy	(only used as part of usage message, not
X	       matched on command-line).
X
X     variable  The name	of the shell variable that should receive
X	       the converted value.
X
X     prompt    The string used when prompting interactively for
X	       argument	values,	and printed in usage messages.
X	       This string may be followed by a	textual
X	       description that	is enclosed in parentheses,
X	       square brackets,	curly braces, or angle brackets.
X
X     The argument specification	string must be terminated by the
X     single string:  ``ENDOFARGS''.
X
X     Note that the comma character (',') is used to separate all
X     fields within an entry, and to separate the entries
X     themselves.  For this reason, no field in any entry may
X     contain a comma unless it appears inside of double	or single
X     quotes.
X
X     Parseargs will parse all command-line arguments for the
X     calling script and	match them against the argument
X     specification string provided. The	argument specification
X     string is read from standard input	by default but may not
X     come from a terminal. The argument	specification string may
X     be	supplied as a single string argument by	using the -a
X
X
X
Page 3
X
X
X
X
X
X
PARSEARGS(1)					     PARSEARGS(1)
X
X
X
X     ``string''	flag.  Long argument specification strings
X     however, may limit	the number of arguments	to the script if
X     there is a	limit to the number of arguments and/or
X     characters	that may appear	on the command line.  For this
X     reason, the argument specification	string may be stored: in
X     an	environment variable using the -e name option; in a file
X     and read using the	-f file	option;	or read	from standard
X     input.  When using	the -e option, the user	must remember to
X     use the name of an	environment variable (not a mere shell
X     variable)!	 The default behavior is to read the argument
X     specification from	standard input.
X
SHELLS
X     After the command line has	been parsed, parseargs will print
X     on	standard output, a script to set the shell variables
X     which correspond to arguments that	were present on	the
X     command-line.  This script	may be evaluated by redirecting
X     it	to a file and then executing the file, or by directly
X     evaluating	the output from	parseargs (under most UNIX
X     shells, this could	be done	using eval).  If any arguments on
X     the command line contained	any special characters that
X     needed to be escaped from the shell, these	characters will
X     remain intact (not	be evaluated by	the shell) in the
X     corresponding shell variable.
X
X     The -s shell option may be	used to	tell parseargs which
X     shell syntax to use. At present, parseargs	only recognizes
X     ``sh'', ``csh'', ``ksh'', ``tcsh'', ``bash'', ``rc'',
X     ``awk'', and ``perl'' as valid command interpreters. Awk
X     output is slightly	different from that of the other shells
X     in	that the actual	variable setting are not printed but each
X     line of an	associative array is printed (the first	field is
X     the array index, the second is the	value for that index).
X     If	no shell is specified, then the	Bourne shell (``sh'')
X     will be assumed.
X
X     If	the user wishes	to use a value other than ``TRUE'' for a
X     boolean flag that is true,	this may be done using the -T
X     string option.  The same may also be done for a boolean flag
X     that is false using the -F	string option.
X
X     Parseargs will only set the values	of variables that
X     correspond	to arguments that were given on	the command line.
X     If	a particular argument was not supplied on the command
X     line, then	no assignment is made for the corresponding shell
X     variable and it will have the same	value that it had before
X     parseargs was invoked. The	only exception to this is that if
X     the -u option is specified, then the positional parameters
X     are unset before any shell	variable assignments (which may
X     reset the positional parameters) are made.
X
X
X
X
X
Page 4
X
X
X
X
X
X
PARSEARGS(1)					     PARSEARGS(1)
X
X
X
X     The double-dash (``--'') which precedes the name and
X     arguments of the calling program is needed	in order for
X     parseargs to be able to distinguish options to itself from
X     options for the calling program.
X
X     The default behavior of parseargs is allow	both single-
X     character options and long-options	(keywords) on the
X     command-line. The user may	specify	that only options (long-
X     options) are to be	permitted by specifying	the -o (-l)
X     option on the command-line.
X
OPTIONS	WITH OPTIONAL ARGUMENTS
X     Options that may take an optional argument	need special
X     consideration.  The shell programmer needs	to know	whether
X     or	not the	option was given, and (if given) if it was
X     accompanied by an argument. In order to accommodate this
X     need, parseargs will set an additional shell variable for
X     each argument that	is given the ARGVALOPT flag if it is
X     supplied on the command line regardless of	whether	or not it
X     was accompanied by	its optional argument.	If the user has
X     defined an	option which may optionally take an argument and
X     the option	appears	on the command line with or without its
X     associated	argument, then the shell variable <name>_flag
X     will be assigned the value	``TRUE'' (or the value supplied
X     with the -T option	to parseargs) where <name> is the name of
X     the shell variable	associated with	the option in the
X     argument description string.
X
ARGUMENT LISTS
X     Parseargs treats ARGLIST arguments	in a special way. The
X     method used for setting up	an argument list depends largely
X     upon the syntax of	shell that was specified on the	command
X     line via the -s option (although ARGLIST arguments	are
X     treated exactly the same as ARGVEC	arguments).
X     Resetting the Positional Parameters to an Argument	List
X
X     For the Bourne, Bourne-Again, and Korn shells, if the
X     variable name corresponding to the	ARGLIST	argument is
X     ``--'', then the positional parameters of the calling
X     program will be re-assigned to the	contents of the	argument
X     list ($1 will be the first	item, $2 the second item, and so
X     on). In this particular case, the calling program may wish
X     to	use the	-u option to reset the positional parameters to
X     NULL before making	any shell-variable assignments (this way,
X     the positional parameters will be unset if	the associated
X     list of command line arguments is not encountered).
X
X     Similarly for the C and TC	shells,	if the variable	name
X     corresponding to the ARGLIST argument is ``argv'',	then the
X     positional	parameters of the calling program will be re-
X     assigned to the contents of the argument list.
X
X
X
X
Page 5
X
X
X
X
X
X
PARSEARGS(1)					     PARSEARGS(1)
X
X
X
X     For the Plan 9 shell (rc),	if the variable	name
X     corresponding to the ARGLIST argument is ``*'', then the
X     positional	parameters of the calling program will be re-
X     assigned to the contents of the argument list.
X
X     For the awk and perl, if the variable name	corresponding to
X     the ARGLIST argument is ``ARGV'', then the	positional
X     parameters	of the calling program will be re-assigned to the
X     contents of the argument list.
X     Bourne Shell Argument Lists
X
X     For the Bourne shell, if the associated variable name is NOT
X     ``--'' and	the -A option was NOT specified, then that
X     variable is treated as a regular shell variable and is
X     assigned using the	following syntax:
X	  name='arg1 arg2  ...'
X     After invoking parseargs, if you wish to go through all the
X     words in the variable name	and one	of the words in	name
X     contains an IFS character (such as	a space	or a tab), then
X     that particular word will be treated by the Bourne	shell as
X     two distinct words.
X
X     Also for the Bourne shell,	If the associated variable name
X     is	NOT ``--'' and the -A option WAS specified, then that
X     variable is treated as the	root name of an	array that is set
X     using the following syntax:
X	  name1='arg1'
X	  name2='arg2'
X	      ...
X     and the variable ``name_count'' will be set to contain the
X     number of items in	the array.  The	user may then step
X     through all the items in the array	using the following
X     syntax:
X	  i=1
X	  while	[ $i -le $name_count ] ; do
X	    eval echo "item #$i	is: " \$name$i
X	    i=`expr $i + 1`
X	  done
X     Korn Shell	Argument Lists
X
X     For the Korn shell, if the	associated variable name is NOT
X     ``--'', then that variable	is treated as an array and is
X     assigned using the	-A option of the set command. The first
X     item will be in ${name[0]}, the second item will be in
X     ${name[1]}, etc ..., and all items	may be given by
X     ${name[*]}	or ${name[@]}.	If the associated variable name
X     is	NOT ``--'' and the -A option WAS specified, then that
X     variable is assigned using	the +A option of the set command
X     (which preserves any array	elements that were not
X     overwritten by the	set command).
X     It	should be noted	that there is a	bug in versions	of the
X     Korn shell	earlier	than 11/16/88a,	in which the following:
X
X
X
Page 6
X
X
X
X
X
X
PARSEARGS(1)					     PARSEARGS(1)
X
X
X
X	  set  -A  name	 'arg1'	 'arg2'	 ...
X     causes the	positional parameters to be overwritten	as an
X     unintentional side-effect.	If your	version	of the Korn shell
X     is	earlier	than this and you wish to keep the contents of
X     your positional parameters	after invoking parseargs than you
X     must save them yourself before you	call parseargs.	This may
X     be	accomplished by	the following:
X	  set  -A  save_parms  "$@"
X     C and TC Shell Argument Lists
X
X     For the C and TC shells, ARGLIST variables	are treated as
X     word-lists	and are	assigned using the following syntax:
X	  set  name = (	'arg1'	'arg2'	... )
X     The first item will be in $name[1], the second item will be
X     in	$name[2], etc ..., and all items may be	given by $name.
X     Notice that Korn shell arrays start at index zero whereas C
X     and TC shell word-lists start at index one.
X
X     Bourne-Again Shell	Argument Lists
X
X     At	present, the Free Software Foundation's	Bourne-Again
X     shell is treated exactly the same as the Bourne Shell. This
X     will change when bash supports arrays.
X     Plan 9 Shell Argument Lists
X
X     For the Plan 9 shell, if the associated variable name is not
X     ``*'' then	it is considered to be word-list and set using
X     the following syntax:
X	  name=( 'arg1'	 'arg2'	 ... )
X
X     Awk Argument Lists
X     For awk, if the -A	option is not given, then the output for
X     thes variable-list	will be	a line with the	variable name,
X     followed by a line	with each of the values	(each value will
X     be	separated with the field separator specified using the -S
X     option - which defaults to	a space).
X	  name
X	  arg1	arg2  ...
X     If	the -A option is given,	then the associated variable is
X     considered	the root name of an array. The ouput for the
X     array will	consist	of two lines for each item in the list
X     (as in the	following expample):
X	  name1
X	  arg1
X
X	  name2
X	  arg2
X
X     and the variable ``name_count'' will have an output line
X     showing the number	of items in the	array.
X
X
X
X
X
Page 7
X
X
X
X
X
X
PARSEARGS(1)					     PARSEARGS(1)
X
X
X
X     Perl Argument Lists
X
X     For perl, each argument list is considered	an array and is
X     set using the following syntax:
X	  @name=( arg1 , arg2 ,	 ... )
X
X
X     The word-lists used by the	C shell, the arrays used by the
X     Korn shell, the Plan 9 shell, awk,	perl, and the positional
X     parameters	used by	all shells (if overwritten by parseargs)
X     will preserve any IFS characters in their contents.  That is
X     to	say that if an item in one of the aforementioned multi-
X     word lists	contains any IFS characters, it	will not be split
X     up	into multiple items but	will remain a single item which
X     contains IFS characters.
X
SUPPLYING DEFAULT ARGUMENTS
X     Programs that use parseargs may be	given default arguments
X     under UNIX	and PCs	through	the use	of environment variables
X     (symbols are used for VMS systems). If a  C-program or
X     shell-script uses parseargs to implement a	command	named
X     ``cmd'' then the environment variable ``CMD_ARGS''	will be
X     parsed for	any "default" arguments	before the command-line
X     is	parsed.	 The command-line will over-ride any options that
X     are specified in this environment variable	(except	that
X     ARGLISTs and ARGVECs set in ``CMD_ARGS'' will be appended
X     from the command-line
X
X     It	is important to	note that the contents of the
X     ``CMD_ARGS'' environment variable are NOT expanded	by the
X     shell and hence any special characters (such as quotes or
X     back-slashes) will	NOT be escaped or removed by parseargs.
X     Furthermore, it will not be possible to try and use a tab,
X     space, or newline character in the	environment variable as
X     anything other than an argument separator.
X
X     Lastly, parts of an option	specification in ``CMD_ARGS'' may
X     NOT be continued on the command-line. As an example, if -f
X     requires an argument and CMD_ARGS="-f", then the command-
X     line "cmd	bah" will NOT assign "bah" as the argument to -f
X     but will instead complain about a missing argument	for -f.
X     Similarly,	if -l takes a list of arguments	and CMD_ARGS="-l
X     item1 item2", then	the command-line "cmd  bah", will NOT
X     assign "bah" to the end of	the list containing "item1" and
X     "item2" but will instead treat "bah" as the first positional
X     parameter on the command-line.
X
PARSING	BEHAVIOR
X     The programmer may	control	parsing	behavior through the use
X     of	parsecntl(3).  The user	may set	his (or	her) own desired
X     parsing behavior through the use of the ``PARSECNTL''
X     environment variable.  By indicating any number of	flags
X
X
X
Page 8
X
X
X
X
X
X
PARSEARGS(1)					     PARSEARGS(1)
X
X
X
X     (possibly negated)	the user will directly modify the
X     behavior of the parseargs library.	Flags may be combined by
X     placing a `+' or `|' character in between flags. A	switch is
X     negated by	immediately preceding it with a	`!' or `-'
X     character.	 The possible ``flags''	are given by the
X     following table. Flags are	case-insensitive.
X
X     Prompt
X	  Prompt the user for any missing arguments that are
X	  required on the command-line.	No special escaping or
X	  quoting is performed on the user input. Required
X	  arguments that expect	a list of values will be
X	  repeatedly prompted for (one item per	line) until a
X	  blank	line (followed by a carriage return) is	entered.
X
X     Ignore
X	  Ignore any unrecognized or improperly	specified
X	  command-line arguments and continue execution	of the
X	  program. Normally, if	an argument is unmatched (or is
X	  improperly specified), a usage message is printed
X	  program execution is terminated.
X
X     OptsOnly
X	  Under	UNIX, setting this flag	will disable the parsing
X	  of long-option syntax. This will cause all arguments
X	  starting with	'+' to always be treated as a positional
X	  parameter (instead of	a long-option).
X
X     KwdsOnly
X	  Under	UNIX, setting this flag	disables the parsing of
X	  single-character options.  This will cause all
X	  arguments starting with '-' to always	be treated as a
X	  positional parameter (instead	of an option).
X
X     LoptsOnly
X	  Same as KwdsOnly.
X
X     Flags1st
X	  Setting this flag causes the parseargs library to force
X	  any and all non-positional arguments to be specified
X	  before any positional	ones.  As an example, under UNIX,
X	  if this flag is SET then parseargs will consider the
X	  command line "cmd -x arg" to consist of one option and
X	  one positional argument; however the command line "cmd
X	  arg -x" would	be considered to consist of two
X	  positional arguments (the -x option will be unmatched).
X
X	  If this flag is UNSET, then both of the previous
X	  examples are considered to consist of	one option and
X	  one positional argument.
X
X     CaseIgnore
X
X
X
Page 9
X
X
X
X
X
X
PARSEARGS(1)					     PARSEARGS(1)
X
X
X
X	  Setting this flag cause character-case to be ignored
X	  when attempting to match single-character argument
X	  names	(i.e. causes "-i" and "-I" will	be considered
X	  equivalent).
X
X     If	the environment	variable ``PARSECNTL'' is empty	or
X     undefined,	then parsing behavior set by the programmer is
X     used.  If the programmer has not explicitly used
X     parsecntl(3) to modify the	parsing	behavior will be
X     ``!Prompt + !Ignore'' for Unix MS-DOS, OS/2, and AmigaDOS
X     systems, and ``Prompt'' for VMS systems.
X
USAGE MESSAGES
X     Through the use of	an environment variable	(or a VMS
X     symbol), the user may control the syntax and the verbosity
X     of	the command-usage messages that	are printed by parseargs.
X     The desired level of verbosity may	be set by defining the
X     environment variable ``USAGECNTL" to be a combination of
X     strings (case insensitive). The value of each string
X     controls one of three different ``modes'' of behavior in the
X     displaying	of usage messages:  The	first ``mode'' is
X     ``verbose'' mode, which controls whether or not a detailed
X     description of each argument should accompany the usual
X     command-line sysnopsis. If	verbose	mode is	``off'', then
X     only a command-line synopsis is printed (this is also
X     refferred to as ``terse'' mode). The other	two ``modes''
X     control the displaying of option syntax and long-option
X     syntax. A mode may	be explicitly disabled by preceding its
X     corresponding string with the `!'	character. The ``modes''
X     which correspond to the possible values of	the ``USAGECNTL''
X     environment variable are given by the following table.
X
X
X     Quiet
X	  No usage message of any kind is displayed.
X
X     Silent
X	  Same as Quiet.
X
X     Paged
X	  The usage message is piped to	a pager. The pager used
X	  is named by the ``USAGE_PAGER'' environment variable.
X	  If this variable is unset or empty (or is not	the name
X	  of an	executable program) then the pager named by the
X	  ``PAGER'' environment	variable us used.  If this
X	  variable is unset or empty (or is not	the name of an
X	  executable program) then /usr/ucb/more is used.
X
X     Description
X	  The command description is printed.
X
X     Terse
X
X
X
Page 10
X
X
X
X
X
X
PARSEARGS(1)					     PARSEARGS(1)
X
X
X
X	  Terse	mode, just print command-line synopsis.
X
X     Verbose
X	  Verbose mode,	print descriptions for each argument
X
X     Options
X	  Option syntax	is displayed.
X
X     LongOpts
X	  Long-option syntax is	displayed.
X
X     KeyWords
X	  Same as LongOpts.
X
X     If	the environment	variable ``USAGECNTL'' is empty	or
X     undefined,	then the default usage level (which is presently
X     ``Verbose + Options'') will be used.
X
EXAMPLES
X     As	a first	example, consider the following	argument
X     specification for a Bourne	shell script:
X
X     #!/bin/sh
X
X     RepCount=2;
X     Verbose="";
X     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}',
X     ENDOFARGS
X     "
X
X     eval `echo	"$ARGUMENTS" | parseargs -s sh -- $0 "$@"`
X
X     This describes a Bourne shell script accepting up to three
X     flag arguments and	one or two positional arguments, plus a
X     list of additional	file arguments.	 Only the first
X     positional	argument is required.  The possible flags (in
X     UNIX) are:
X
X	  -c count  An integer repetition count.  This defaults
X		    to two.
X
X	  -v	    A Boolean ``verbose'' flag.	 It defaults to
X		    FALSE (an empty string).
X
X	  -X	    A Boolean ``X Rated'' flag.	 This is not
X		    printed in the usage message.
X
X
X
Page 11
X
X
X
X
X
X
PARSEARGS(1)					     PARSEARGS(1)
X
X
X
X     The two positional	arguments are both strings, as is the
X     final list.  If we	were to	invoke the above script	with the
X     following command line:
X	  cmdname  -v  input_file  output_file	file1  file2
X
X     Then, after invoking parseargs, the following shell
X     variables would contain the following values:
X	  $RepCount would evaluate to ``2''
X
X	  $Verbose would evaluate to ``TRUE''
X	  $InFile would	evaluate to ``input_file''
X
X	  $OutFile would evaluate to ``output_file''
X	  $Files would evaluate	to ``file1  file2''
X
X	  $XRated would	be unset and would evaluate to an empty
X	  string (``'').
X
X
X     Now let's present a more complete example.	The following
X     page shows	a Bourne shell script which uses parseargs to
X     parse its command line, echoes the	settings of all	its
X     associated	command	line variables,	and then prints	its
X     command usage.
X
X     #!/bin/sh
X     #	  test.sh - Bourne shell script	to test	out the	parseargs command!
X     #
X     NAME="`basename $0`";  DOT=".";
X
X     ARGUMENTS="
X       '?', ARGHIDDEN, argUsage, NULL,	  'Help	: print	usage and exit',
X       'S', ARGVALOPT, argStr,	 string,  'STRing : optional string arg',
X       'g', ARGLIST,   argStr,	 groups,  'newsGROUPS :	groups to test',
X       'r', ARGOPT,    argInt,	 count,	  'REPcount <# to repeat each group>',
X       'd', ARGOPT,    argStr,	 dirname, 'DIRectory : working directory',
X       'x', ARGOPT,    argBool,	 xflag,	  'Xflag : turn	on X-mode',
X       'y', ARGOPT,    argUBool, yflag,	  'Yflag : turn	off Y-mode',
X       's', ARGOPT,    argChar,	 sepch,	  'SEPchar : field separator',
X       'f', ARGLIST,   argStr,	 files,	  'files : files to process',
X       'n', ARGREQ|ARGPOS, argStr, name,  'name	: name to use',
X       ' ', ARGLIST,   argStr,	 -- ,	  'argv	: any remaining	arguments',
X       ENDOFARGS
X     "
X     export ARGUMENTS
X
X     yflag='TRUE'     ## set defaults (dir=".";	count=1; sepch=',') ##
X
X     ##	parse command-line and save assignments	in a temporary file ##
X     parseargs -s sh -e	ARGUMENTS -u --	"$NAME"	"$@" >/tmp/tmp$$
X     if	[ $? -ne 0 ]
X       then rm -f /tmp/tmp$$; exit 2  ## non-zero status (usage	given)
X
X
X
Page 12
X
X
X
X
X
X
PARSEARGS(1)					     PARSEARGS(1)
X
X
X
X     fi
X
X     ##	evaluate results from parseargs	and remove temporary file
X     $DOT /tmp/tmp$$;  rm -f /tmp/tmp$$
X
X     ##	echo  the parsed arguments (use	defaults if not	defined)
X     echo "ARGUMENTS:"
X     echo "=========="
X     echo "Name='$name', Count='${count:-1}'"
X     echo "XFlag='$xflag', YFlag='$yflag'"
X     echo "Directory='${dirname:-"."}',	SepChar='${sepch:-","}'"
X     echo "Groups='$groups'"
X     echo "Files='$files'"
X     if	[ "$string_flag" ]
X       then string=${string:-"!string arg ommitted on cmd-line!"}
X       else string="default string"
X     fi
X     echo "String='$string'"
X     echo "New Positional Parameters='$*'"
X
X     parseargs -a "$ARGUMENTS" -U "$NAME"     ## print usage ##
X
DIAGNOSTICS
X     Parseargs may exit	with one of the	following status codes:
X
X
X     -1	  Some type of system error occurred during execution,
X	  causing the program to exit prematurely.
X
X     0	  Normal exit status (no problems were encountered).
X
X     1	  The calling program specified	the -U or the -M option
X	  to parseargs,	or specified an	argUsage flag on the
X	  command line.	 Only the appropriate message is
X	  displayed.
X
X     2	  A command line syntax	error was encountered by
X	  parseargs. The offending command line	argument may have
X	  been intended	for either parseargs or	for the	calling
X	  program.
X
X     3	  The environment variable that	was specified with the -e
X	  option is either NULL	(has an	empty value) or	does not
X	  exist. Perhaps the user specified a shell variable
X	  and/or forgot	to export it.
X
X     4	  A syntax error was encountered in the	argument
X	  specification	string that was	specified to parseargs.
X
FILES
X     /usr/local/parseargs.pl
X	  This file defines a perl function named parseargs to
X
X
X
Page 13
X
X
X
X
X
X
PARSEARGS(1)					     PARSEARGS(1)
X
X
X
X	  parse	arguments more conveniently for	perl-scripts. The
X	  function is both documented and implemented in this
X	  file.	The user should	``require'' this file in his/her
X	  perl-script before invoking the function.
X
X     /usr/local/parseargs.awk
X	  This file defines an awk function named parseargs to
X	  parse	arguments more conveniently for	awk-scripts. The
X	  function is both documented and implemented in this
X	  file.	The user should	include	this file in his/her
X	  awk-script before invoking the function.
X
SEE ALSO
X     argtype(3), parseargs(3), parsecntl(3)
X
CAVEATS
X     Because of	the way	argument parsing is implemented	under
X     UNIX, MS-DOS, and OS/2, option arguments which contain a
X     leading dash (`-')	(or whatever the option	prefix character
X     is	defined	to be) may not be specified as a separate
X     argument on the command line, it must be part of the same
X     argument. That is to say that if a	program	has a -f option
X     that requires a string argument, then the following:
X	  -f-arg
X
X     will properly assign the string ``-arg'' to the option
X     whereas the following:
X	  -f -arg
X
X     will be interpreted by parseargs as two option strings: the
X     first of which (``-f'') is	missing	a required argument and
X     the second	of which (``-arg'') will most likely be	flagged
X     as	an invalid option.
X
X     Similarly,	if the user requires an	ARGLIST	option to take
X     multiple arguments	with leading dashes then the following
X     method must be used: It is	a ``feature'' of parseargs that
X     ARGLIST arguments are always appended to the current list of
X     arguments for the given option. Thus, if ``-f'' is	an option
X     taking a list of arguments, then the following are	all
X     equivalent:
X	  -farg1 arg2
X
X	  -f arg1 arg2
X	  -farg1 -farg2
X
X	  -f arg1 -f arg2
X     Hence multiple ``leading dash'' arguments may specified as
X     follows:
X
X	  -f-dash_arg1 -f-dash_arg2  ...
X
X
X
X
Page 14
X
X
X
X
X
X
PARSEARGS(1)					     PARSEARGS(1)
X
X
X
BUGS
X     It	does not make sense to use any arguments of type argTBool
X     since parseargs currently has no way of knowing what the
X     initial value of the variable is. For this	reason,	argTBool
X     is	not recognized as a valid argument type	(even though it
X     is	used by	parseargs(3)). By the same token, since	the user
X     cannot create their own arguments types on	the fly	from a
X     shell-script, ARGNOVAL is not recognized as a valid argument
X     flag.
X
X     Commas will not be	interpreted properly if	any field in the
X     argument specification string contains double quotes that
X     are nested	inside of double quotes, or single quotes that
X     are nested	inside of single quotes.
X
X     Inside the	argument specification string, any repeated
X     string of commas that does	not appear inside of double or
X     single quotes will	be treated as a	single comma.
X
X     Text descriptions for argument entries are	automatically
X     formatted in usage	messages. Any attempt by the user to
X     include tabs and/or newlines in the description will cause
X     it	to be formatted	improperly.
X
X     Parseargs cannot properly preserve	any newlines in	shell
X     variables if the eval command is used to read its output
X     (this is a	shortcoming of the eval	command, not of
X     parseargs). If the	user is	concerned about	this particular
X     case, then	the user should	redirect the output from
X     parseargs to a temporary file and use the source command in
X     csh or the	dot command (`.') in sh	and ksh, to interpret the
X     results; otherwise, newlines will be translated into spaces,
SHAR_EOF
true || echo 'restore of parseargs/parseargs1.txt failed'
fi
echo 'End of  part 7'
echo 'File parseargs/parseargs1.txt is continued in part 8'
echo 8 > _shar_seq_.tmp
exit 0
exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent at sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent at uunet.uu.net.



More information about the Comp.sources.misc mailing list