Brad Appleton <brad@hcx1.ssd.csd.harris.com> (05/18/91)
Submitted-by: Brad Appleton <brad@hcx1.ssd.csd.harris.com> Posting-number: Volume 19, Issue 85 Archive-name: parseargs/patch05d Patch-To: parseargs: Volume 17, Issue 45-57 #!/bin/sh # do not concatenate these parts, unpack them in order with /bin/sh # file PATCH05 continued # if test ! -r _shar_seq_.tmp; then echo 'Please unpack part 1 first!' exit 1 fi (read Scheck if test "$Scheck" != 4; then echo Please unpack part "$Scheck" next! exit 1 else exit 0 fi ) < _shar_seq_.tmp || exit 1 if test ! -f _shar_wnt_.tmp; then echo 'x - still skipping PATCH05' else echo 'x - continuing file PATCH05' sed 's/^X//' << 'SHAR_EOF' >> 'PATCH05' && - ``verbose'' mode, which controls whether or not a detailed - description of each argument should accompany the usual - command-line sysnopsis. If verbose mode is ``off'', then - only a command-line synopsis is printed (this is also - refferred to as ``terse'' mode). The other two ``modes'' - control the displaying of option syntax and long-option - - - - Page 10 - - - - - - - PARSEARGS(1) PARSEARGS(1) - - - - syntax. A mode may be explicitly disabled by preceding its - corresponding string with the `!' or `-' character. The - ``modes'' which correspond to the possible values of the - ``USAGECNTL'' environment variable are given by the - following table. - - Quiet - No usage message of any kind is displayed. - - Silent - Same as Quiet. - - Paged - The usage message is piped to a pager. The pager used - is named by the ``USAGE_PAGER'' environment variable. - If this variable is unset or empty (or is not the name - of an executable program) then the pager named by the - ``PAGER'' environment variable us used. If this - variable is unset or empty (or is not the name of an - executable program) then /usr/ucb/more is used. - - Description - The command description is printed. - - Terse - Terse mode, just print command-line synopsis. - - Verbose - Verbose mode, print descriptions for each argument - - Options - Option syntax is displayed. - - LongOpts - Long-option syntax is displayed. - - KeyWords - Same as LongOpts. - - - If the environment variable ``USAGECNTL'' is empty or - undefined, then the default usage level (which is presently - ``Verbose + Options'') will be used. - - EXAMPLES - As a first example, consider the following argument - specification for a Bourne shell script: - - #!/bin/sh - RepCount=2; - Verbose=""; - - - - - Page 11 - - - - - - - PARSEARGS(1) PARSEARGS(1) - - - - ARGSPEC=" - 'c', ARGOPT, argInt, RepCount, 'count {# times to repeat}', - 'v', ARGOPT, argBool, Verbose, 'verbose {turn on verbose mode}', - ' ', ARGREQ, argStr, InFile, 'input {file to read from}', - ' ', ARGOPT, argStr, OutFile, 'output {file to write to}', - 'X', ARGHIDDEN, argBool, XRated, 'xrated {naughty! naughty!}', - ' ', ARGOPT|ARGLIST, listStr, Files, 'files {files to process}', - ENDOFARGS - " - eval `echo "$ARGSPEC" | parseargs -s sh -- $0 "$@"` - - - This describes a Bourne shell script accepting up to three - flag arguments and one or two positional arguments, plus a - list of additional file arguments. Only the first - positional argument is required. The possible flags (in - UNIX) are: - - -c count An integer repetition count. This defaults - to two. - - -v A Boolean ``verbose'' flag. It defaults to - FALSE (an empty string). - - -X A Boolean ``X Rated'' flag. This is not - printed in the usage message. - - The two positional arguments are both strings, as is the - final list. If we were to invoke the above script with the - following command line: - cmdname -v input_file output_file file1 file2 - - Then, after invoking parseargs, the following shell - variables would contain the following values: - $RepCount would evaluate to ``2'' - - $Verbose would evaluate to ``TRUE'' - $InFile would evaluate to ``input_file'' - - $OutFile would evaluate to ``output_file'' - $Files would evaluate to ``file1 file2'' - - $XRated would be unset and would evaluate to an empty - string (``''). - - - Now let's present a more complete example. The following - page shows a Bourne shell script which uses parseargs to - parse its command line, echoes the settings of all its - associated command line variables, and then prints its - command usage. - - - - - Page 12 - - - - - - - PARSEARGS(1) PARSEARGS(1) - - - - #!/bin/sh - # test.sh - Bourne shell script to test out the parseargs command! - # - NAME="`basename $0`"; DOT="."; - - ARGUMENTS=" - '?', ARGHIDDEN, argUsage, NULL, 'Help : print usage and exit', - 'S', ARGVALOPT, argStr, string, 'STRing : optional string arg', - 'g', ARGLIST, argStr, groups, 'newsGROUPS : groups to test', - 'r', ARGOPT, argInt, count, 'REPcount <# to repeat each group>', - 'd', ARGOPT, argStr, dirname, 'DIRectory : working directory', - 'x', ARGOPT, argBool, xflag, 'Xflag : turn on X-mode', - 'y', ARGOPT, argUBool, yflag, 'Yflag : turn off Y-mode', - 's', ARGOPT, argChar, sepch, 'SEPchar : field separator', - 'f', ARGLIST, argStr, files, 'files : files to process', - 'n', ARGREQ|ARGPOS, argStr, name, 'name : name to use', - ' ', ARGLIST, argStr, -- , 'argv : any remaining arguments', - ENDOFARGS - " - export ARGUMENTS - - yflag='TRUE' ## set defaults (dir="."; count=1; sepch=',') ## - - ## parse command-line and save assignments in a temporary file ## - parseargs -s sh -e ARGUMENTS -u -- "$NAME" "$@" >/tmp/tmp$$ - if [ $? -ne 0 ] - then rm -f /tmp/tmp$$; exit 2 ## non-zero status (usage given) - fi - - ## evaluate results from parseargs and remove temporary file - $DOT /tmp/tmp$$; rm -f /tmp/tmp$$ - - ## echo the parsed arguments (use defaults if not defined) - echo "ARGUMENTS:" - echo "==========" - echo "Name='$name', Count='${count:-1}'" - echo "XFlag='$xflag', YFlag='$yflag'" - echo "Directory='${dirname:-"."}', SepChar='${sepch:-","}'" - echo "Groups='$groups'" - echo "Files='$files'" - if [ "$string_flag" ] - then string=${string:-"!string arg ommitted on cmd-line!"} - else string="default string" - fi - echo "String='$string'" - echo "New Positional Parameters='$*'" - - parseargs -a "$ARGUMENTS" -U "$NAME" ## print usage ## - - DIAGNOSTICS - Parseargs may exit with one of the following status codes: - - - - - Page 13 - - - - - - - PARSEARGS(1) PARSEARGS(1) - - - - -1 Some type of system error occurred during execution, - causing the program to exit prematurely. - - 0 Normal exit status (no problems were encountered). - - 1 The calling program specified the -#, the -U or the -M - option to parseargs, or specified an argUsage flag on - the command line. Only the appropriate message is - displayed. - - 2 A command line syntax error was encountered by - parseargs. The offending command line argument may have - been intended for either parseargs or for the calling - program. - - 3 The environment variable that was specified with the -e - option is either NULL (has an empty value) or does not - exist. Perhaps the user specified a shell variable - and/or forgot to export it. - - 4 A syntax error was encountered in the argument - specification string that was specified to parseargs. - - FILES - /usr/local/parseargs.pl - This file defines a perl function named parseargs to - parse arguments more conveniently for perl-scripts. The - function is both documented and implemented in this - file. The user should ``require'' this file in his/her - perl-script before invoking the function. - - /usr/local/parseargs.awk - This file defines an awk function named parseargs to - parse arguments more conveniently for awk-scripts. The - function is both documented and implemented in this - file. The user should include this file in his/her - awk-script before invoking the function. - - SEE ALSO - argtype(3), parseargs(3), parsecntl(3) - - CAVEATS - Because of the way argument parsing is implemented under - UNIX, MS-DOS, and OS/2, option arguments which contain a - leading dash (`-') (or whatever the option prefix character - is defined to be) may not be specified as a separate - argument on the command line, it must be part of the same - argument. That is to say that if a program has a -f option - that requires a string argument, then the following: - -f-arg - - will properly assign the string ``-arg'' to the option - - - - Page 14 - - - - - - - PARSEARGS(1) PARSEARGS(1) - - - - whereas the following: - -f -arg - - will be interpreted by parseargs as two option strings: the - first of which (``-f'') is missing a required argument and - the second of which (``-arg'') will most likely be flagged - as an invalid option. - - Similarly, if the user requires an ARGLIST option to take - multiple arguments with leading dashes then the following - method must be used: It is a ``feature'' of parseargs that - ARGLIST arguments are always appended to the current list of - arguments for the given option. Thus, if ``-f'' is an option - taking a list of arguments, then the following are all - equivalent: - -farg1 arg2 - - -f arg1 arg2 - -farg1 -farg2 - - -f arg1 -f arg2 - Hence multiple ``leading dash'' arguments may specified as - follows: - - -f-dash_arg1 -f-dash_arg2 ... - - BUGS - It does not make sense to use any arguments of type argTBool - since parseargs currently has no way of knowing what the - initial value of the variable is. For this reason, argTBool - is not recognized as a valid argument type (even though it - is used by parseargs(3)). By the same token, since the user - cannot create their own arguments types on the fly from a - shell-script, ARGNOVAL is not recognized as a valid argument - flag. - - Commas will not be interpreted properly if any field in the - argument specification string contains double quotes that - are nested inside of double quotes, or single quotes that - are nested inside of single quotes. - - Inside the argument specification string, any repeated - string of commas that does not appear inside of double or - single quotes will be treated as a single comma. - - Text descriptions for argument entries are automatically - formatted in usage messages. Any attempt by the user to - include tabs and/or newlines in the description will cause - it to be formatted improperly. - - Parseargs cannot properly preserve any newlines in shell - variables if the eval command is used to read its output - - - - Page 15 - - - - - - - PARSEARGS(1) PARSEARGS(1) - - - - (this is a shortcoming of the eval command, not of - parseargs). If the user is concerned about this particular - case, then the user should redirect the output from - parseargs to a temporary file and use the source command in - csh or the dot command (`.') in sh and ksh, to interpret the - results; otherwise, newlines will be translated into spaces, - or characters following a newline may be lost, in any - variables that are set by parseargs. - - AUTHOR - Brad Appleton (brad@ssd.csd.harris.com) - Harris Computer Systems, Fort Lauderdale, FL USA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Page 16 - - - --- 0 ---- diff -cNr ../patchlevel4/parseargs3.txt ./parseargs3.txt *** ../patchlevel4/parseargs3.txt Thu May 2 11:06:45 1991 --- ./parseargs3.txt Wed Dec 31 18:00:00 1969 *************** *** 1,1254 **** - - - - PARSEARGS(3) PARSEARGS(3) - - - - NAME - parseargs - parse command line argument vectors - - SYNOPSIS - #include <parseargs.h> - - int parseargs( char *argv[], ARGDESC *argd ); - int fparseargs( FILE *fp, ARGDESC *argd ); - int lparseargs( ArgList *argls, ARGDESC *argd ); - int sparseargs( char *str, ARGDESC *argd ); - int vparseargs( ARGDESC *argd, int argc, ... ); - void usage( const ARGDESC *argd ); - extern const char *ProgName; - - DESCRIPTION - Given a vector of string-valued arguments such as that - passed to main and a vector describing the possible argu- - ments, parseargs matches actual arguments to possible argu- - ments, converts values to the desired type, and diagnoses - problems such as missing arguments, extra arguments, and - argument values that are syntactically incorrect. - - Given a readable input stream and an argdesc array, fpar- - seargs will parse arguments in a file in the same manner as - parseargs. A maximum-line length of 255 characters is - imposed. NO ``escaping'' of any kind is performed. Comments - of a limited form are permitted: if the first non-whitespace - character on a line is a '#' (or '!' for VMS) then that - entire line is considered a comment and is ignored. If a - value is provided for an argument that is NOT a list or a - vector, then the value MUST be on the same line as the argu- - ment (in other words, ``-v val'' is fine but ``-v\nval'' is - a not). - - Given an ArgList and an argdesc array, lparseargs will parse - arguments in an ArgList in the same manner as parseargs. - - Given a single string and an argdesc array, sparseargs will - parse arguments from a string in much the manner as par- - seargs. Sparseargs will split the given string up into a - vector of whitespace separated tokens and then attempt to - parse the resultant vector as if it were given as argv[] on - the command-line. NO special treatment is given to charac- - ters such as single-quotes, double-quotes, or anything else. - Sparseargs will always assume that any whitespace characters - are intended as argument separators. - - Vparseargs takes an argdesc array, the number of arguments - to parse, and a (possibly NULL terminated) list of - argument-strings and parses them in the same manner as par- - seargs. Unlike sparseargs, vparseargs assumes that all - parameters are already split up into tokens, hence any - - - - Page 1 - - - - - - - PARSEARGS(3) PARSEARGS(3) - - - - whitespace characters contained in any of the string- - parameters are used as is (and will be considered a part of - an argument name or value). - - Given an argdesc array, usage will print the usage for the - given command in the format specified by the user's - USAGECNTL environment variable. - - After returning from any of the aforementioned functions, - the global string ProgName will contain the name of the com- - mand corresponding to the argument-descriptor array that was - most recently operated upon by one the functions in the par- - seargs(3) function library. - - THE ARGUMENT STRUCTURE - The basic type used by the parseargs library is the argument - descriptor (or "argdesc" for short). An ARGDESC structure is - used to describe a command-line argument. Each command line - argument contains various fields which need to be set and/or - queried by the programmer. The individual fields of an - ARGDESC structure are desribed below: - - char ad_name; - This is a single character which corresponds to the - option-letter (case-sensitive) from the command-line - that matches the argument described by this structure. - Positional-arguments are denoted by putting a a space - character in this field. - - argMask_t ad_flags; - This field contains the various bitflags that describe - the semantics of this argument. See the ARGUMENT FLAGS - section for more information on the possible combina- - tions of bitmasks for this field. - - argTypePtr_t ad_type; - This field is a pointer to a type conversion function - (such as the ones provided in argtype(3)). The type - conversion function is responsible for verifying the - validity of the argument, allocating any necessary - storage for its internal representation, and converting - the command-line argument into its required internal - form. The type conversion function used may be one of - the pre-defined argtype(3) functions. The function is - given three parameters: The first is a pointer to the - ARGDESC struct in question, the second is the string- - value (if any) supplied on the command-line, and the - third is a boolean value that is TRUE only if the - second parameter points to temporary storage (and hence - may need to be copied). In the case of parseargs(1) - this field must correspond to the name of one of the - argument type functions described in argtype(3). - - - - Page 2 - - - - - - - PARSEARGS(3) PARSEARGS(3) - - - - ARBPTR ad_valp; - This field is a generic pointer to the storage used to - represent the internal value of the command-line argu- - ment. It may be a pointer to a number, a boolean value, - a string, a list, or anything else for which there - exists a corresponding arg-type function to use in the - ad_type field. In the case of of parseargs(1) this - field must be the name of the corresponding shell vari- - able which will eventually hold the value of the argu- - ment given on the command-line. - - const char *ad_prompt; - This field contains the long-name of the argument and - an optional description (the description must be - separated from the long-name by at least one whitespace - character and may optionally be enclosed in a set of - balanced delimiters (such as parentheses, curly-braces, - square-brackets, or angle-brackets). If the long-name - contains any uppercase characters, then the substring - of long-name consisting of all uppercase characters is - used as the argument keyword and the entire long-name - is used as the name of the argument (if a value may be - supplied). The long-name may be matched by supplying a - unique prefix of either the argument keyword or the - argument name. - - DEFINING ARGDESC ARRAYS - When defining an argdesc array, the first item in the list - should be the item STARTOFARGS. Normal arguments (defined by - the programmer) may then be specified as documented in this - manual. The list of arguments is terminated using - ENDOFARGS. - - For example, consider the description: - int RepCount = 2; - BOOL Verbose = FALSE; - char *InFile; - char *OutFile = CHARNULL; - BOOL XRated = FALSE; - ArgList *Files = ARGLISTNULL; - - ARGDESC Args[] = - { - STARTOFARGS, - 'c', ARGOPT, argInt, __ &RepCount, "REPcount {# of repetitions}", - 'v', ARGOPT, argBool, __ &Verbose, "Verbose {set verbose mode}", - ' ', ARGREQ, argStr, __ &InFile, "INPUTfile {input file}", - ' ', ARGOPT, argStr, __ &OutFile, "OUTPUTfile {output file}", - 'X', ARGHIDDEN, argBool, __ &XRated, "XratedMODE {naughty stuff!}", - ' ', ARGLIST, listStr, __ &Files, "File {files to be read}", - ENDOFARGS - }; - - - - Page 3 - - - - - - - PARSEARGS(3) PARSEARGS(3) - - - - This describes a program accepting up to three flag argu- - ments and one or two positional arguments, plus a list of - additional file arguments. Only the first positional argu- - ment is required. The possible flags (in UNIX) are: - - -c count An integer repetition count. This defaults to - two. - - -v A Boolean ``verbose'' flag. It defaults to FALSE. - - -X A Boolean ``X Rated'' flag. This is not printed - in the usage message. - - The two positional arguments are both strings, as is the - final list. In AmigaDOS, the options would be REP count, V, - and XMODE. In VAX/VMS, the qualifiers would be /REP=count, - /V, and /XMODE. - - ARGUMENT FLAGS - These are the possible bitmasks that may be turned ON or OFF - in the ad_flags field of an ARGDESC structure. - - ARGOPT - This flag is actually a dummy flag (i.e. it is the - default). This flag specifies that the command-line - argument is optional (need not appear on the command- - line). It is only needed if no other flags are used to - define the given argument. If other flags are given - and ARGREQ is NOT one of them, then ARGOPT is always - assumed. - - ARGREQ - The associated command argument is required on the - command-line. - - ARGPOS - The associated command argument is positonal. The - difference between using this flag to indicate a posi- - tional argument and between using a blank in the - ad_name field to indicate a positional arguments is the - following: If this flag is set but the ad_name of the - argument is non-blank, then this argument may be - matched either positionally or by keyword. If the - ad_name field is blank, then this argument may only be - matched positionally. - - ARGNOVAL - The associated command argument takes no value (as in - "-x value"); Its mere presence (or lack thereof) on the - command-line is sufficient to determine the necessary - action(s) to take (as in "-x"). Boolean argument types - and Pseudo-argument types automatically default to - - - - Page 4 - - - - - - - PARSEARGS(3) PARSEARGS(3) - - - - ARGNOVAL. - - ARGVALOPT - This flag is used to indicate that the command-line - argument takes a value (as in "-s string" or - "/str=string") but that the value to this command-line - argument is NOT required (hence simply "-s" or "/str" - is also permissable). - - ARGVALREQ - Another "dummy" flag. Unless ARGNOVAL or ARGVALOPT is - specified, ARGVALREQ is always assumed. This flag indi- - cates that the value to a command-line argument is - required (hence "-s string" is okay but just "-s" is - not). - - ARGHIDDEN - Don't display this argument in usage messages but still - attempt to match it against strings given on the - command-line. - - ARGLIST - A variable number of values are used for this argument - (and hence may use more than one or two argv elements - from the command-line as in "-l val1 val2 ..."). The - list of values must be stored in an ArgList structure - (NOT a vector structure), an the corresponding - argument-type function should be one of the listXxxx - functions. - - ARGVEC - A variable number of values are used for this argument - (and hence may use more than one or two argv elements - from the command-line as in in "-v val1 val2 ..."). The - list of values must be stored in a vector structure - (NOT an ArgList structure). - - The following bitmasks may also be present, but, unlike the - above masks which must be specified by the programmer at - initialization time, the following masks must only be read - (never set) by the programmer. They may be queried by using - the pc_ARGFLAGS function code and the mode pc_READ with par- - secntl(3). - - ARGGIVEN - The argument WAS given on the command-line. - - ARGVALGIVEN - The value for this argument was given on the command- - line. - - ARGVALSEP - - - - Page 5 - - - - - - - PARSEARGS(3) PARSEARGS(3) - - - - The value to this argument was supplied in a separate - argv element from the argument itself (as in "-x value" - as opposed to "-xvalue"). - - ARGKEYWORD - This argument was matched as a keyword (long-form) on - the command-line and not as a single character. - - ARGDESCRIBED - This argument was given a description by the programmer - at initialization. - - ARGCOPYF - This flag is only used for lists and vectors (mul- - tivalued arguments) and is used on a per-item basis. If - it is set, it means that the corresponding value in the - vector/list required space to be allocated (such as the - duplication of a temporary string). - - ARGDESC MACROS - The following macros are used to extract and query the - attributes of a pointer to a preprocessed arg-descriptor: - - arg_cname(ad) - Return the single-character name of an argument. - - arg_flags(ad) - Return the argument flags of an argument. The flags - themselves may be manipulated using the BTEST, BSET, - and BCLEAR macros defined in <useful.h>. - - arg_type(ad) - Return the pointer to the value-translation-routine of - an argument. - - arg_valp(ad) - Return the pointer to the value of this argument. - - arg_sname(ad) - Return the string name of an argument. - - arg_sdesc(ad) - Return the description of an argument. If a description - was supplied, the ARGDESCRIBED flag will be set and the - description will immediately follow the terminating - NULL byte of the string name. - - ARG_isDESCRIBED(ad) - Evaluates to TRUE only if an argument description was - provided. - - arg_description(ad) - - - - Page 6 - - - - - - - PARSEARGS(3) PARSEARGS(3) - - - - Return the description string (or an empty string if no - description was given) for this argument. - - ARG_isPOSITIONAL(ad) - Evaluates to TRUE if this argument may be positionally - matched. - - ARG_isPOSONLY(ad) - Evaluates to TRUE if this argument may only be posi- - tionally matched. - - ARG_isLIST(ad) - Evaluates to TRUE if this argument is an arglist. - - ARG_isVEC(ad) - Evaluates to TRUE if this argument is a vector. - - ARG_isMULTIVAL(ad) - Evaluates to TRUE if this argument is an arglist or a - vector. - - ARG_isVALTAKEN(ad) - Evaluates to TRUE if this argument does NOT take a - value. - - ARG_isGIVEN(ad) - Evaluates to TRUE if this argument was given on the - command-line. - - ARG_isVALGIVEN(ad) - Evaluates to TRUE if the argument value was given on - the command-line. - - ARG_isREQUIRED(ad) - Evaluates to TRUE if this argument is required. - - ARG_isVALOPTIONAL(ad) - Evaluates to TRUE if the argument value is optional. - - ARG_isVALSEPARATE(ad) - Evaluates to TRUE if the argument value is optional. - - ARG_isHIDDEN(ad) - Evaluates to TRUE if this argument is omitted from - usage messages. - - CMD MACROS - <parseargs.h> defines a set of macros to allow a more "self - documenting" approach to declaring argument-descriptor - arrays. The "old-style" is still accepted (but if used it is - recommended that the STARTOFARGS macro is used in conjunc- - tion with ENDOFARGS). An example use of these macros - - - - Page 7 - - - - - - - PARSEARGS(3) PARSEARGS(3) - - - - (which, with one exception, all begin with ``CMD'') follows: - #include <parseargs.h> - - static BOOL bflag = FALSE; - static char *arg1 = CHARNULL; - static char *arg2 = CHARNULL; - - static - CMD_OBJECT - MyCmd - - CMD_NAME - "mycmd -- one line statement of purpose" - - CMD_DESCRIPTION - "Mycmd will try really really hard to run without errors \ - and do whatever the heck it is supposed to do. If (God forbid) \ - something should actually go wrong it will say so." - - CMD_ARGUMENTS - 'H', ARGOPT, argUsage, __ NULL, - "Help -- display usage and quit", - - 'b', ARGOPT, argSBool, __ &bflag, - "bflag -- turn on `b'-mode (whatever that is)", - - ' ', ARGREQ, argStr, __ &arg1, - "arg1 -- first argument to this spiffy program", - - ' ', ARGOPT, argStr, __ &arg2, - "arg2 -- optional second argument to this spiffy program", - - END_ARGUMENTS - CMD_END - - main( int argc, char *argv[] ) - { - (void) parseargs( argv, MyCmd ); - (void) dostuff(); - exit( 0 ); - } - - DEFAULT ARGUMENT DESCRIPTOR - Each argdesc-array has an initial default argument list - (which may be reset using the pc_DEFARGS function code with - parsecntl). This initial default argument-list contains `?' - and `H' which may be used as single character keywords to - display command-usage for all command-line styles. Simi- - larly, ``?'', ``H'', and ``Help'' may be used as long- - keywords to display command-usage for all command-line - styles. In Addition, for VMS style commands, the qualifiers - /INPUT=file, /OUTPUT=file, and /ERROR=file, may be used to - - - - Page 8 - - - - - - - PARSEARGS(3) PARSEARGS(3) - - - - redirect stdin, stdout, and stderr (respectively) to a file. - For AmigaDOS style commands, the keyword ``ENDKWDS'' may be - used to disable parsing for any more keywords on the - command-line. - - SUPPLYING DEFAULT ARGUMENTS - Programs that use parseargs may be given default arguments - under UNIX and PCs through the use of environment variables - (symbols are used for VMS systems). If a C-program or - shell-script uses parseargs to implement a command named - ``cmd'' then the environment variable ``CMD_ARGS'' will be - parsed for any "default" arguments before the command-line - is parsed. The command-line will over-ride any options that - are specified in this environment variable (except that - ARGLISTs and ARGVECs set in ``CMD_ARGS'' will be appended - from the command-line if they are selected). - - It is important to note that the contents of the - ``CMD_ARGS'' environment variable are NOT expanded by the - shell and hence any special characters (such as quotes or - back-slashes) will NOT be escaped or removed by parseargs. - Furthermore, it will not be possible to try and use a tab, - space, or newline character in the environment variable as - anything other than an argument separator. - - Lastly, parts of an option specification in ``CMD_ARGS'' may - NOT be continued on the command-line. As an example, if -f - requires an argument and CMD_ARGS="-f", then the command- - line "cmd bah" will NOT assign "bah" as the argument to -f - but will instead complain about a missing argument for -f. - Similarly, if -l takes a list of arguments and CMD_ARGS="-l - item1 item2", then the command-line "cmd bah", will NOT - assign "bah" to the end of the list containing "item1" and - "item2" but will instead treat "bah" as the first positional - parameter on the command-line. - - PARSING BEHAVIOR - The programmer may control parsing behavior through the use - of parsecntl(3). The user may set his (or her) own desired - parsing behavior through the use of the ``PARSECNTL'' - environment variable. By indicating any number of flags - (possibly negated) the user will directly modify the - behavior of the parseargs library. Flags may be combined by - placing a `+' or `|' character in between flags. A switch is - negated by immediately preceding it with a `!' or `-' char- - acter. The possible ``flags'' are given by the following - table. Flags are case-insensitive. - - Prompt - 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 - - - - Page 9 - - - - - - - PARSEARGS(3) PARSEARGS(3) - - - - arguments that expect a list of values will be repeat- - edly prompted for (one item per line) until a blank - line (followed by a carriage return) is entered. - - Ignore - Ignore any unrecognized or improperly specified - command-line arguments and continue execution of the - program. Normally, if a required argument is unmatched - (or an argument is improperly specified), a usage mes- - sage is printed program execution is terminated. - - OptsOnly - 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). - - KwdsOnly - Under UNIX, setting this flag disables the parsing of - single-character options. This will cause all argu- - ments starting with `-' to always be treated as a posi- - tional parameter (instead of an option). - - LoptsOnly - Same as KwdsOnly. - - Flags1st - 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 posi- - tional arguments (the -x option will be unmatched). - - If this flag is UNSET, then both of the previous exam- - ples are considered to consist of one option and one - positional argument. - - CaseIgnore - Setting this flag will cause character-case to be - ignored when attempting to match single-character argu- - ment names (i.e. causes "-i" and "-I" to be considered - equivalent). - - If the environment variable ``PARSECNTL'' is empty or unde- - fined, then the parsing behavior set by the programmer is - used. If the programmer has not explicitly used par- - secntl(3) to modify the parsing behavior, then the default - behavior will be ``Flags1st'' for Unix systems, ``!Prompt + - !Ignore'' for AmigaDOS systems, ``CaseIgnore'' for MS-DOS - - - - Page 10 - - - - - - - PARSEARGS(3) PARSEARGS(3) - - - - and OS/2 systems, and ``Prompt'' for VMS systems. - - USAGE MESSAGES - Through the use of an environment variable (or a VMS sym- - bol), the user may control the syntax and the verbosity of - the command-usage messages that are printed by parseargs. - The desired level of verbosity may be set by defining the - environment variable ``USAGECNTL" to be a combination of - strings (case insensitive). The value of each string con- - trols one of three different ``modes'' of behavior in the - displaying of usage messages: The first ``mode'' is ``ver- - bose'' mode, which controls whether or not a detailed - description of each argument should accompany the usual - command-line sysnopsis. If verbose mode is ``off'', then - only a command-line synopsis is printed (this is also ref- - ferred to as ``terse'' mode). The other two ``modes'' con- - trol the displaying of option syntax and long-option syntax. - A mode may be explicitly disabled by preceding its - corresponding string with the `!' or `-' character. The - ``modes'' which correspond to the possible values of the - ``USAGECNTL'' environment variable are given by the follow- - ing table. - - Quiet - No usage message of any kind is displayed. - - Silent - Same as Quiet. - - Paged - The usage message is piped to a pager. The pager used - is named by the ``USAGE_PAGER'' environment variable. - If this variable is unset or empty (or is not the name - of an executable program) then the pager named by the - ``PAGER'' environment variable us used. If this vari- - able is unset or empty (or is not the name of an exe- - cutable program) then /usr/ucb/more is used. - - Description - The command description is printed. - - Terse - Terse mode, just print command-line synopsis. - - Verbose - Verbose mode, print descriptions for each argument - - Options - Option syntax is displayed. - - LongOpts - Long-option syntax is displayed. - - - - Page 11 - - - - - - - PARSEARGS(3) PARSEARGS(3) - - - - KeyWords - Same as LongOpts. - - If the environment variable ``USAGECNTL'' is empty or unde- - fined, then the default usage level (which is presently - ``Verbose + Options'') will be used. - - MULTI-VALUED ARGUMENTS - Parseargs supports two different types of multi-valued argu- - ments: linked-lists and vectors. The linked-lists are called - argument lists (or arg-lists) and are specified by supplying - the ARGLIST flag along with an associated listXxxx - argument-translation routine. The value associated with an - arg-list should be a list structure of type ArgList. The - include file <parseargs.h> defines four macros for manipu- - lating ArgList structures: ARGLISTNULL, L_NEXT, L_STRING, - and L_FLAGS. - - ARGLISTNULL is simply the NULL argument-list pointer. - L_NEXT and L_STRING each take a pointer to a non-NULL - ArgList structure. L_NEXT returns the address of the next - item in the list and L_STRING returns the string-value of - the current list-item. L_FLAGS return the arg-flags for a - given item in the list. With non-multivalued arguments, only - the flags in the argument descriptor are needed; lists and - vectors however need a set of flags for each item they con- - tain. Once an arg-list has been created, it may be deallo- - cated using the function listFree. ListFree takes one param- - eter: the address of the first item in the arg-list. - - An alternative to argument-lists is argument vectors (or - arg-vectors). Arg-vectors use the ARGVEC flag instead of - the ARGLIST flag and do not require a special listXxxx func- - tion for each vector-type. Each of the argXxxx functions is - responsible for handling vectors of its type (although some - argXxx functions such as the boolean types do not support - vectors). An arg-vector is a structure which contains a - count, an array of elements (i.e. an argc,argv pair), and an - array of flags, one for each element of argv. There are two - macros in defined in <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 - - - - Page 12 - - - - - - - PARSEARGS(3) PARSEARGS(3) - - - - 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 vecFree or the macro vecDeepFree and passing it the - arg-vector structure. The differemce between these two mac- - ros is that the latter will also free each item in the vec- - tor that required space to be allocated (at the expense of - traversing the vector). At this writing, the only prede- - fined argument-types 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=%x\n", - i, L_STRING(ls), L_FLAGS(ls) ); - - for ( i = 0 ; i < StrVec.count ; i++ ) - printf( "String[%d]=%s, flags=%x\n", - i, StrVec.array[i], StrVec.flags[i] ); - - for ( i = 0 ; i < NumVec.count ; i++ ) - - - - Page 13 - - - - - - - PARSEARGS(3) PARSEARGS(3) - - - - printf( "Number[%d]=%s, flags=%x\n", - i, NumVec.array[i], NumVec.flags[i] ); - - listFree( StrList ); - StrList = ARGLISTNULL; - - vecDeepFree( StrVec, char * ); - vecFree( NumVec, int ); - - exit( 0 ); - } - - - ARGUMENT TYPE FUNCTIONS - The argument types recognized by parseargs can be extended - by adding new type functions. Argument type functions are - declared as: - - BOOL argXxx( ARGDESC *ad, char *vp, BOOL copyf ) - - The ad argument points to the descriptor for the argument - being converted. Its main use is to find the location in - which to store the converted value, located in ad->ad_valp. - The string value to be converted is passed in vp (which will - be NULL if the ARGNOVAL flag was set for the corresponding - entry in the arg-descriptor table). The copyf flag is TRUE - if the vp string value must be copied when saved. Most - non-string types are copied implicitly (for example, integer - arguments are stored in binary form, so the original string - value need not be saved), so this argument can usually be - ignored. Put simply, this flag is TRUE when vp points to a - temporary buffer area. - - If the type function successfully converts the value, and - uses the entire value, it should return TRUE. If the type - function successfully converts the value, and uses only N - characters of the value, it should return -N. Otherwise, it - should print a message using usrerr(3) and return FALSE. - This message should be of the form "invalid xxxx option - 'yyyy' for Zzzz", where xxxx is the type of the option, yyyy - is the string passed in vp, and zzzz is the name (taken from - ad->ad_prompt). The argXxxx function is responsible for - detecting if the given argument descriptor is an ARGVEC - argument and for taking the appropriate action. - - For example, a type function that took a filename and stored - an open file pointer might be coded as: - - #define REALLOC(ptr,size) ((! ptr) ? malloc(size) : realloc(ptr, size)) - typedef ARGVEC_T(FILE *) FILEvec_t; - - BOOL argReadFile( ARGDESC *ad, char *vp, BOOL copyf ) - - - - Page 14 - - - - - - - PARSEARGS(3) PARSEARGS(3) - - - - { - register FILE *fp; - fp = fopen(vp, "r"); - - if ( ! fp ) { - usrerr("cannot open '%s' for reading", vp); - return (FALSE); - } - if ( BTEST(arg_flags(ad), ARGVEC) ) { - FILEvec_t *vec = (FILEvec_t *) arg_valp(ad); - size_t size = (1 + vec->count) * (sizeof (FILE *)); - - vec->array = (FILE **) REALLOC(vec->array, size); - if ( ! vec->array ) - syserr( "(m|re)alloc failed in argReadFile" ); - vec->flags = (FILE **) REALLOC(vec->flags, size); - if ( ! vec->flags ) - syserr( "(m|re)alloc failed in argReadFile" ); - - vec->flags[ vec->count ] = arg_flags(ad); - vec->array[ (vec->count)++ ] = fp; - } - else - *(FILE *) arg_valp(ad) = fp; - return (TRUE); - } - - LONG OPTIONS - Under UNIX, MS-DOS, and OS/2, parseargs also allows for long - options in addition to single character options. Under - UNIX, long options are denoted by a `+' character. Under - MS-DOS, and OS/2, long options are denoted by the second - character in the SWITCHAR environment variable. If there is - no second character, then if the first character is `-', - then a `+' is used, otherwise a `/' is used. The keyword - that is used is the first word in the prompt field of an - argument descriptor entry. Long options are case insensi- - tive! Under UNIX, an argument to a long option may be - separated from the long option by an equal sign (`=') or by - one or more whitespace characters. Thus, if an entry looks - like: - - then ``-c4'', ``+repcount=4'', ``+count=4'', ``+rep- - count 4'', and ``+count 4'' will all have the same effect. - - The long option names for ``-?'' in the default argument - descriptor are ``+help'' and ``+?'' (respectively). In addi- - tion, ``++'' may be used to indicate the end of options so - that all remaining arguments will be interpreted as posi- - tional parameters (even if one begins with a `+' or a `-'). - - - - - - Page 15 - - - - - - - PARSEARGS(3) PARSEARGS(3) - - - - Under MS-DOS, and OS/2, an argument to a long-option must be - separated from the long option by an equal sign (`=') - (unless the first character of $SWITCHAR is a `-', in which - case UNIX syntax is used). The long option names for ``/?'' - in the default argument descriptor are ``/help'' and ``/?'' - (respectively). - - Under VAX/VMS and AmigaDOS, single-character options are not - used and the ``long'' name (in the prompt field of an argu- - ment descriptor) is always used to match for possible argu- - ments (or keywords, or qualifiers). - - For all supported operating systems, a long option may be - matched in one of two ways: it may match all uppercase char- - acters in the prompt field, or it may match all characters - in the prompt field (as in ``+count=4'' and ``+rep- - count=4''). - - Under all systems except AmigaDOS, only the number of char- - acters required to uniquely identify the desired argument - are needed, but at least two characters must be given - (unless the prompt field is itself less than two characters - long). This means that using the above example, that - ``+rep=4'' and ``+cou=4'' would also work but ``+c=4'' would - NOT (in other words, if you only want to use one character, - use ``-c4'' instead). - - Under VAX/VMS, the possibilities using the above example - would be: ``/REPCOUNT=4'', ``/COUNT=4'', ``/REP=4'', and - ``/COU=4'', - - Under AmigaDOS, no ``shortened'' keywords are accepted and - the possibilities using the above example would be: ``REP- - COUNT 4'', and ``COUNT 4'' - - RETURN VALUE - The functions in the parseargs library will return a value - of zero upon succesful completion. They may however, return - any of the following status codes (which are defined in - <parseargs.h>): - - pe_SYSTEM - A system error occurred. The global variable errno may - indicate the problem (then again, it may not). - - pe_SUCCESS - Success, no errors encountered (zero is returned). - - pe_SYNTAX - A command-line syntax error was encountered - - pe_DEFARGS - - - - Page 16 - - - - - - - PARSEARGS(3) PARSEARGS(3) - - - - An attempt (using parsecntl) was made to change the - default arg-search list of a command to point to an - argdesc-array which already has the given command on - its default arg-search list (which would cause an - infinite loop when attempting to match an unknown - command-line argument). - - pe_NOMATCH - Unable to match the named argument. This occurs when - the argument keyword name passed to parsecntl (using - the pc_ARGFLAGS functions code) was found in the given - argdesc-array or in its default-list. - - pe_BADMODE - Bad mode for given command in parsecntl. This occurs - when pc_WRITE or pc_RDWR mode is passed to parsecntl in - conjunction with the pc_ARGFLAGS functions code. Par- - secntl will not modify existing arguments. - - pe_BADCNTL - Bad command for parsecntl. This occurs if an unknown - function-code was passed to parsecntl. - - SIDE EFFECTS - Each of the functions in the parseargs library will set the - external character string ProgName to be the name of the - last command that was operated upon by any of the library - routines. - - When an argument-descriptor array is first encountered by - any of the parseargs library routines, it is initially com- - piled into an intermediate form that is more convenient to - manipulate. As a direct result, it is not advisable to - attempt to index directly into the array to manipulate one - of the argument descriptors (because the argdesc that you - thought was there may actually be somewhere else). After the - array has been given its initial value(s), only parsecntl(3) - should be used to manipulate or query the attributes of an - argument descriptor. - - DOCUMENTING YOUR COMMANDS - The commands that you write with parseargs(3) may be docu- - mented using parseargs(1). Just copy the argument descriptor - array into a separate file, and invoke parseargs(1) with the - -M option and pass it the command-name (dont forget to - redirect input to come from your newly created file). It is - important to note that the only portion of that argdesc - array to insert into your file is the portion starting with - the very first command-line argument, all the way down to - (and including) the ENDOFARGS or END_ARGUMENTS entry. - - - - - - Page 17 - - - - - - - PARSEARGS(3) PARSEARGS(3) - - - - FILES - /usr/local/lib/libparse.a - Link library for parseargs. - - /usr/local/include/parseargs.h - Include file for parseargs. - - /usr/local/include/useful.h - Include file for portability. - - SEE ALSO - argtype(3), parseargs(1), parsecntl(3) - The ``C Advisor'' column in UNIX Review Vol. 7 No. 11. - - CAVEATS - Because of the way argument parsing is implemented under - UNIX, MS-DOS, and OS/2, option arguments which contain a - leading dash (`-') (or whatever the option prefix character - is defined to be) may not be specified as a separate argu- - ment on the command line, it must be part of the same argu- - ment. That is to say that if a program has a -f option that - requires a string argument, then the following: - -f-arg - - will properly assign the string ``-arg'' to the option - whereas the following: - -f -arg - - will be interpreted by parseargs as two option strings: the - first of which (``-f'') is missing a required argument and - the second of which (``-arg'') will most likely be flagged - as an invalid option. - - Similarly, if the user requires an ARGLIST option to take - multiple arguments with leading dashes then the following - method must be used: It is a ``feature'' of parseargs that - ARGLIST arguments are always appended to the current list of - arguments for the given option. Thus, if ``-f'' is an option - taking a list of arguments, then the following are all - equivalent: - -farg1 arg2 - - -f arg1 arg2 - -farg1 -farg2 - - -f arg1 -f arg2 - Hence multiple ``leading dash'' arguments may specified as - follows: - - -f-dash_arg1 -f-dash_arg2 ... - - - - - - Page 18 - - - - - - - PARSEARGS(3) PARSEARGS(3) - - - - BUGS - When a non-multivalued argument appears more than once on - the command-line then only the last value supplied is used. - A problem occurs however in the following scenario: suppose - `-s' is an option that takes an optional string argument - (and suppose `-x' is some boolean flag). Then if the follow- - ing command-line is issued: - - command -s string -x -s - - then, the argument flags will properly correspond to the - second instance of the `-s' option (namely ARGGIVEN will be - set but ARGVALGIVEN will be unset) but the value associated - with the option will be ``string'' (because the first - instance overwrote the default). Because of this, it may be - safest to reassign the default value if ARGGIVEN is set but - ARGVALGIVEN is unset. - - AUTHOR - Eric Allman, University of California, Berkeley - - MODIFICATIONS - Modified to accept a vector of arguments, better error mes- - sages, Unix keyword matching, and AmigaDOS version by Peter - da Silva. - - Rewritten by Brad Appleton. Parseargs(1); functions par- - secntl, sparseargs, fparseargs, lparseargs, and vparseargs; - argument types argUsage, argDummy, argUBool, and argTBool; - argument flags ARGPOS, ARGVALOPT, ARGVALREQ, ARGVALGIVEN, - ARGNOVAL, and ARGVEC; and VAX/VMS version and IBM-PC version - by Brad Appleton - - - - - - - - - - - - - - - - - - - - - - - - Page 19 - - - --- 0 ---- diff -cNr ../patchlevel4/parsecntl3.txt ./parsecntl3.txt *** ../patchlevel4/parsecntl3.txt Thu May 2 11:06:46 1991 --- ./parsecntl3.txt Wed Dec 31 18:00:00 1969 *************** *** 1,594 **** - - - - PARSECNTL(3) PARSECNTL(3) - - - - NAME - parsecntl - get and set attributes of an argument descriptor - array - - SYNOPSIS - #include <parseargs.h> - - int parsecntl( ARGDESC argd[], parsecntl_t func, parsemode_t mode, ... ); - - - DESCRIPTION - Parsecntl will read and/or write the desired attributes of - the given command-object. The attributes to be operated upon - are specified by the second parameter to parsecntl. The - desired mode (read, write, or both) are specified by the - third parameter to parsecntl. If the operation to be per- - formed is pc_ARGFLAGS, then the fourth argument to parsecntl - should be the keyword name of the argument whose flags are - to be retrieved. The last parameter to parsecntl is always - the object to contain the attribute(s) to be read/written. - If the attribute(s) are to be read (regardless of whether or - not they are also being changed) then the last argument - should be a pointer to an object, otherwise the last argu- SHAR_EOF true || echo 'restore of PATCH05 failed' fi echo 'End of part 4' echo 'File PATCH05 is continued in part 5' echo 5 > _shar_seq_.tmp exit 0 exit 0 # Just in case... -- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM Sterling Software, IMD UUCP: uunet!sparky!kent Phone: (402) 291-8300 FAX: (402) 291-4362 Please send comp.sources.misc-related mail to kent@uunet.uu.net.