brad@hcx1.ssd.csd.harris.com (Brad Appleton) (03/18/91)
Submitted-by: Brad Appleton <brad@hcx1.ssd.csd.harris.com> Posting-number: Volume 17, Issue 53 Archive-name: parseargs/part08 This is part 8 of parseargs #!/bin/sh # this is Part.08 (part 8 of a multipart archive) # do not concatenate these parts, unpack them in order with /bin/sh # file parseargs/parseargs1.txt continued # if test ! -r _shar_seq_.tmp; then echo 'Please unpack part 1 first!' exit 1 fi (read Scheck if test "$Scheck" != 8; 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/parseargs1.txt' else echo 'x - continuing file parseargs/parseargs1.txt' sed 's/^X//' << 'SHAR_EOF' >> 'parseargs/parseargs1.txt' && X or characters following a newline may be lost, in any X variables that are set by parseargs. X X Parseargs(1) is subject to the same caveats as parseargs(3). X Refer to the CAVEATS section of the parseargs(3) manual X page(s) for more information. X AUTHOR X Brad Appleton (brad@ssd.csd.harris.com) X Harris Computer Systems, Fort Lauderdale, FL USA X X X X X X X X X X X X X Page 15 X X X SHAR_EOF echo 'File parseargs/parseargs1.txt is complete' && chmod 0664 parseargs/parseargs1.txt || echo 'restore of parseargs/parseargs1.txt failed' Wc_c="`wc -c < 'parseargs/parseargs1.txt'`" test 33378 -eq "$Wc_c" || echo 'parseargs/parseargs1.txt: original size 33378, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= parseargs/parseargs3.txt ============== if test -f 'parseargs/parseargs3.txt' -a X"$1" != X"-c"; then echo 'x - skipping parseargs/parseargs3.txt (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting parseargs/parseargs3.txt (Text)' sed 's/^X//' << 'SHAR_EOF' > 'parseargs/parseargs3.txt' && X X X PARSEARGS(3) PARSEARGS(3) X X X NAME X parseargs, usage - parse command line argument vectors X SYNOPSIS X #include <parseargs.h> X X int parseargs( char *argv[], ARGDESC *argd ) X int fparseargs( FILE *fp, ARGDESC *argd ) X int lparseargs( ArgList *argls, ARGDESC *argd ) X int sparseargs( char *str, ARGDESC *argd ) X int vparseargs( ARGDESC *argd, ... ) X void usage( const ARGDESC *argd ) X DESCRIPTION X Given a vector of string-valued arguments such as that X passed to main and a vector describing the possible argu- X ments, parseargs matches actual arguments to possible argu- X ments, converts values to the desired type, and diagnoses X problems such as missing arguments, extra arguments, and X argument values that are syntactically incorrect. X X Given a readable input stream and an argdesc array, fpar- X seargs will parse arguments in a file in much the same X manner as parseargs. A maximum-line length of 255 charac- X ters is imposed. NO ``escaping'' of any kind is performed. X Comments of a limited form are permitted: if the first non- X whitespace character on a line is a '#' (or '!' for VMS) X then that entire line is considered a comment and is X ignored. If a value is provided for an argument that is NOT X a list or a vector, then the value MUST be on the same line X as the argument (in other words, ``-v val'' is fine but X ``-v\nval'' is a not). X X Given an ArgList and an argdesc array, lparseargs will parse X arguments in a file in much the same manner as parseargs. X X Given a single string and an argdesc array, sparseargs will X parse arguments from a string in much the same manner as X parseargs. Sparseargs will split the given string up into a X vector of whitespace separated tokens and then attempt to X parse the resultant vector as if it were given as argv[] on X the command-line. NO special treatment is given to charac- X ters such as single-quotes, double-quotes, or anything else. X Sparseargs will always assume that any whitespace characters X are intended as argument separators. X X X Vparseargs takes an argdesc array, the number of arguments X to parse, and a (possibly NULL terminated) list of X argument-strings and parses them in much the same manner as X parseargs. Unlike sparseargs, vparseargs assumes that all X parameters are already split up into tokens, hence any X X X Page 1 X X X X X X PARSEARGS(3) PARSEARGS(3) X X X X whitespace characters contained in any of the string- X parameters are used as is (and will be considered a part of X an argument name or value). X X X Given an argdesc array, usage will print the usage for the X given command in the format specified by the user's X USAGECNTL environment variable. X THE ARGUMENT STRUCTURE X The basic type used by the parseargs library is the argument X descriptor (or "argdesc" for short). An ARGDESC structure is X used to describe a command-line argument. Each command line X argument contains various fields which need to be set and/or X queried by the programmer. The individual fields of an X ARGDESC structure are desribed below: X X char ad_name; X This is a single character which corresponds to the X option-letter (case-sensitive) from the command-line X that matches the argument described by this structure. X Positional-arguments are denoted by putting a a space X character in this field. X X argMask_t ad_flags; X This field contains the various bitflags that describe X the semantics of this argument. See the ARGUMENT FLAGS X section for more information on the possible combina- X tions of bitmasks for this field. X X argTypePtr_t ad_type; X This field is a pointer to a type conversion function X (such as the ones provided in argtype(3). The type X conversion function is responsible for verifying the X validity of the argument, allocating any necessary X storage for its internal representation, and converting X the command-line argument into its required internal X form. The type conversion function used may be one of X the pre-defined argtype(3) functions. The function is X given three parameters: The first is a pointer to the X ARGDESC struct in question, the second is the string- X value (if any) supplied on the command-line, and the X third is a boolean value that is TRUE only if the X second parameter points to temporary storage (and hence X may need to be copied). In the case of parseargs(1) X this field must correspond to the name of one of the X argument type functions described in argtype(3). X X ARBPTR ad_valp; X This field is a generic pointer to the storage used to X represent the internal value of the command-line argu- X ment. It may be a pointer to a number, a boolean value, X X X Page 2 X X X X X X PARSEARGS(3) PARSEARGS(3) X X X X a string, a list, or anything else for which there X exists a corresponding arg-type function to use in the X ad_type field. In the case of of parseargs(1) this X field must be the name of the corresponding shell vari- X able which eventually hold the value of the argument X given on the command-line. X X const char *ad_prompt; X This field contains the long-name of the argument and X an optional description (the description must be X separated from the long-name by at least one whitespace X characters and may optionally be enclosed in a set of X balanced delimiters (such as parentheses, curly-braces, X square-brackets, or angle-brackets. If the long-name X contains any uppercase characters, then the substring X of long-name consisting of all uppercase characters is X used as the argument name and the entire long-name is X used as the name of the argument-value (if a value my X be supplied). The long-name may be matched by supplying X a unique prefix of either the argument name or the X argument-value name. X DEFINING ARGDESC ARRAYS X When defining an argdesc array, the first item in the list X should be the item STARTOFARGS. Normal arguments (defined by X the programmer) may then be specified as documented in this X manual. The list of arguments is terminated using X ENDOFARGS. X X For example, consider the description: X int RepCount = 2; X BOOL Verbose = FALSE; X char *InFile; X char *OutFile = CHARNULL; X BOOL XRated = FALSE; X struct namelist *Files = NULL; X X ARGDESC Args[] = X { X STARTOFARGS, X 'c', ARGOPT, argInt, __ &RepCount, "REPcount {# of repetitions}", X 'v', ARGOPT, argBool, __ &Verbose, "Verbose {set verbose mode}", X ' ', ARGREQ, argStr, __ &InFile, "INPUTfile {input file}", X ' ', ARGOPT, argStr, __ &OutFile, "OUTPUTfile {output file}", X 'X', ARGHIDDEN, argBool, __ &XRated, "XratedMODE {naughty stuff!}", X ' ', ARGOPT|ARGLIST, argStr, __ &Files, "File {files to be read}", X ENDOFARGS X }; X X This describes a program accepting up to three flag argu- X ments and one or two positional arguments, plus a list of X additional file arguments. Only the first positional X X X Page 3 X X X X X X PARSEARGS(3) PARSEARGS(3) X X X X argument is required. The possible flags (in UNIX) are: X X -c count An integer repetition count. This defaults to X two. X X -v A Boolean ``verbose'' flag. It defaults to FALSE. X X -X A Boolean ``X Rated'' flag. This is not printed X in the usage message. X X The two positional arguments are both strings, as is the X final list. In AmigaDOS, the options would be REP count, V, X and XMODE. In VAX/VMS, the qualifiers would be /REP=count, X /V, and /XMODE. X ARGUMENT FLAGS X These are the possible bitmasks that may be turned ON or OFF X in the ad_flags field of an ARGDESC structure. X X ARGOPT X This flag is actually a dummy flag (i.e. it is the X default). This flag specifies that the command-line X argument is optional (need not appear on the command- X line). It is only needed if no other flags are used to X define the given argument. If other flags are given X and ARGREQ is NOT one of them, then ARGOPT is always X assumed. X X ARGREQ X The associated command argument is required on the X command-line. X X ARGPOS X The associated command argument is positonal. The X difference between using this flag to indicate a posi- X tional argument and between using a blank in the X ad_name field to indicate a positional arguments is the X following: If this flag is set but the ad_name of the X argument is non-blank, then this argument may be X matched either positionally or by keyword. If the X ad_name field is blank, then this argument may only be X matched positionally. X X ARGNOVAL X The associated command argument takes no value (as in X "-x value"); Its mere presence (or lack thereof) on the X command-line is sufficient to determine the necessary X action(s) to take (as in "-x"). Boolean argument types X and Pseudo-argument types automatically default to ARG- X NOVAL. X X ARGVALOPT X X X Page 4 X X X X X X PARSEARGS(3) PARSEARGS(3) X X X X This flag is used to indicate that the command-line X argument takes a value (as in "-s string" or X "/str=string") but that the value to this command-line X argument is NOT required (hence simply "-s" or "/str" X is also permissable). X X ARGVALREQ X Another "dummy" flag. Unless ARGNOVAL or ARGVALOPT is X specified, ARGVALREQ is always assumed. This flag indi- X cates that the value to a command-line argument is X required (hence "-s string" is okay but just "-s" is X not). X X ARGHIDDEN X Don't display this argument in usage messages but still X attempt to match it against strings given on the X command-line. X X ARGLIST X A variable number of values are used for this argument X (and hence may use more than one or two argv elements X from the command-line as in "-l val1 val2 ..."). The X list of values must be stored in an ArgList structure X (NOT a vector structure), an the corresponding X argument-type function should be one of the listXxxx X functions. X X ARGVEC X A variable number of values are used for this argument X (and hence may use more than one or two argv elements X from the command-line as in in "-v val1 val2 ..."). The X list of values must be stored in a vector structure X (NOT an ArgList structure). X X The following bitmasks may also be present, but, unlike the X above masks which must be specified by the programmer at X initialization time, the following masks must only be read X (never set) by the programmer. They may be queried by using X the pc_ARGFLAGS function code and the mode pc_READ with par- X secntl(3). X X ARGGIVEN X The argument WAS given on the command-line. X X ARGVALGIVEN X The value for this argument was given on the command- X line. X X ARGVALSEP X The value to this argument was supplied in a separate X argv element from the argument itself (as in "-x value" X as opposed to "-xvalue"). X X X Page 5 X X X X X X PARSEARGS(3) PARSEARGS(3) X X X X ARGKEYWORD X This argument was matched as a keyword (long-form) on X the command-line and not as a single character. X X ARGDESCRIBED X This argument was given a description by the programmer X at initialization. X X ARGCOPYF X This flag is only used for lists and vectors (mul- X tivalued arguments) and is used on a per-item basis. If X it is set, it means that the corresponding value in the X vector/list required space to be allocated (such as the X duplication of a temporary string). X ARGDESC MACROS X The following macros are used to extract and query the X attributes of a pointer to a preprocessed arg-descriptor: X X arg_cname(ad) X Return the single-character name of an argument. X X arg_flags(ad) X Return the argument flags of an argument. The flags X themselves may be manipulated using the BTEST, BSET, X and BCLEAR macros defined in <useful.h>. X X arg_type(ad) X Return the pointer to the value-translation-routine of X an argument. X X arg_valp(ad) X Return the pointer to the value of this argument. X X arg_sname(ad) X Return the string name of an argument. X X arg_sdesc(ad) X Return the description of an argument. If a description X was supplied, the ARGDESCRIBED flag will be set and the X description will immediately follow the terminating NUL X byte of the string name. X X ARG_isDESCRIBED(ad) X Evaluates to TRUE only if an argument description was X provided. X X arg_description(ad) X Return the description string (or an empty string if no X description was given) for this argument. X X ARG_isPOSITIONAL(ad) X X X Page 6 X X X X X X PARSEARGS(3) PARSEARGS(3) X X X X Evaluates to TRUE if this argument may be positionally X matched. X X ARG_isPOSONLY(ad) X Evaluates to TRUE if this argument may only be posi- X tionally matched. X X ARG_isLIST(ad) X Evaluates to TRUE if this argument is an arglist. X X ARG_isVEC(ad) X Evaluates to TRUE if this argument is a vector. X X ARG_isMULTIVAL(ad) X Evaluates to TRUE if this argument is an arglist or a X vector. X X ARG_isVALTAKEN(ad) X Evaluates to TRUE if this argument does NOT take a X value. X X ARG_isGIVEN(ad) X Evaluates to TRUE if this argument was given on the X command-line. X X ARG_isVALGIVEN(ad) X Evaluates to TRUE if the argument value was given on X the command-line. X X ARG_isREQUIRED(ad) X Evaluates to TRUE if this argument is required. X X ARG_isVALOPTIONAL(ad) X Evaluates to TRUE if the argument value is optional. X X ARG_isVALSEPARATE(ad) X Evaluates to TRUE if the argument value is optional. X X ARG_isHIDDEN(ad) X Evaluates to TRUE if this argument is omitted from X usage messages. X CMD MACROS X Parseargs.h defines a set of macros to allow a more "self X documenting" approach to declaring argument-descriptor X arrays. The "old-style" is still accepted (but if used it is X recommended that the STARTOFARGS macro is used in conjunc- X tion with ENDOFARGS). An example use of these macros X (which, with one exception, all begin with ``CMD'') follows: X #include <parseargs.h> X X static BOOL bflag = FALSE; X X X Page 7 X X X X X X PARSEARGS(3) PARSEARGS(3) X X X X static char *arg1 = CHARNULL; X static char *arg2 = CHARNULL; X X static X CMD_OBJECT X MyCmd X X CMD_NAME X "mycmd -- one line statement of purpose" X X CMD_DESCRIPTION X "Mycmd will try really really hard to run without errors \ X and do whatever the heck it is supposed to do. If (God forbid) \ X something should actually go wrong it will say so." X X CMD_ARGUMENTS X 'H', ARGOPT, argUsage, __ NULL, X "Help -- display usage and quit", X X 'b', ARGOPT, argSBool, __ &bflag, X "bflag -- turn on `b'-mode (whatever that is)", X X ' ', ARGREQ, argStr, __ &arg1, X "arg1 -- first argument to this spiffy program", X X ' ', ARGOPT, argStr, __ &arg2, X "arg2 -- optional second argument to this spiffy program", X X END_ARGUMENTS X CMD_END X X main( int argc, char *argv[] ) X { X (void) parseargs( argv, MyCmd ); X (void) dostuff(); X exit( 0 ); X } X DEFAULT ARGUMENT DESCRIPTOR X Each argdesc-array has an initial default argument list X (which may be reset using the pc_DEFARGS function code with X parsecntl). This initial default argument-list contains `?' X and `H' which may be used as single character keywords to X display command-usage for all command-line styles. Simi- X larly, ``?'', ``H'', and ``Help'' may be used as long- X keywords to display command-usage for all command-line X styles. In Addition, for VMS style commands, the qualifiers X /INPUT=file, /OUTPUT=file, and /ERROR=file, may be used to X redirect stdin, stdout, and stderr (respectively) to a file. X For AmigaDOS style commands, the keyword ``ENDKWDS'' may be X used to disable parsing for any more keywords on the X command-line. X X X Page 8 X X X X X X PARSEARGS(3) PARSEARGS(3) X X 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 (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 `-' char- X acter. The possible ``flags'' are given by the following X 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 argu- X ments that expect a list of values will be repeatedly X prompted for (one item per line) until a blank line X (followed by a carriage return) is entered. X X Ignore X X X Page 9 X X X X X X PARSEARGS(3) PARSEARGS(3) X X X 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 pro- X gram 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 argu- X ments starting with '-' to always be treated as a posi- X tional 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 posi- X tional arguments (the -x option will be unmatched). X X If this flag is UNSET, then both of the previous exam- X ples are considered to consist of one option and one X positional argument. X X CaseIgnore 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 unde- X fined, then parsing behavior set by the programmer is used. X If the programmer has not explicitly used parsecntl(3) to X modify the parsing behavior will be ``!Prompt + !Ignore'' X for Unix MS-DOS, OS/2, and AmigaDOS systems, and ``Prompt'' X for VMS systems. X USAGE MESSAGES X Through the use of an environment variable (or a VMS sym- X bol), the user may control the syntax and the verbosity of X the command-usage messages that are printed by parseargs. X X X Page 10 X X X X X X PARSEARGS(3) PARSEARGS(3) X X X 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 con- X trols one of three different ``modes'' of behavior in the X displaying of usage messages: The first ``mode'' is ``ver- X bose'' 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 ref- X ferred to as ``terse'' mode). The other two ``modes'' con- X trol the displaying of option syntax and long-option syntax. X 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 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 vari- X able is unset or empty (or is not the name of an exe- X cutable program) then /usr/ucb/more is used. X X Description X The command description is printed. X X Terse 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 X If the environment variable ``USAGECNTL'' is empty or unde- X fined, then the default usage level (which is presently X X X Page 11 X X X X X X PARSEARGS(3) PARSEARGS(3) X X X X ``Verbose + Options'') will be used. X MULTI-VALUED ARGUMENTS X Parseargs supports two different types of multi-valued argu- X ments: linked-lists and vectors. The linked-lists are called X argument lists (or arg-lists) and are specified by supplying X the ARGLIST flag along with an associated listXxxx X argument-translation routine. The value associated with an X arg-list should be a list structure of type ArgList. The X include file <parseargs.h> defines four macros for manipu- X lating ArgList structures: ARGLISTNULL, L_NEXT, L_STRING, X and L_FLAGS. X X ARGLISTNULL is simply the NULL argument-list pointer. X L_NEXT and L_STRING each take a pointer to a non-NULL X ArgList structure. L_NEXT returns the address of the next X item in the list and L_STRING returns the string-value of X the current list-item. L_FLAGS return the arg-flags for a X given item in the list. With non-multivalued, only the flags X in the argument descriptor are needed; lists and vectors X however need a set of flags for each item they contain. Once X an arg-list has been created, it may be deallocated using X the function listFree. ListFree takes two parameters, the X first of which is the address of the first item in the arg- X list, and the second of which is a boolean value that is X TRUE only if each value pointed to by each item should also X be deallocated. X X An alternative to argument-lists is argument vectors (or X arg-vectors). Arg-vectors use the ARGVEC flag instead of X the ARGLIST flag and do not require a special listXxxx func- X tion for each vector-type. Each of the argXxxx functions is X responsible for handling vectors of its type (although some X argXxx functions such as the boolean types do not support X vectors). An arg-vector is a structure which contains a X count, an array of elements (i.e. an argc/argv pair), and an X array of flags, one for each element of argv. There are two X macros in defined in <parseargs.h> which are used for arg- X vectors. ARGVEC_T may be used to declare a vector structure X or a vector type; ARGVEC_EMPTY may be used to initialize the X structure. It is strongly recommended that ARGVEC_T be used X to declare vector types in a typedef statement (particularly X if one is using function prototypes) but for those who X insist, it may be used to directly declare a structure. X String-vectors will always have an extra NULL-pointer at the X end such that: X X ( StrVec.array[ StrVec.count ] == (char *)NULL ) X X is always true, and character-vectors will always have an X extra NUL-character at the end such that: X X X X Page 12 X X X X X X PARSEARGS(3) PARSEARGS(3) X X X X ( CharVec.array[ CharVec.count ] == '\0' ) X X is always true. Integer and floating point vectors contain X no extra "null" elements. X X Once created, arg-vectors may be deallocated by calling the X macro vecFree or the macro vecDeepFree and passing it the X arg-vector structure. The differemce between these two mac- X ros is that the latter will also free each item in the vec- X tor that required space to be allocated (at the expense of X traversing the vector). At this writing, the only prede- X fined argument-types that would benefit from vecDeepFree is X argStr vectors. X X An example use of arg-lists, and of arg-vectors follows: X X #include <parseargs.h> X X typedef ARGVEC_T(char *) strvec_t; X X static ArgList *StringList = ARGLISTNULL; X static strvec_t StringVec = ARGVEC_EMPTY(char *); X static ARGVEC_T(int) NumberVec = ARGVEC_EMPTY(int); X X static X CMD_OBJECT Args X CMD_NAME "foo -- do whatever foo does" X CMD_DESCRIPTION "put a brief paragraph here" X CMD_ARGUMENTS X 'l', ARGLIST, listStr, __ &StrList, "LiSt {list of strings}", X 's', ARGVEC, argStr, __ &StrVec, "STRing {vector of strings}", X 'i', ARGVEC, argInt, __ &NumVec, "NUMber {vector of numbers}", X END_ARGUMENTS X CMD_END X X main( int argc, char *argv[] ) X { X int i, *ls; X X if ( parseargs(argv, Args) ) syserr( "parseargs failed" ); X X for ( ls = StrList, i=1 ; ls ; ls = L_NEXT(ls), i++ ) X printf( "List item %d=%s, flags=%x\n", X i, L_STRING(ls), L_FLAGS(ls) ); X X for ( i = 0 ; i < StrVec.count ; i++ ) X printf( "String[%d]=%s, flags=%x\n", X i, StrVec.array[i], StrVec.flags[i] ); X X for ( i = 0 ; i < NumVec.count ; i++ ) X printf( "Number[%d]=%s, flags=%x\n", X i, NumVec.array[i], NumVec.flags[i] ); X X X Page 13 X X X X X X PARSEARGS(3) PARSEARGS(3) X X X X listFree( StrList ); X StrList = ARGLISTNULL; X X vecDeepFree( StrVec, char * ); X vecFree( NumVec, int ); X X exit( 0 ); X } X X ARGUMENT TYPE FUNCTIONS X The argument types recognized by parseargs can be extended X by adding new type functions. Argument type functions are X declared as: X X BOOL argXxx( ARGDESC *ad, char *vp, BOOL copyf ) X X The argd argument points to the descriptor for the argument X being converted. Its main use is to find the location in X which to store the converted value, located in X argd->ad_valp. The string value to be converted is passed X in argp (which will be NULL if the ARGNOVAL flag was set for X the corresponding entry in the arg-descriptor table). The X copyf flag is TRUE if the argp string value must be copied X when saved. Most non-string types are copied implicitly X (for example, integer arguments are stored in binary form, X so the original string value need not be saved), so this X argument can usually be ignored. Put simply, this flag is X TRUE when argp points to a temporary buffer area. X X If the type function successfully converts the value, and X uses the entire value, it should return TRUE. If the type X function successfully converts the value, and uses only N X characters of the value, it should return -N. Otherwise, it X should print a message using usrerr(3) and return FALSE. X This message should be of the form "invalid xxxx option X 'yyyy' for Zzzz", where xxxx is the type of the option, yyyy X is the string passed in vp, and zzzz is the name (taken from X ad->ad_prompt). The argXxxx function is responsible for X detecting if the given argument descriptor is an ARGVEC X argument and for taking the appropriate action. X X For example, a type function that took a filename and stored X an open file pointer might be coded as: X X #define REALLOC(ptr,size) ((! ptr) ? malloc(size) : realloc(ptr, size)) X typedef ARGVEC_T(FILE *) FILEvec_t; X X BOOL argReadFile( ARGDESC *ad, char *vp, BOOL copyf ) X { X register FILE *fp; X fp = fopen(vp, "r"); X X X Page 14 X X X X X X PARSEARGS(3) PARSEARGS(3) X X X X if ( ! fp ) { X usrerr("cannot open '%s' for reading", vp); X return (FALSE); X } X if ( BTEST(arg_flags(ad), ARGVEC) ) { X FILEvec_t *vec = (FILEvec_t *) arg_valp(ad); X size_t size = (1 + vec->count) * (sizeof (FILE *)); X X vec->array = (FILE **) REALLOC(vec->array, size); X if ( ! vec->array ) X syserr( "(m|re)alloc failed in argReadFile" ); X vec->flags = (FILE **) REALLOC(vec->flags, size); X if ( ! vec->flags ) X syserr( "(m|re)alloc failed in argReadFile" ); X X vec->flags[ vec->count ] = arg_flags(ad); X vec->array[ (vec->count)++ ] = fp; X } X else X *(FILE *) arg_valp(ad) = fp; X return (TRUE); X } X LONG OPTIONS X Under UNIX, Parseargs also allows for long options in addi- X tion to single character options. Long options are denoted X by a `+' character (which may be changed using keywordpre- X fix). The keyword that is used is the first word in the X prompt field of an argument descriptor entry. Long options X are case insensitive! An argument to a long option may be X separated from the long option by an equal sign (`=') or by X one or more whitespace characters. Thus, if an entry looks X like: X X then ``-c4'', ``+repcount=4'', ``+count=4'', ``+rep- X count 4'', and ``+count 4'' will all have the same effect. X X The long option names for ``-?'' in the default argument X descriptor are ``+help'' and ``+?'' (respectively). In addi- X tion, ``++'' or ``+endopts'' may be used to indicate the end X of options so that all remaining arguments will be inter- X preted as positional parameters (even if one begins with a X `+' or a `-'). X X Under VAX/VMS and AmigaDOS, single-character options are not X used and the ``long'' name (in the prompt field of an argu- X ment descriptor) is always used to match for possible argu- X ments (or keywords, or qualifiers). X X For all supported operating systems, a long option may be X matched in one of two ways: it may match all uppercase char- X acters in the prompt field, or it may match all characters X X X Page 15 X X X X X X PARSEARGS(3) PARSEARGS(3) X X X X in the prompt field (as in ``+count=4'' and ``+rep- X count=4''). X X Under UNIX and VAX/VMS, only the number of characters X required to uniquely identify the desired argument are X needed, but at least two characters must be given (unless X the prompt field is itself less than two characters long). X This means that using the above example, that ``+rep=4'' and X ``+cou=4'' would also work but ``+c=4'' would NOT (in other X words, if you only want to use one character, use ``-c4'' X instead). X X Under VAX/VMS, the possibilities using the above example X would be: ``/REPCOUNT=4'', ``/COUNT=4'', ``/REP=4'', and X ``/COU=4'', X X Under AmigaDOS, no ``shortened'' keywords are accepted and X the possibilities using the above example would be: ``REP- X COUNT 4'', and ``COUNT 4'' X RETURN VALUE X The functions in the parseargs library will return a value X of zero upon succesful completion. They may however, return X any of the following status codes (which are defined in X <parseargs.h>): X X pe_SYSTEM X A system error occurred. The global variable errno may X indicate the problem (then again, it may not). X X pe_SUCCESS X Success, no errors encountered (zero is returned). X X pe_SYNTAX X A command-line syntax error was encountered X X pe_DEFARGS X An attempt (using parsecntl) was made to change the X default arg-search list of a command to point to an X argdesc-array which already has the given command on X its default arg-search list (which would cause an X infinite loop when attempting to match an unknown X command-line argument). X X pe_NOMATCH X Unable to match the named argument. This occurs when X the argument keyword name passed to parsecntl (using X the pc_ARGFLAGS functions code) was found in the given X argdesc-array or in its default-list. X X pe_BADMODE X Bad mode for given command in parsecntl. This occurs X X X Page 16 X X X X X X PARSEARGS(3) PARSEARGS(3) X X X X when pc_WRITE or pc_RDWR mode is passed to parsecntl in X conjunction with the pc_ARGFLAGS functions code. Par- X secntl will not modify existing arguments. X X pe_BADCNTL X Bad command for parsecntl. This occurs if an unknown X function-code was passed to parsecntl. X SEE ALSO X argtype(3), parseargs(1), syserr(3) X The ``C Advisor'' column in UNIX Review Vol. 7 No. 11. 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 argu- X ment on the command line, it must be part of the same argu- X ment. That is to say that if a program has a -f option that X 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 BUGS X When a non-multivalued argument appears more than once on X the command-line then only the last value supplied is used. X X X Page 17 X X X X X X PARSEARGS(3) PARSEARGS(3) X X X X A problem occurs however in the following scenario: suppose X `-s' is an option that takes an optional string argument (nd X suppose `-x' is some boolean flag). Then if the following X command-line is issued: X X command -s string -x -s X X then, the argument flags will properly correspond to the X second instance of the `-s' option (namely ARGGIVEN will be X set but ARGVALGIVEN will be unset) but the value associated X with the option will be ``string'' (because the first X instance overwrote the default). Because of this, it may be X safest to reassign the default value if ARGGIVEN is set but X ARGVALGIVEN is unset. X AUTHOR X Eric Allman, University of California, Berkeley X MODIFICATIONS X Modified to accept a vector of arguments, better error mes- X sages, Unix keyword matching, and AmigaDOS version by Peter X da Silva. X X Rewritten by Brad Appleton. Parseargs(1); functions par- X secntl, sparseargs, fparseargs, lparseargs, and vparseargs; X argument types argUsage, argDummy, argUBool, and argTBool; X argument flags ARGPOS, ARGVALOPT, ARGVALREQ, ARGVALGIVEN, X ARGNOVAL, and ARGVEC; and VAX/VMS version and IBM-PC version X by Brad Appleton X X X X X X X X X X X X X X X X X X X X X X X X X X Page 18 X X X SHAR_EOF chmod 0664 parseargs/parseargs3.txt || echo 'restore of parseargs/parseargs3.txt failed' Wc_c="`wc -c < 'parseargs/parseargs3.txt'`" test 37108 -eq "$Wc_c" || echo 'parseargs/parseargs3.txt: original size 37108, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= parseargs/parsecntl3.txt ============== if test -f 'parseargs/parsecntl3.txt' -a X"$1" != X"-c"; then echo 'x - skipping parseargs/parsecntl3.txt (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting parseargs/parsecntl3.txt (Text)' sed 's/^X//' << 'SHAR_EOF' > 'parseargs/parsecntl3.txt' && X X X PARSECNTL(3) PARSECNTL(3) X X X NAME X parsecntl - get and set attributes of an argument descriptor X array X SYNOPSIS X #include <parseargs.h> X X int parsecntl( ARGDESC argd[], parsecntl_t func, parsemode_t mode, ... ) X X DESCRIPTION X Parsecntl will read and/or write the desired attributes of X the given command-object. The attributes to be operated upon X are specified by the second parameter to parsecntl. The X desired mode (read, write, or both) are specified by the X third parameter to parsecntl. If the operation to be per- X formed is pc_ARGFLAGS, then the fourth argument to parsecntl X should be the keyword name of the argument whose flags are X to be retrieved. The last parameter to parsecntl is always X the object to contain the attribute(s) to be read/written. X If the attribute(s) are to be read (regardless of whether or X not they are also being changed) then the last argument X should be a pointer to an object, otherwise the last argu- X ment should be the object itself. X X If mode is pc_READ, then the desired attributes are copied X into the object pointed to by the last parameter. If the X mode is pc_WRITE, then the attributes from the last parame- X ter are copied to the command- object. If mode is pc_RDWR, X then the attributes pointed to by the last parameter are X copied to the command-object, and then the previous value of X these attributes (before they were overwritten) is copied X into the object pointed to by the last parameter. X X If cntl is pc_ARGFLAGS, then the only valid mode is pc_READ. X All other attributes may be written or read by parsecntl. X FUNCTION CODES X Each of the following function codes specifies an attribute X that is to be manipulated by parsecntl. The function code X is the second parameter to parsecntl. With the exception of X pc_ARGFLAGS, each of the function codes corresponds to a X call to parsecntl using four parameters ( pc_ARGFLAGS uses 5 X parameters). In each case, the last parameter is either the X address of a buffer to write the attribute to, or the actual X buffer to read the attribute from (depending upon the mode - X the third parameter to parsecntl). X X pc_PARSEFLAGS X This function code is used to read and/or modify the X existing parsing parsing behavior. The fourth parameter X to parsecntl should be a combination of pc_XXXX X X X Page 1 X X X X X X PARSECNTL(3) PARSECNTL(3) X X X X bitmasks if the parse-flags are only being written, X otherwise it should be a pointer to an argMask_t vari- X able. X X pc_ARGFLAGS X This function code may only be used to read the X argument-flags of a named argument. It is an error to X specify a mode that attempts to write the argument- X flags with this function code. The fourth parameter to X parsecntl should be the keyword name of the argument X whose flags are to be read. The fifth (and final) argu- X ment should be a pointer to the argMask_t variable X which will receive the resulting argument-flags. X X pc_DEFARGS X This function code is used to query or modify the X current default argument-descriptor list for the given X command. The fourth parameter to parsecntl should be X the argument-descriptor array to assign as the new X default-list (or the address of an argdesc-array if the X default list is being retrieved). X X If a given option/qualifier does not appear to match X any items in the argdesc-array, a default argdesc- X array is then searched to match the option. If it is X STILL unmatched then it is flagged as such. The X default-argdesc array is automatically used by all X programmer-defined argdesc-array but may be unset or X reset using the pc_DEFARGS function of parsecntl. In X such a manner, a programmer could specify a different X set of default-arguments to search for. Furthermore, X default argdesc-arrays may also be assigned default X argdesc-arrays, thus allowing the programmer to define X a whole search-list of default argdesc-arrays for a X given command. X X This could prove useful in a situation where a set of X commands have a few common-options and differ in their X remaining ones. If the same main() were used for each X command, then main could define one common argdesc- X array and then a set of argdesc-arrays for each com- X mand. Main could then figure out which argdesc-array to X used based on the name in argv[0], and set its default X argdesc-array to be the common argdesc-array, as in the X following: X X #include <parseargs.h> X . X . variable declarations X . X X static ARGDESC common_args[] = { X X X Page 2 X X X X X X PARSECNTL(3) PARSECNTL(3) X X X X STARTOFARGS, X { 'L', ARGOPT, argBool, __ &lflag, "list (list the items)" }, X { 'I', ARGOPT, argStr, __ &item, "item (item to use)" }, X ENDOFARGS X }; X X static ARGDESC cmd1_args[] = { X STARTOFARGS, X { 's', ARGOPT, argBool, __ &sflag, "S (set S)" }, X { 't', ARGOPT, argBool, __ &tflag, "T (set T)" }, X ENDOFARGS X }; X X static ARGDESC cmd2_args[] = { X STARTOFARGS, X { 'x', ARGOPT, argBool, __ &xflag, "X (set X)" }, X { 'y', ARGOPT, argBool, __ &yflag, "Y (set Y)" }, X ENDOFARGS X }; X X main( int argc, char *argv[] ) X { X ARGDESC *cmd = cmd1_args; X int rc; X X if ( strcmp(*argv, "cmd2") == 0 ) X cmd = cmd2_args; X X rc = parsecntl( cmd, pc_DEFARGS, pc_WRITE, common_args ); X if ( rc != pe_SUCCESS ) X syserr( "unable to set default args" ); X X rc = parseargs( argv, cmd ); X . X . X . X } X X Note that in the above call to parsecntl(3), that zero X will be returned upon success and non-zero upon X failure. If pe_DEFARGS is returned, then cmd is already X on common_args's list of defaults (and would result in X an infinite loop while parsing). X X pc_NAME X X pc_PURPOSE X X pc_DESCRIPTION X Each of these last three function codes are used to X modify or query the name, purpose, or description asso- X ciated with a command. The fourth parameter to X X X Page 3 X X X X X X PARSECNTL(3) PARSECNTL(3) X X X X parsecntl should be the new string to use (or the X address of the string, a char** variable, to recieve X the current value). X PARSE MODES X Parsecntl may be used to read current command attributes, X write (assign) new command attributes, or both. The mode X argument to parsecntl determines the which of these three X alternatives are desired. If the programmer merely wishes to X assign new attributes, then invoking parsecntl in pc_WRITE X mode and passing the new attributes will do the job. If the X programmer wishes simply to query attributes, then invoking X parsecntl in pc_READ mode and passing a pointer to the X desired object in which to write the attribute settings will X suffice. X X If the programmer wishes to assign new attributes and at the X same time find out what the attributes were before making X the assignment, then programmer must invoke parsecntl for X pc_RDWR mode and pass a pointer to the object containing the X new attribute settings; When parsecntl returns, then (assum- X ing it returns 0) the desired attributes will have been X assigned and the object that contained the new attribute X settings will now contain the attribute settings that were X in effect before parsecntl was invoked. X PARSE FLAGS X The following bitmasks may be combined in order to modify X the behavior of the parseargs library. The parse flags for a X given may be set through the use of the parsecntl(3) func- X tion. X X pa_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 argu- X ments that expect a list of values will be repeatedly X prompted for (one item per line) until a blank line X (followed by a carriage return) is entered. X X pa_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 pro- X gram execution is terminated. X X pa_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 X Page 4 X X X X X X PARSECNTL(3) PARSECNTL(3) X X X X pa_KWDSONLY X Under UNIX, setting this flag disables the parsing of X single-character options. This will cause all argu- X ments starting with `-' to always be treated as a posi- X tional parameter (instead of an option). X X pa_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 posi- X tional arguments (the -x option will be unmatched). X X If this flag is UNSET, then both of the previous exam- X ples are considered to consist of one option and one X positional argument. X X pa_ANYCASE X Setting this flag will cause character-case to be X ignored when attempting to match single-character argu- X ment names (i.e. causes "-i" and "-I" will be con- X sidered equivalent). X X pa_ARGV0 X Normally, the parseargs library will assume that the X first argument on the command-line is the name of the X command. Setting this flag tells parseargs that this is X NOT the case and that the very first argument on the X command-line is a bona-fide argument to the command. X X pa_NOCHECK X Setting this flag will prevent parseargs from checking X for any required arguments that were not given on the X command-line. This is useful when more than one call to X the parseargs library is needed to parse all the X command-line arguments (which could occur if the X command-line argument came from a file or from two X argv-vectors). X X Keeping this flag on until the final set of arguments X is parsed will cause parseargs to not check for missing X arguments until the last set of arguments has been X parsed (by the final call to *parseargs). X X pa_CONTINUE X Setting this flag will cause subsequent calls to the X parseargs library to NOT reset the current command- X state. Hence, all arguments will not be initially set X to "NOT GIVEN" and other (normal) initializations are X X X Page 5 X X X X X X PARSECNTL(3) PARSECNTL(3) X X X X not be performed. This is useful in conjunction with X the pa_NOCHECK flag when more than one call to par- X seargs is required to parse all the command arguments. X In this scenario, pa_CONTINUE should be unset (the X default setting) for the very first call to parseargs, X but should then be set before any subsequent calls to X parseargs are made. X X pa_NOCMDENV X Setting this flag prevents parseargs from checking the X CMD-NAME_ARGS environment variable (or symbol) for any X user-defined default command arguments. X X pa_COPYF X When this flag is OFF (the default), a value of FALSE X is provided as the copyf argument to all the arg-type X (argXxxxx) functions when an argument is matched. Set- X ting this flag will cause a value of TRUE to be pro- X vided as the copyf argument to all the arg-type X (argXxxxx) functions when an argument is matched. X ARGUMENT FLAGS X These are the possible bitmasks that may be turned ON or OFF X in the ad_flags field of an ARGDESC structure. X X ARGOPT X This flag is actually a dummy flag (i.e. it is the X default). This flag specifies that the command-line X argument is optional (need not appear on the command- X line). It is only needed if no other flags are used to X define the given argument. If other flags are given X and ARGREQ is NOT one of them, then ARGOPT is always X assumed. X X ARGREQ X The associated command argument is required on the X command-line. X X ARGPOS X The associated command argument is positonal. The X difference between using this flag to indicate a posi- X tional argument and between using a blank in the X ad_name field to indicate a positional arguments is the X following: If this flag is set but the ad_name of the X argument is non-blank, then this argument may be X matched either positionally or by keyword. If the X ad_name field is blank, then this argument may only be X matched positionally. X X ARGNOVAL X The associated command argument takes no value (as in X "-x value"); Its mere presence (or lack thereof) on the X X X Page 6 X X X X X X PARSECNTL(3) PARSECNTL(3) X X X X command-line is sufficient to determine the necessary X action(s) to take (as in "-x"). Boolean argument types X and Pseudo-argument types automatically default to ARG- X NOVAL. X X ARGVALOPT X This flag is used to indicate that the command-line X argument takes a value (as in "-s string" or X "/str=string") but that the value to this command-line X argument is NOT required (hence simply "-s" or "/str" X is also permissable). X X ARGVALREQ X Another "dummy" flag. Unless ARGNOVAL or ARGVALOPT is X specified, ARGVALREQ is always assumed. This flag indi- X cates that the value to a command-line argument is X required (hence "-s string" is okay but just "-s" is X not). X X ARGHIDDEN X Don't display this argument in usage messages but still X attempt to match it against strings given on the X command-line. X X ARGLIST X A variable number of values are used for this argument X (and hence may use more than one or two argv elements X from the command-line as in "-l val1 val2 ..."). The X list of values must be stored in an ArgList structure X (NOT a vector structure), an the corresponding X argument-type function should be one of the listXxxx X functions. X X ARGVEC X A variable number of values are used for this argument X (and hence may use more than one or two argv elements X from the command-line as in in "-v val1 val2 ..."). The X list of values must be stored in a vector structure X (NOT an ArgList structure). X X The following bitmasks may also be present, but, unlike the X above masks which must be specified by the programmer at X initialization time, the following masks must only be read X (never set) by the programmer. They may be queried by using X the pc_ARGFLAGS function code and the mode pc_READ with par- X secntl(3). X X ARGGIVEN X The argument WAS given on the command-line. X X ARGVALGIVEN X The value for this argument was given on the command- X X X Page 7 X X X X X X PARSECNTL(3) PARSECNTL(3) X X X X line. X X ARGVALSEP X The value to this argument was supplied in a separate X argv element from the argument itself (as in "-x value" X as opposed to "-xvalue"). X X ARGKEYWORD X This argument was matched as a keyword (long-form) on X the command-line and not as a single character. X X ARGDESCRIBED X This argument was given a description by the programmer X at initialization. X X ARGCOPYF X This flag is only used for lists and vectors (mul- X tivalued arguments) and is used on a per-item basis. If X it is set, it means that the corresponding value in the X vector/list required space to be allocated (such as the X duplication of a temporary string). X RETURN VALUE X The functions in the parseargs library will return a value X of zero upon succesful completion. They may however, return X any of the following status codes (which are defined in X <parseargs.h>): X X pe_SYSTEM X A system error occurred. The global variable errno may X indicate the problem (then again, it may not). X X pe_SUCCESS X Success, no errors encountered (zero is returned). X X pe_SYNTAX X A command-line syntax error was encountered X X pe_DEFARGS X An attempt (using parsecntl) was made to change the X default arg-search list of a command to point to an X argdesc-array which already has the given command on X its default arg-search list (which would cause an X infinite loop when attempting to match an unknown X command-line argument). X X pe_NOMATCH X Unable to match the named argument. This occurs when X the argument keyword name passed to parsecntl (using X the pc_ARGFLAGS functions code) was found in the given X argdesc-array or in its default-list. X X X X Page 8 X X X X X X PARSECNTL(3) PARSECNTL(3) X X X X pe_BADMODE X Bad mode for given command in parsecntl. This occurs X when pc_WRITE or pc_RDWR mode is passed to parsecntl in X conjunction with the pc_ARGFLAGS functions code. Par- X secntl will not modify existing arguments. X X pe_BADCNTL X Bad command for parsecntl. This occurs if an unknown X function-code was passed to parsecntl. X SEE ALSO X argtype(3), X parseargs(3), X parseargs(1) X AUTHOR X Brad Appleton (brad@ssd.csd.harris.com) X Harris Computer Systems, Fort Lauderdale, FL USA X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X Page 9 X X X SHAR_EOF chmod 0664 parseargs/parsecntl3.txt || echo 'restore of parseargs/parsecntl3.txt failed' Wc_c="`wc -c < 'parseargs/parsecntl3.txt'`" test 17278 -eq "$Wc_c" || echo 'parseargs/parsecntl3.txt: original size 17278, current size' "$Wc_c" rm -f _shar_wnt_.tmp fi # ============= parseargs/pgopen.c ============== if test -f 'parseargs/pgopen.c' -a X"$1" != X"-c"; then echo 'x - skipping parseargs/pgopen.c (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting parseargs/pgopen.c (Text)' sed 's/^X//' << 'SHAR_EOF' > 'parseargs/pgopen.c' && /************************************************************************* ** ^FILE: pgopen.c - pipe output to a pager for Unix Systems. ** ** ^DESCRIPTION: ** The functions in this file implement a minimal paging system ** using popen() & pclose() to invoke a specified paging program. ** ** The following public functions are defined: ** ** FILE *pgopen( FILE *fp, const char *pager_cmd ) ** -- attempt to open the pager, return the corresponding ** file-pointer to write to (which will be <fp> if ** popen(3S) fails). ** ** int pgclose( FILE *pager_fp ) ** -- close the pager stream, return 0 on success ** ** int pgactive( const FILE *pager_fp ) ** -- return TRUE if the pager is open. ** ** ^HISTORY: ** 12/03/90 Brad Appleton <brad@ssd.csd.harris.com> Created ***^^**********************************************************************/ X #ifdef USE_PAGER X X #include <stdio.h> #include <signal.h> #include <setjmp.h> #include <useful.h> X /* get #defines for access() call */ #include <sys/file.h> #ifndef X_OK # define X_OK 0x01 #endif X /* ** Implement a state machine that tries first to use a pager ** specified by the user, then as a second choice, /usr/ucb/more, ** if all else fails use the given file-pointer (which we assume to ** be writable) ** ** The following defines the state machine. ** */ X typedef enum { X PG_CLOSED, /* pager not-yet-open */ X PG_NONE, /* No pager used */ X PG_ENV, /* the given pager name (or $PAGER) was used */ X PG_DFLT, /* default pager (more) used */ X PG_FILE /* file-pointer used */ } pager_t; X #define DEFAULT_PAGER "/usr/ucb/more" X #ifndef TRUE # define TRUE 1 #endif #ifndef FALSE # define FALSE 0 #endif X #define MAX_NAME_LEN 512 #define isTERMINAL(fd) ( isatty(fd) ) ? TRUE : (errno = 0, FALSE) X extern char *strcpy(); extern int strcmp(); extern int access(); extern int isatty(); extern int wait(); extern int sleep(); X extern int errno; X static void pg_error(); /* broken-pipe exception handler */ static jmp_buf pg_recover; /* jump-buffer for exception handler */ static pager_t pg_pathname(); X static pager_t Pager_Type = PG_CLOSED; static FILE *Pager_FP = (FILE *)NULL; X X /*************************************************************************** ** ^FUNCTION: pgactive - query pager status ** ** ^SYNOPSIS: */ #ifndef __ANSI_C__ X int pgactive( pager_fp ) /* ** ^PARAMETERS: */ X FILE *pager_fp; /* -- the file-pointer returned by pgopen() */ #endif /* !__ANSI_C__ */ X /* ^DESCRIPTION: ** Pgactive indicates whether or not the given file-pointer is in ** use by the paging system. ** ** ^REQUIREMENTS: ** pgopen() must first be called in order to obtain a valid SHAR_EOF true || echo 'restore of parseargs/pgopen.c failed' fi echo 'End of part 8' echo 'File parseargs/pgopen.c is continued in part 9' echo 9 > _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.