home *** CD-ROM | disk | FTP | other *** search
- From: brad@hcx1.ssd.csd.harris.com (Brad Appleton)
- Newsgroups: comp.sources.misc
- Subject: v17i052: parseargs - functions to parse command line arguments, Part07/12
- Message-ID: <1991Mar18.155620.2062@sparky.IMD.Sterling.COM>
- Date: 18 Mar 91 15:56:20 GMT
- Approved: kent@sparky.imd.sterling.com
- X-Checksum-Snefru: 00a33476 552c2895 40115535 19ba6afb
-
- Submitted-by: Brad Appleton <brad@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@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@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.
-