home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-05-18 | 69.1 KB | 2,220 lines |
- Newsgroups: comp.sources.misc
- From: brad@hcx1.ssd.csd.harris.com (Brad Appleton)
- Subject: v29i119: parseargs - functions to parse command line arguments, Part04/10
- Message-ID: <1992May17.182342.28709@sparky.imd.sterling.com>
- X-Md4-Signature: 8d0fbe66797e91e23bae8aeec8652cd8
- Date: Sun, 17 May 1992 18:23:42 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: brad@hcx1.ssd.csd.harris.com (Brad Appleton)
- Posting-number: Volume 29, Issue 119
- Archive-name: parseargs/part04
- Environment: UNIX, VMS, MS-DOS, OS/2, Amiga
- Supersedes: parseargs: Volume 17, Issue 46-57
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 4 (of 10)."
- # Contents: doc/parseargs.man1 doc/parseargs.man3 pgopen.c stest.c
- # unix_man.c useful.h
- # Wrapped by brad@hcx1 on Thu May 7 12:12:22 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'doc/parseargs.man1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'doc/parseargs.man1'\"
- else
- echo shar: Extracting \"'doc/parseargs.man1'\" \(13778 characters\)
- sed "s/^X//" >'doc/parseargs.man1' <<'END_OF_FILE'
- X.\" $Header: parseargs.1,v 1.0 90/07/24 Brad Appleton $
- X.de SS
- X.sp 8p
- X\s+1\fB\\$1\fP\s-1
- X.br
- X..
- X.TH PARSEARGS 1
- X.nh
- X.SH NAME
- Xparseargs \- parse command line arguments in shell scripts
- X.\"-----------------------------------------------------------
- X.SH SYNOPSIS
- X.TP 12
- X\fBparseargs\fP
- X[\fB\-#UMCAlouip1\fP]
- X[\fB\-S\fP\ \fIseparator\fP]
- X[\fB\-T\fP\ \fIstring\fP]
- X[\fB\-F\fP\ \fIstring\fP]
- X[\fB\-a\fP\ \fIarg-spec\fP]
- X[\fB\-e\fP\ \fIname\fP]
- X[\fB\-f\fP\ \fIfile\fP]
- X[\fB\-s\fP\ \fIshell\fP\^]
- X\fB\-\^\-\fP
- X\fIname\fP
- X[\fIarguments\fP\ .\^.\^.\^]
- X.\"-----------------------------------------------------------
- X.SH OPTIONS
- X.TP 14
- X\fB\-#\fP
- Xjust print the version and patchlevel, do not parse the command line
- X.TP 14
- X\fB\-U\fP
- Xjust print program usage, do not parse the command line
- X.TP 14
- X\fB\-M\fP
- Xjust print (n|t)roff \-man manual page template, do not parse the command line
- X.TP 14
- X\fB-S\fP\ \fIseparator\fP
- Xfield-separator-string used to delimit array elements (\fIdefault=``\0''\fP\|)
- X.TP 14
- X\fB\-T\fP \fIstring\fP
- Xstring to use for true boolean arguments\| (\fIdefault=``\s-1TRUE\s+1\^''\fP\|)
- X.TP 14
- X\fB\-F\fP \fIstring\fP
- Xstring to use for false boolean arguments (\fIdefault=``\^''\fP\|)
- X.TP 14
- X\fB\-C\fP
- XIgnore the difference between upper and lower case when parsing single
- Xcharacter options.
- X.TP 14
- X\fB\-A\fP
- Xmodify array behavior for the specified shell.
- X.TP 14
- X\fB\-a\fP \fIarg-spec\fP
- Xargument specification string
- X.TP 14
- X\fB\-e\fP\ \fIname\fP
- Xread the arg-spec string from the environment variable named \fIname\fP
- X.TP 14
- X\fB\-f\fP \fIfile\fP
- Xread the arg-spec from \fIfile\fP (\fIdefault=stdin\fP)
- X.TP 14
- X\fB\-l\fP
- XLong-options only. Disable the parsing of (single-character) options.
- X.TP 14
- X\fB\-o\fP
- XOptions only. Disable the parsing of long-options (keywords).
- X.TP 14
- X\fB\-s\fP \fIshell\fP
- Xuse \fIshell\fP command syntax\| (\fIdefault=``sh''\fP\|)
- X.TP 14
- X\fB\-u\fP
- Xunset positional parameters before assigning variables
- X.TP 14
- X\fB\-p\fP
- Xprompt the user for missing required arguments
- X.TP 14
- X\fB\-i\fP
- Xignore bad command-line syntax and continue processing (instead of aborting)
- X.TP 14
- X\fB\-1\fP
- XForce any and all non-positional parameters to be specified before any
- Xpositional parameters on the command-line.
- X.\"-----------------------------------------------------------
- X.SH ARGUMENTS
- X.TP 14
- X\fI\-\^\-\fP
- XIndicates that any remaining options are intended for the calling program.
- X.TP 14
- X\fIname\fP
- Xname of calling program
- X.TP 14
- X\fIarguments\fP
- Xarguments to calling program
- X.\"-----------------------------------------------------------
- X.so parseargs1.inc
- X.\"-----------------------------------------------------------
- X.PP
- XThe argument specification string contains one entry for each possible flag.
- XEntries in the argument specification string are separated by commas.
- XEach entry has five comma-separated fields:
- Xa name, some flags, a type, a variable-name, and a prompt.
- XEach of these fields are described below:
- X.TP 10
- X\fIname\fP
- XThe single character name of the associated flag.
- XFor example, to indicate that the program is expecting a ``\-x'' flag,
- Xthis field would contain \'x\'.
- XPositional arguments (those without a ``\-\fIx\fP'' prefix)
- Xare indicated by passing a ``space'' character.
- X.TP 10
- X\fIflags\fP
- XFlags modifying the semantics of this entry.
- XThese should have one of
- X\s-1ARGREQ\s+1
- Xto indicate a required argument or
- X\s-1ARGOPT\s+1
- Xto indicate an optional argument
- X(\s-1ARGOPT\s+1 is the default unless \s-1ARGREQ\s+1 is specified).
- X\s-1ARGPOS\s+1
- Xmay be ``ored'' in to indicate a positional argument that may also
- Xbe keyword matched.
- X\s-1ARGVALOPT\s+1
- Xmay be ``ored'' in to indicate that an argument to the option may be
- Xoptionally supplied on the command-line, but is not required.
- X\s-1ARGVALREQ\s+1
- Xmay be ``ored'' in to indicate that an argument to the option is required
- X(this is the default behavior for options that take arguments).
- X\s-1ARGLIST\s+1
- Xmay be ``ored'' in (using the `\^|\^' character) to indicate that an argument
- Xis actually a list of one or more arguments from the command line.
- X\s-1ARGHIDDEN\s+1
- Xmay be ``ored'' in to indicate a flag that should not be printed
- Xin usage messages \(em
- Xfor example, flags intended for internal debugging purposes.
- X.TP 10
- X\fItype\fP
- XThe type of the argument.
- XExisting types include
- X\fIargUsage\fP (print usage message and exit),
- X\fIargBool\fP and \fIargSBool\fP (set Boolean flags),
- X\fIargUBool\fP (unset Boolean flags),
- X\fIargStr\fP (string-valued arguments),
- X\fIargChar\fP (char-valued arguments),
- X\fIargInt\fP (native integer arguments),
- X\fIargShort\fP (short integer arguments),
- X\fIargLong\fP (long integer arguments),
- X\fIargFloat\fP (short floating point arguments),
- X\fIargDouble\fP (long floating point arguments), and
- X\fIargDummy\fP (only used as part of usage message,
- Xnot matched on command-line).
- X.TP 10
- X\fIvariable\fP
- XThe name of the shell variable that should receive the converted value.
- X.TP 10
- X\fIprompt\fP
- XThe string used when prompting interactively for argument values,
- Xand printed in usage messages. This string may be followed by a
- Xtextual description that is enclosed in parentheses, square brackets,
- Xcurly braces, or angle brackets.
- X
- XThe prompt-string may be specifed
- Xin two parts: a keyword name and an argument name. The argument
- Xname may be separated from the keyword name by a single equal sign
- X('='). No whitespace is allowed before or after the equal sign.
- X
- XAlternatatively, the keyword name may be distinguished from the
- Xargument name by character case: if the long-name contains any
- Xuppercase characters, then the substring of long-name consisting of
- Xall uppercase characters is used as the argument keyword and the
- Xentire long-name is used as the name of the argument (if a value may
- Xbe supplied). The long-name may be matched by supplying a unique
- Xprefix of either the argument keyword or the argument name.
- X.PP
- XThe argument specification string must be terminated by the single string:
- X``ENDOFARGS''.
- X.PP
- XNote that the comma character (',') is used to separate all fields
- Xwithin an entry, and to separate the entries themselves.
- XFor this reason, \fIno field in any entry may contain a comma unless
- Xit appears inside of double or single quotes\fP.
- X.PP
- X.B Parseargs
- Xwill parse all command-line arguments for the calling script and match
- Xthem against the argument specification string provided. The argument
- Xspecification string is read from standard input by default but may not
- Xcome from a terminal. The argument specification string may be supplied as
- Xa single string argument by using the \fB\-a\fP ``\fIstring\fP'' flag.
- XLong argument specification strings however, may limit the number of arguments
- Xto the script if there is a limit to the number of arguments and/or characters
- Xthat may appear on the command line.
- XFor this reason, the argument specification string may be stored: in an
- Xenvironment variable using the \fB\-e\fP \fIname\fP option; in a file
- Xand read using the \fB\-f\fP \fIfile\fP option; or read from standard input.
- XWhen using the \fB\-e\fP option, the user must remember to use the name
- Xof an environment variable (not a mere shell variable)!
- XThe default behavior is to read the argument specification from standard input.
- X.\"-----------------------------------------------------------
- X.so shells.inc
- X.\"-----------------------------------------------------------
- X.PP
- XThe double-dash (``\fB\-\^\-\fP'') which precedes the name and arguments of
- Xthe calling program is needed in order for \fBparseargs\fP to be able to
- Xdistinguish options to itself from options for the calling program.
- X.PP
- XThe default behavior of parseargs is to allow both single-character options and
- Xlong-options (keywords) on the command-line. The user may specify that only
- Xoptions (long-options) are to be permitted by specifying the \fB\-o\fP
- X(\fB\-l\fP) option on the command-line.
- X.\"----------------------------------------------------------------
- X.SH "SPECIFYING PARSE-BEHAVIOR"
- X.PP
- XThe \fB\-C\fP, \fB\-p\fP, \fB\-i\fP, and \fB\-1\fP switches may be used to
- Xmodify the command-line parsing behavior of the invoking script. Specifying
- X\fB\-C\fP will cause case-differences in single-character options to be
- Xignored. Specifying \fB\-p\fP will cause the user to be interactively prompted
- Xfor any missing required arguments. Specifying \fB\-i\fP will cause
- Xsyntactically incorrect arguments to be ignored (instead of having a usage
- Xmessage printed and execution terminated). Specifying \fB\-1\fP will force
- Xall non-positional parameters to precede any positional parameters on the
- Xcommand-line (hence anything on the command-line after a positional parameter
- Xthat resembles a keyword parameter will nevertheless be interpreted as a
- Xpositional parameter).
- X.\"----------------------------------------------------------------
- X.so argvalopt.inc
- X.\"----------------------------------------------------------------
- X.so sh_arrays.inc
- X.\"----------------------------------------------------------------
- X.so env_args.inc
- X.\"----------------------------------------------------------------
- X.so env_parse.inc
- X.\"----------------------------------------------------------------
- X.so env_usage.inc
- X.\"----------------------------------------------------------------
- X.SH EXAMPLES
- X.PP
- XAs a first example, consider the following argument specification for a
- XBourne shell script:
- X.PP
- X.nf
- X.\" *** font 4 is the "typewriter-style" non-proportional font on my machine ***
- X.ft 4
- X.sp 8p
- X#!/bin/sh
- X.sp 8p
- XRepCount=2;
- XVerbose="";
- X.sp 8p
- XARGSPEC="
- X 'c', ARGOPT, argInt, RepCount, 'count {# times to repeat}',
- X 'v', ARGOPT, argBool, Verbose, 'verbose {turn on verbose mode}',
- X ' ', ARGREQ, argStr, InFile, 'input {file to read from}',
- X ' ', ARGOPT, argStr, OutFile, 'output {file to write to}',
- X 'X', ARGHIDDEN, argBool, XRated, 'xrated {naughty! naughty!}',
- X ' ', ARGOPT|ARGLIST, listStr, Files, 'files {files to process}',
- XENDOFARGS
- X"
- X.sp 8p
- Xeval `echo "$ARGSPEC" | parseargs \-s sh \-\|\- $0 "$@"`
- X.sp 8p
- X.ft R
- X.fi
- X.PP
- XThis describes a Bourne shell script accepting up to three flag arguments and
- Xone or two positional arguments, plus a list of additional file arguments.
- XOnly the first positional argument is required.
- XThe possible flags (in UNIX) are:
- X.RS
- X.TP 10
- X\fB\-c\fP \fIcount\fP
- XAn integer repetition count.
- XThis defaults to two.
- X.TP 10
- X\fB\-v\fP
- XA Boolean ``verbose'' flag.
- XIt defaults to \s-1FALSE\s+1 (an empty string).
- X.TP 10
- X\fB\-X\fP
- XA Boolean ``X Rated'' flag.
- XThis is not printed in the usage message.
- X.RE
- X.PP
- XThe two positional arguments are both strings, as is the final list.
- XIf we were to invoke the above script with the following command line:
- X.sp 8p
- X.RS
- X\f4cmdname \-v input_file output_file file1 file2\fP
- X.RE
- X.sp 8p
- XThen, after invoking \fBparseargs\fP, the following shell variables would
- Xcontain the following values:
- X.sp 8p
- X.RS
- X\f4$RepCount\fP would evaluate to ``\f42\fP\^''
- X.sp 4p
- X\f4$Verbose\fP would evaluate to ``\f4\s-1TRUE\s+1\fP\^''
- X.sp 4p
- X\f4$InFile\fP would evaluate to ``\f4input_file\fP\^''
- X.sp 4p
- X\f4$OutFile\fP would evaluate to ``\f4output_file'\fP\^'
- X.sp 4p
- X\f4$Files\fP would evaluate to ``\f4file1 file2\fP\^''
- X.sp 4p
- X\f4$XRated\fP would be unset and would evaluate to an empty string (``\^'').
- X.RE
- X.sp
- X.PP
- XNow let's present a more complete example. The following page shows a
- XBourne shell script which uses \fBparseargs\fP to parse its command line,
- Xechoes the settings of all its associated command line variables, and
- Xthen prints its command usage.
- X
- X.nf
- X.\" *** font 4 is the "typewriter-style" non-proportional font on my machine ***
- X.ft 4
- X.so ../test.sh
- X.ft R
- X.fi
- X.\"-----------------------------------------------------------
- X.SH DIAGNOSTICS
- X\fBParseargs\fP may exit with one of the following status codes:
- X
- X.TP 5
- X-1
- XSome type of system error occurred during execution, causing the program
- Xto exit prematurely.
- X.TP 5
- X\|\|0
- XNormal exit status (no problems were encountered).
- X.TP 5
- X\|\|1
- XThe calling program specified the \fB\-#\fP, the \fB\-U\fP or the \fB\-M\fP
- Xoption to \fBparseargs\fP, or specified an \fIargUsage\fP flag on the command
- Xline. Only the appropriate message is displayed.
- X.TP 5
- X\|\|2
- XA command line syntax error was encountered by \fBparseargs\fP. The offending
- Xcommand line argument may have been intended for either \fBparseargs\fP or
- Xfor the calling program.
- X.TP 5
- X\|\|3
- XThe environment variable that was specified with the \fB\-e\fP option
- Xis either \s-1NULL\s+1 (has an empty value) or does not exist. Perhaps
- Xthe user specified a shell variable and/or forgot to export it.
- X.TP 5
- X\|\|4
- XA syntax error was encountered in the argument specification string that was
- Xspecified to \fBparseargs\fP.
- X.\"-----------------------------------------------------------
- X.SH FILES
- X.IP "\fI/usr/local/parseargs.pl\fP"
- XThis file defines a \fIperl\fP function named \fIparseargs\fP to parse
- Xarguments more conveniently for perl-scripts. The function is
- Xboth documented and implemented in this file. The user should
- X``require'' this file in his/her perl-script before invoking the
- Xfunction.
- X.IP "\fI/usr/local/parseargs.awk\fP"
- XThis file defines an \fIawk\fP function named \fIparseargs\fP to parse
- Xarguments more conveniently for awk-scripts. The function is
- Xboth documented and implemented in this file. The user should
- Xinclude this file in his/her awk-script before invoking the
- Xfunction.
- X.\"-----------------------------------------------------------
- X.SH SEE ALSO
- X.IR argtype (3),
- X.IR parseargs (3),
- X.IR parsecntl (3)
- X.\"-----------------------------------------------------------
- X.so caveats.inc
- X.\"-----------------------------------------------------------
- X.so bugs.inc
- X.\"-----------------------------------------------------------
- X.SH AUTHOR
- X.nf
- XBrad Appleton (\fIbrad@ssd.csd.harris.com\fP)
- XHarris Computer Systems, Fort Lauderdale, FL USA
- X.fi
- END_OF_FILE
- if test 13778 -ne `wc -c <'doc/parseargs.man1'`; then
- echo shar: \"'doc/parseargs.man1'\" unpacked with wrong size!
- fi
- # end of 'doc/parseargs.man1'
- fi
- if test -f 'doc/parseargs.man3' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'doc/parseargs.man3'\"
- else
- echo shar: Extracting \"'doc/parseargs.man3'\" \(11684 characters\)
- sed "s/^X//" >'doc/parseargs.man3' <<'END_OF_FILE'
- X.\" $Header: parseargs.3,v 2.0 89/12/24 00:56:26 eric Exp $
- X.TH PARSEARGS 3
- X.\"-----------------------------------------------------------
- X.SH NAME
- Xparseargs \- parse command line argument vectors
- X.\"-----------------------------------------------------------
- X.SH SYNOPSIS
- X#include <parseargs.h>
- X.PP
- X.nf
- Xint parseargs( char *argv\f4[]\fP, ARGDESC *argd );
- Xint fparseargs( FILE *fp, ARGDESC *argd );
- Xint lparseargs( ArgList *argls, ARGDESC *argd );
- Xint sparseargs( char *str, ARGDESC *argd );
- Xint vparseargs( ARGDESC *argd, int argc, ... );
- Xvoid usage( const ARGDESC *argd );
- Xextern const char *ProgName;
- X.fi
- X.\"-----------------------------------------------------------
- X.SH DESCRIPTION
- X.so parseargs3.inc
- X.so fparseargs3.inc
- X.so lparseargs3.inc
- X.so sparseargs3.inc
- X.so vparseargs3.inc
- X.so usage3.inc
- X.PP
- XAfter returning from any of the aforementioned functions, the global
- Xstring \fIProgName\fP will contain the name of the command corresponding
- Xto the argument-descriptor array that was most recently operated upon by
- Xone the functions in the \fIparseargs\fP(3) function library.
- X.\"-----------------------------------------------------------
- X.so argdesc.inc
- X.\"-----------------------------------------------------------
- X.SH DEFINING ARGDESC ARRAYS
- XWhen defining an argdesc array, the first item in the list should
- Xbe the item STARTOFARGS. Normal arguments (defined by the programmer)
- Xmay then be specified as documented in this manual.
- XThe list of arguments is terminated using ENDOFARGS.
- X.PP
- XFor example, consider the description:
- X.sp 4p
- X.in +2
- X.nf
- X.ft 4
- Xint RepCount = 2;
- XBOOL Verbose = FALSE;
- Xchar *InFile;
- Xchar *OutFile = CHARNULL;
- XBOOL XRated = FALSE;
- XArgList *Files = ARGLISTNULL;
- X
- XARGDESC 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 ' ', ARGLIST, listStr, _\|_ &Files, "File {files to be read}",
- X ENDOFARGS
- X};
- X.ft R
- X.fi
- X.in -2
- X.PP
- XThis describes a program accepting up to three flag arguments and
- Xone or two positional arguments, plus a list of additional file arguments.
- XOnly the first positional argument is required.
- XThe possible flags (in UNIX) are:
- X.TP 10
- X\fB\-c\fP \fIcount\fP
- XAn integer repetition count.
- XThis defaults to two.
- X.TP 10
- X\fB\-v\fP
- XA Boolean ``verbose'' flag.
- XIt defaults to FALSE.
- X.TP 10
- X\fB\-X\fP
- XA Boolean ``X Rated'' flag.
- XThis is not printed in the usage message.
- X.PP
- XThe two positional arguments are both strings, as is the final list.
- XIn AmigaDOS, the options would be
- X\fBREP\fP \fBcount\fP,
- X\fBV\fP, and
- X\fB\s-1XMODE\s+1\fP.
- XIn \s-1VAX/VMS\s+1, the qualifiers would be
- X\fB\s-1/REP\s+1\fP=\fIcount\fP,
- X\fB\s-1/V\s+1\fP, and
- X\fB\s-1/XMODE\s+1\fP.
- X.\"-----------------------------------------------------------
- X.so argflags.inc
- X.\"-----------------------------------------------------------
- X.so arg_macros.inc
- X.\"-----------------------------------------------------------
- X.so cmd_macros.inc
- X.\"-----------------------------------------------------------
- X.so defargs.inc
- X.\"-----------------------------------------------------------
- X.so env_args.inc
- X.\"-----------------------------------------------------------
- X.so env_parse.inc
- X.\"-----------------------------------------------------------
- X.so env_usage.inc
- X.\"-----------------------------------------------------------
- X.so multivals.inc
- X.\"-----------------------------------------------------------
- X.SH ARGUMENT TYPE FUNCTIONS
- XThe argument types recognized by
- X.I parseargs
- Xcan be extended by adding new type functions.
- XArgument type functions are declared as:
- X.RS
- X.PP
- X.nf
- X.ft 4
- XBOOL argXxx( ARGDESC *ad, char *vp, BOOL copyf )
- X.ft R
- X.fi
- X.RE
- X.PP
- XThe \f4ad\fP argument points to the descriptor for the argument being
- Xconverted. Its main use is to find the location in which to store the
- Xconverted value, located in ad\(->ad_valp.
- XThe string value to be converted is passed in \f4vp\fP
- X(which will be \s-1NULL\s+1 if the \s-1ARGNOVAL\s+1 flag was set for the
- Xcorresponding entry in the arg-descriptor table).
- XThe \f4copyf\fP flag is TRUE if the \f4vp\fP string value must be copied
- Xwhen saved. Most non-string types are copied implicitly (for example,
- Xinteger arguments are stored in binary form, so the original string value
- Xneed not be saved), so this argument can usually be ignored. Put simply,
- Xthis flag is TRUE when \f4vp\fP points to a temporary buffer area.
- X.PP
- XIf the type function successfully converts the value, and uses the entire
- Xvalue, it should return TRUE. If the type function successfully converts
- Xthe value, and uses only \fIN\fP characters of the value, it should return
- X-\fIN\fP. Otherwise, it should print a message using
- X.IR usrerr (3)
- Xand return FALSE. This message should be of the form
- X\fB"invalid xxxx option 'yyyy' for Zzzz"\fP, where xxxx is the type of the
- Xoption, yyyy is the string passed in \f4vp\fP, and zzzz is the name (taken
- Xfrom \f4ad\(->ad_prompt\fP).
- XThe \fIargXxxx\fP function is responsible for detecting if the given argument
- Xdescriptor is an \s-1ARGVEC\s+1 argument and for taking the appropriate action.
- X.PP
- XFor example, a type function that took a filename
- Xand stored an open file pointer might be coded as:
- X.RS
- X.PP
- X.nf
- X.ft 4
- X#define REALLOC(ptr,size) ((! ptr) ? malloc(size) : realloc(ptr, size))
- X.sp 8p
- Xtypedef ARGVEC_T(FILE *) FILEvec_t;
- X.sp 8p
- XBOOL argReadFile( ARGDESC *\|ad, char *\|vp, BOOL copyf )
- X{
- X register FILE *fp;
- X.sp 4p
- X fp = fopen(vp, "r");
- X.sp 4p
- X if ( ! fp ) {
- X usrerr("cannot open '%s' for reading", vp);
- X return (FALSE);
- X }
- X.sp 4p
- 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.sp 4p
- X vec->array = (FILE **) REALLOC(vec->array, size);
- X if ( ! vec->array )
- X syserr( "(m|re)alloc failed in argReadFile" );
- X.sp 4p
- X vec->flags = (FILE **) REALLOC(vec->flags, size);
- X if ( ! vec->flags )
- X syserr( "(m|re)alloc failed in argReadFile" );
- X.sp 4p
- X vec->flags[ vec->count ] = arg_flags(ad);
- X vec->array[ (vec->count)++ ] = fp;
- X }
- X else
- X *(FILE *) arg_valp(ad) = fp;
- X.sp 4p
- X return (TRUE);
- X}
- X.ft R
- X.fi
- X.RE
- X.RE
- X.\"------------------------------------------------------------------
- X.SH LONG OPTIONS
- X.PP
- XUnder \s-1UNIX\s+1, \s-1MS-DOS\s+1, and \s-1OS\s+1/2,
- X\fIparseargs\fP also allows for long
- Xoptions in addition to single character options.
- XUnder \s-1UNIX\s+1, long options are denoted by a `\fB+\fP' character
- X(unless \fIparseargs\fP was compiled for conformance with POSIX, inc which
- Xcase the long option prefix is `\fB\-\|\-\fP').
- XUnder \s-1MS-DOS\s+1, and \s-1OS\s+1/2, long options are denoted by the second
- Xcharacter in the \s-1SWITCHAR\s+1 environment variable. If there is no second
- Xcharacter, then if the first character is `\-', then a `\fB+\fP' is used,
- Xotherwise a `\fB/\fP' is used.
- XThe keyword that is used is the first word in the prompt field of an
- Xargument descriptor entry. Long options are case insensitive!
- XUnder \s-1UNIX\s+1, an argument to a long option may be separated
- Xfrom the long option by an equal sign (`=') or by one or more
- Xwhitespace characters. Thus, if an entry looks like:
- X.RS
- X.sp 4p
- X.nf
- X.ft 4
- X\^'c', ARGOPT, argInt, _\|_ &count, "repCOUNT (# of times to repeat)",
- X.ft R
- X.fi
- X.sp 4p
- X.RE
- Xthen ``\fB\-c4\fP'', ``\fB+repcount=4\fP'', ``\fB+count=4\fP'',
- X``\fB+repcount\04\fP'', and ``\fB+count\04\fP'' will all have the same effect.
- X.PP
- XThe long option names for ``\fB\-?\fP'' in the default argument descriptor
- Xare ``\fB+help\fP'' and ``\fB+?\fP'' (respectively). In addition, ``\fB++\fP''
- Xmay be used to indicate the end of options so that
- Xall remaining arguments will be interpreted as positional parameters
- X(even if one begins with a `\fB+\fP' or a `\fB\-\fP').
- X.PP
- XUnder \s-1MS-DOS\s+1, and \s-1OS\s+1/2, an argument to a long-option must be
- Xseparated from the long option by an equal sign (`=') (unless the first
- Xcharacter of $SWITCHAR is a `\-', in which case \s-1UNIX\s+1 syntax is used).
- XThe long option names for ``\fB/?\fP'' in the default argument descriptor
- Xare ``\fB/help\fP'' and ``\fB/?\fP'' (respectively).
- X.PP
- XUnder VAX/VMS and AmigaDOS, single-character options are not used and the
- X``long'' name (in the prompt field of an argument descriptor) is always used
- Xto match for possible arguments (or keywords, or qualifiers).
- X.PP
- XFor all supported operating systems, a long option may be matched in one of
- Xtwo ways: it may match all uppercase characters in the prompt field, or it may
- Xmatch all characters in the prompt field (as in ``\fB+count=4\fP'' and
- X``\fB+repcount=4\fP'').
- X.PP
- XUnder all systems except AmigaDOS,
- Xonly the number of characters required to uniquely identify the desired argument
- Xare needed, but at least two characters must be given (unless the prompt field
- Xis itself less than two characters long). This means that using the above
- Xexample, that ``\fB+rep=4\fP'' and
- X``\fB+cou=4\fP'' would also work but ``\fB+c=4\fP'' would \s-1NOT\s+1 (in other words, if
- Xyou only want to use one character, use ``\fB\-c4\fP'' instead).
- X.PP
- XUnder VAX/VMS, the possibilities using the above example would be:
- X``\fB/REPCOUNT=4\fP'', ``\fB/COUNT=4\fP'', ``\fB/REP=4\fP'', and ``\fB/COU=4\fP'',
- X.PP
- XUnder AmigaDOS, no ``shortened'' keywords are accepted and the possibilities
- Xusing the above example would be:
- X``\fBREPCOUNT 4\fP'', and ``\fBCOUNT 4\fP''
- X.\"------------------------------------------------------------------
- X.so returns.inc
- X.\"------------------------------------------------------------------
- X.so effects.inc
- X.\"------------------------------------------------------------------
- X.SH "DOCUMENTING YOUR COMMANDS"
- X.PP
- XThe commands that you write with \fIparseargs\fP(3) may be documented
- Xusing \fIparseargs\fP(1). Just copy the argument descriptor array
- Xinto a separate file, and invoke \fIparseargs\fP(1) with the \fB\-M\fP
- Xoption and pass it the command-name (dont forget to redirect input
- Xto come from your newly created file). It is important to note that the
- Xonly portion of that argdesc array to insert into your file is the portion
- Xstarting with the very first command-line argument, all the way down to
- X(and including) the \s-1ENDOFARGS\s+1 or \s-1END_ARGUMENTS\s+1 entry.
- X.\"------------------------------------------------------------------
- X.SH FILES
- X.IP "\fI/usr/local/lib/libparse.a\fP"
- XLink library for parseargs.
- X.IP "\fI/usr/local/include/parseargs.h\fP"
- XInclude file for parseargs.
- X.IP "\fI/usr/local/include/useful.h\fP"
- XInclude file for portability.
- X.\"------------------------------------------------------------------
- X.SH SEE ALSO
- X.IR argtype (3),
- X.IR parseargs (1),
- X.IR parsecntl (3)
- X.br
- XThe ``C Advisor'' column in
- X.ul
- XUNIX Review
- XVol. 7 No. 11.
- X.\"-----------------------------------------------------------
- X.so caveats.inc
- X.\"-----------------------------------------------------------
- X.so lib_bugs.inc
- X.\"-----------------------------------------------------------
- X.SH AUTHOR
- XEric Allman, University of California, Berkeley
- X.SH MODIFICATIONS
- X.PP
- XModified to accept a vector of arguments, better error messages,
- XUnix keyword matching, and AmigaDOS version by Peter da Silva.
- X.PP
- XRewritten by Brad Appleton.
- XParseargs(1);
- Xfunctions parsecntl, sparseargs, fparseargs, lparseargs, and vparseargs;
- Xargument types argUsage, argDummy, argUBool, and argTBool;
- Xargument flags \s-1ARGPOS\s+1, \s-1ARGVALOPT\s+1, \s-1ARGVALREQ\s+1,
- X\s-1ARGVALGIVEN\s+1, \s-1ARGNOVAL\s+1, and \s-1ARGVEC\s+1; and
- X\s-1VAX/VMS\s+1 version and IBM-PC version by Brad Appleton
- END_OF_FILE
- if test 11684 -ne `wc -c <'doc/parseargs.man3'`; then
- echo shar: \"'doc/parseargs.man3'\" unpacked with wrong size!
- fi
- # end of 'doc/parseargs.man3'
- fi
- if test -f 'pgopen.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'pgopen.c'\"
- else
- echo shar: Extracting \"'pgopen.c'\" \(12598 characters\)
- sed "s/^X//" >'pgopen.c' <<'END_OF_FILE'
- X/*************************************************************************
- X** ^FILE: pgopen.c - pipe output to a pager for Unix Systems.
- X**
- X** ^DESCRIPTION:
- X** The functions in this file implement a minimal paging system
- X** using popen() & pclose() to invoke a specified paging program.
- X**
- X** The following public functions are defined:
- X**
- X** FILE *pgopen( FILE *fp, const char *pager_cmd )
- X** -- attempt to open the pager, return the corresponding
- X** file-pointer to write to (which will be <fp> if
- X** popen(3S) fails).
- X**
- X** int pgclose( FILE *pager_fp )
- X** -- close the pager stream, return 0 on success
- X**
- X** int pgactive( const FILE *pager_fp )
- X** -- return TRUE if the pager is open.
- X**
- X** ^HISTORY:
- X** 12/03/90 Brad Appleton <brad@ssd.csd.harris.com> Created
- X***^^**********************************************************************/
- X
- X#ifdef USE_PAGER
- X
- X
- X#include <stdio.h>
- X#include <errno.h>
- X#include <signal.h>
- X#include <setjmp.h>
- X#include <useful.h>
- X
- X/* get #defines for access() call */
- X#ifndef SYSV
- X# include <sys/file.h>
- X#endif
- X#ifndef X_OK
- X# define X_OK 0x01
- X#endif
- X
- X#include "exit_codes.h"
- X
- X/*
- X** Implement a state machine that tries first to use a pager
- X** specified by the user, then as a second choice, /usr/ucb/more,
- X** if all else fails use the given file-pointer (which we assume to
- X** be writable)
- X**
- X** The following defines the state machine.
- X**
- X*/
- X
- Xtypedef 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 */
- X} pager_t;
- X
- X#define DEFAULT_PAGER "/usr/ucb/more"
- X
- X#ifndef TRUE
- X# define TRUE 1
- X#endif
- X#ifndef FALSE
- X# define FALSE 0
- X#endif
- X
- X#define MAX_NAME_LEN 512
- X#define isTERMINAL(fd) ( isatty(fd) ) ? TRUE : (errno = 0, FALSE)
- X
- Xextern char *strcpy();
- Xextern int strcmp();
- Xextern int access();
- Xextern int isatty();
- Xextern unsigned sleep();
- X
- Xstatic void pg_error(); /* broken-pipe exception handler */
- Xstatic jmp_buf pg_recover; /* jump-buffer for exception handler */
- Xstatic pager_t pg_pathname();
- X
- Xstatic pager_t Pager_Type = PG_CLOSED;
- Xstatic FILE *Pager_FP = (FILE *)NULL;
- X
- X
- X/***************************************************************************
- X** ^FUNCTION: pgactive - query pager status
- X**
- X** ^SYNOPSIS:
- X*/
- X#ifndef __ANSI_C__
- X int pgactive( pager_fp )
- X/*
- X** ^PARAMETERS:
- X*/
- X FILE *pager_fp;
- X/* -- the file-pointer returned by pgopen()
- X*/
- X#endif /* !__ANSI_C__ */
- X
- X/* ^DESCRIPTION:
- X** Pgactive indicates whether or not the given file-pointer is in
- X** use by the paging system.
- X**
- X** ^REQUIREMENTS:
- X** pgopen() must first be called in order to obtain a valid
- X** pager-file-pointer.
- X**
- X** ^SIDE-EFFECTS:
- X** None.
- X**
- X** ^RETURN-VALUE:
- X** Zero if the pager is active; non-zero otherwise.
- X**
- X** ^ALGORITHM:
- X** Trivial.
- X***^^**********************************************************************/
- X#ifdef __ANSI_C__
- X int pgactive( const FILE *pager_fp )
- X#endif
- X{
- X return ( (Pager_Type != PG_CLOSED) && (pager_fp) );
- X}
- X
- X
- X/***************************************************************************
- X** ^FUNCTION: pgclose - close the pager.
- X**
- X** ^SYNOPSIS:
- X*/
- X#ifndef __ANSI_C__
- X int pgclose( pager_fp )
- X/*
- X** ^PARAMETERS:
- X*/
- X FILE *pager_fp;
- X/* -- the file-pointer returned by pgopen()
- X*/
- X#endif /* !__ANSI_C__ */
- X
- X/* ^DESCRIPTION:
- X** Pgclose will flush any remaining output and close the pager.
- X**
- X** ^REQUIREMENTS:
- X** pgopen() must first be called in order to obtain a valid
- X** pager-file-pointer.
- X**
- X** ^SIDE-EFFECTS:
- X** None.
- X**
- X** ^RETURN-VALUE:
- X** Returns 0 if the pager was succesfully close; non-zero if it wasnt
- X** in use to begin with.
- X**
- X** ^ALGORITHM:
- X** - if ( pager-not-in-use ) return 1
- X** - flush any remaining pager output
- X** - if we used popen() to open this pager then
- X** - call pclose to close the pager-program
- X** - unset the SIGPIPE signal-handler
- X** end-if
- X** - reset the pager-file-pointer to NULL
- X** - set the pager-state to closed
- X** - return 0
- X***^^**********************************************************************/
- X#ifdef __ANSI_C__
- X int pgclose( FILE *pager_fp )
- X#endif
- X{
- X if ( Pager_Type == PG_CLOSED || !Pager_FP || !pager_fp ) return 1;
- X
- X fflush( Pager_FP );
- X
- X if ( Pager_Type == PG_ENV || Pager_Type == PG_DFLT ) {
- X (VOID) pclose( Pager_FP );
- X (VOID) signal( SIGPIPE, (void (*)())SIG_IGN );
- X }
- X
- X Pager_FP = (FILE *)NULL;
- X Pager_Type = PG_CLOSED;
- X
- X return 0;
- X}
- X
- X
- X/***************************************************************************
- X** ^FUNCTION: pgopen - open the pager
- X**
- X** ^SYNOPSIS:
- X*/
- X#ifndef __ANSI_C__
- X FILE *pgopen( fp, pager_cmd )
- X/*
- X** ^PARAMETERS:
- X*/
- X FILE *fp;
- X/* -- the file pointer to use if popen() fails
- X*/
- X char *pager_cmd;
- X/* -- name of the pager-program to pass to popen()
- X*/
- X#endif /* !__ANSI_C__ */
- X
- X/* ^DESCRIPTION:
- X** Pgopen will attempt to "redirect" output from the given file
- X** pointer to the pager specified by <pager_cmd>. If <fp> is NOT
- X** connected to a terminal or <pager_cmd> cannot be succesfully
- X** opened, then <fp> is resturned output is sent to it unpaginated.
- X** Otherwise, pgopen will try to open <pager_cmd> for input. If it
- X** cannot succeed it tries to open $PAGER for input. If this also
- X** fails then /usr/ucb/more is tried. If all else fails, return <fp>.
- X**
- X** ^REQUIREMENTS:
- X** pager_cmd should be the full-pathname name of a valid, executable
- X** program which reads from standard input and writes (one screenful
- X** at a time) to the terminal.
- X**
- X** ^SIDE-EFFECTS:
- X** If popen() succeeds, the SIGPIPE signal is trapped.
- X**
- X** ^RETURN-VALUE:
- X** returns 0 upon success, non-zero if the pager is already in use.
- X**
- X** ^ALGORITHM:
- X** - if the pager is already in use, return 1
- X** - if <fp> is not connected to a terminal, use it for output and return 0
- X** - set up recovery point for SIGPIPE signal
- X** - if we can open the pager_cmd, check for a SIGPIPE error
- X** - if either of the above fails, then try the same with $PAGER
- X** - if either of the above fails, then try the same with /usr/ucb/more
- X** - if either of the above fails, just use <fp> and return
- X***^^**********************************************************************/
- X#ifdef __ANSI_C__
- X FILE *pgopen( FILE *fp, const char *pager_cmd )
- X#endif
- X{
- X pager_t pg_type;
- X char pg_name[ MAX_NAME_LEN ];
- X
- X /* if a pager is already open - ignore this call */
- X if ( Pager_Type != PG_CLOSED || Pager_FP ) return fp;
- X
- X /*
- X ** dont page output if it has been redirected
- X */
- X if ( !isTERMINAL(fileno(fp)) ) {
- X Pager_Type = PG_FILE;
- X Pager_FP = fp;
- X return fp;
- X }
- X
- X *pg_name = '\0';
- X if ( pager_cmd ) strcpy( pg_name, pager_cmd );
- X pg_type = pg_pathname( pg_name );
- X Pager_FP = (FILE *)NULL;
- X
- X /* jump here after pg_error fields SIGPIPE */
- X if ( setjmp( pg_recover ) ) {
- X (void) pclose( Pager_FP );
- X Pager_FP = (FILE *)NULL;
- X pg_type = ( pg_type == PG_ENV ) ? PG_DFLT : PG_NONE;
- X }
- X
- X /* keep trying till we get a valid file-pointer */
- X while ( !Pager_FP ) {
- X switch( pg_type ) {
- X case PG_DFLT:
- X /* jump here if both $PAGER and DEFAULT-PAGER fail */
- X if ( setjmp( pg_recover )) {
- X (void) pclose( Pager_FP );
- X Pager_FP = (FILE *)NULL;
- X pg_type = PG_NONE;
- X continue;
- X }
- X /* fall through to next case */
- X
- X case PG_ENV:
- X signal( SIGPIPE, pg_error );
- X Pager_FP = (FILE *) popen( pg_name, "w" );
- X if ( !Pager_FP ) {
- X if ( pg_type == PG_ENV ) {
- X Pager_FP = (FILE *)NULL;
- X pg_type = PG_DFLT;
- X }
- X else {
- X Pager_FP = fp;
- X pg_type = PG_NONE;
- X }
- X }
- X else {
- X /*
- X ** Sleep for a bit, just so we block, and the child
- X ** process can get moving. Then attempt to write to
- X ** the pager pipeline. If the pager is bad then the
- X ** pipe will be broken and pg_error() will handle
- X ** the broken-pipe signal. Othwerwise, the write will
- X ** succeed and we'll reset the handler to ignore the
- X ** broken pipe signal.
- X */
- X sleep( 1 );
- X fputc( '\n', Pager_FP );
- X fflush( Pager_FP );
- X signal( SIGPIPE, (void (*)())SIG_IGN );
- X }
- X break;
- X
- X case PG_NONE:
- X case PG_FILE:
- X Pager_FP = fp;
- X break;
- X
- X default:
- X fprintf( stderr, "Unrecognized state [%d] in pgopen()\n",
- X pg_type );
- X exit( exit_SYSTEM );
- X }/*switch*/
- X }/*while*/
- X
- X Pager_Type = pg_type;
- X return Pager_FP;
- X}
- X
- X
- X/***************************************************************************
- X** ^FUNCTION: pg_error - handle error when trying to open a pager
- X**
- X** ^SYNOPSIS:
- X*/
- X#ifndef __ANSI_C__
- X static void pg_error()
- X#endif
- X/*
- X** ^PARAMETERS:
- X** None.
- X**
- X** ^DESCRIPTION:
- X** Pgerror is called when the SIGPIPE signal is recieved. If SIGPIPE
- X** is recieved, it means that popen succesfully forked the shell to
- X** run the pager but the pager-command itself broke the read-end of
- X** the pipe between us (i.e. it is an invalid pager-program or it crashed).
- X**
- X** When SIGPIPE is recieved, this routine will reset the signal handler
- X** to its previous value and jump to the recovery point set up by pgopen.
- X**
- X** ^REQUIREMENTS:
- X** Pgopen must set up this function is the SIGPIPE handler function.
- X**
- X** Pgopen must place the address of the desired recovery point in
- X** pg_recover.
- X**
- X** ^SIDE-EFFECTS:
- X** Resets SIGPIPE signal-handler and performs a non-local goto.
- X**
- X** ^RETURN-VALUE:
- X** None.
- X**
- X** ^ALGORITHM:
- X** Trivial.
- X***^^**********************************************************************/
- X#ifdef __ANSI_C__
- X static void pg_error( void )
- X#endif
- X{
- X signal( SIGPIPE, (void (*)())SIG_IGN );
- X longjmp( pg_recover, 1 );
- X}
- X
- X
- X/***************************************************************************
- X** ^FUNCTION: pg_pathname - get name of pager-program to use
- X**
- X** ^SYNOPSIS:
- X*/
- X#ifndef __ANSI_C__
- X static pager_t pg_pathname( pager_cmd )
- X/*
- X** ^PARAMETERS:
- X*/
- X char *pager_cmd;
- X/* -- name of the pager-program to verify
- X*/
- X#endif /* !__ANSI_C__ */
- X
- X/* ^DESCRIPTION:
- X** Pg_pathname will determine the name of the pager-program to attempt to
- X** open based on the values of pager_cmd, and $PAGER.
- X**
- X** ^REQUIREMENTS:
- X** pager_cmd must be non-null and be large enough to hold any of the
- X** possible pager program-names to be opened.
- X**
- X** ^SIDE-EFFECTS:
- X** pager_cmd is over-written with the name of the pager-command to
- X** try to open for output
- X**
- X** ^RETURN-VALUE:
- X** Returns PG_DFLT if /usr/ucb/more is to be used.
- X** Returns PG_ENV if $PAGER or <pager_cmd> is to be used.
- X**
- X** ^ALGORITHM:
- X** - If pager_cmd is executable then compare it to /usr/ucb/more
- X** return PG_ENV if not-equal, else return PG_DFLT
- X** - Else
- X** - pager_cmd = $PAGER
- X** - If $PAGER is executable then compare it to /usr/ucb/more
- X** return PG_ENV if not-equal, else return PG_DFLT
- X** - Else
- X** pager_cmd = /usr/ucb/more
- X** return PG_DFLT
- X** End-if
- X** End-if
- X***^^**********************************************************************/
- X#ifdef __ANSI_C__
- X static pager_t pg_pathname( char *pager_cmd )
- X#endif
- X{
- X char *pg_name = pager_cmd, *getenv();
- X pager_t pg_type;
- X
- X if ( Pager_Type != PG_NONE ) pg_type = Pager_Type;
- X
- X /* see if the given pager is okay */
- X if ( !pg_name || !*pg_name || access(pg_name, X_OK) ) {
- X pg_name = getenv("PAGER");
- X }
- X else {
- X pg_type = ( strcmp(pager_cmd, DEFAULT_PAGER) ) ? PG_ENV : PG_DFLT;
- X return pg_type;
- X }
- X
- X /* see if $PAGER is ok */
- X if ( !access(pg_name, X_OK) ) {
- X pg_type = ( strcmp(pg_name, DEFAULT_PAGER) ) ? PG_ENV : PG_DFLT;
- X strcpy( pager_cmd, pg_name );
- X }
- X else {
- X pg_type = PG_DFLT;
- X strcpy( pager_cmd, DEFAULT_PAGER );
- X }
- X
- X return pg_type;
- X}/* pg_pathname */
- X
- X
- X#endif /* USE_PAGER */
- END_OF_FILE
- if test 12598 -ne `wc -c <'pgopen.c'`; then
- echo shar: \"'pgopen.c'\" unpacked with wrong size!
- fi
- # end of 'pgopen.c'
- fi
- if test -f 'stest.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'stest.c'\"
- else
- echo shar: Extracting \"'stest.c'\" \(9296 characters\)
- sed "s/^X//" >'stest.c' <<'END_OF_FILE'
- X/*************************************************************************
- X** ^FILE: stest.c - test program for parseargs()
- X**
- X** ^DESCRIPTION:
- X** This file is the test program for the parseargs(3) function libarary.
- X** It is used to test parseargs for all command-line styles (which presently
- X** includes: UNIX, VMS, AmigaDOS, MS-DOS, and OS/2).
- X**
- X** ^HISTORY:
- X** --/--/-- Brad Appleton <brad@ssd.csd.harris.com>
- X** - Added structured block comments
- X** - Added an extra test for both old-style and new-style argument arrays
- X** - Added a test for triggers (ARGNOVAL arguments)
- X** - Added a test for arguments with optional values (using parsecntl())
- X** - Added arg-vector arguments
- X**
- X** --/--/-- Peter da Silva <peter@ferranti.com>
- X**
- X** --/--/-- Eric P. Allman <eric@Berkeley.EDU> Created
- X***^^**********************************************************************/
- X
- X#include <useful.h>
- X#include <parseargs.h>
- X
- X#ifdef vms
- X# include <ssdef.h>
- X#endif
- X
- XVERSIONID("$Header: stest.c,v 2.0 89/12/24 00:56:29 eric Exp $");
- X
- Xstatic char Mode[4] = "OFF";
- X
- X/***************************************************************************
- X** ^FUNCTION: argMine - example ARGNOVAL argument translation routine
- X**
- X** ^SYNOPSIS:
- X*/
- X#ifndef __ANSI_C__
- X BOOL argMine( ad, vp, copyf )
- X/*
- X** ^PARAMETERS:
- X*/
- X ARGDESC *ad;
- X/* -- the argument descriptor for this parameter.
- X*/
- X char *vp;
- X/* -- a pointer to the string input value.
- X*/
- X BOOL copyf;
- X/* -- if TRUE, the value will be destroyed later, and so should be
- X** copied if it will be retained (as for a string).
- X*/
- X#endif /* !__ANSI_C__ */
- X
- X/* ^DESCRIPTION:
- X** This routine is provided as a (very) simple example of how to use
- X** the ARGNOVAL flag to set up "trigger" arguments. Depending upon the
- X** implementation of the "trigger" function (this routine), the position
- X** of the corresponding argument on the command line may (or may not) be
- X** important.
- X**
- X** ^REQUIREMENTS:
- X** ad should have ARGNOVAL set and this function as its ad_type.
- X**
- X** ^SIDE-EFFECTS:
- X** The static global variable Mode is (re)written.
- X**
- X** ^RETURN-VALUE:
- X** TRUE.
- X**
- X** ^ALGORITHM:
- X** Trivial.
- X***^^**********************************************************************/
- X/*ARGSUSED*/
- X#ifdef __ANSI_C__
- X BOOL argMine( ARGDESC *ad, char *vp, BOOL copyf )
- X#endif
- X{
- X strcpy(Mode, "ON");
- X return TRUE;
- X}
- X
- X/*************************************************************************/
- X /* declare variables to hold values from the command-line */
- X#define DEF_STR "Default String"
- X
- Xtypedef ARGVEC_T(char *) strvec_t;
- X
- Xstatic int RepCount;
- Xstatic char *Name;
- Xstatic char *Str = DEF_STR;
- Xstatic char *DirName = ".";
- Xstatic BOOL XRated = FALSE;
- Xstatic BOOL XFlag = FALSE;
- Xstatic BOOL YFlag = TRUE;
- Xstatic BOOL ZFlag = FALSE;
- Xstatic char TabChar = ':';
- Xstatic ARGVEC_T(int) Integers = ARGVEC_EMPTY(int);
- Xstatic strvec_t Groups = ARGVEC_EMPTY(char *);
- Xstatic ArgList *Argv = (ArgList *)NULL;
- X
- X/*************************************************************************/
- X /* declare a new style argument-descriptor array */
- Xstatic
- XCMD_OBJECT
- X Cmd
- X
- XCMD_NAME
- X "stest -- test program for parseargs"
- X
- XCMD_DESCRIPTION
- X "This program is used to test parseargs for each desired command-line \
- Xstyle and for both old and new style argument-array declarations. The actual \
- Xname of the command will be <os>_test. parseargs will be called twice (with \
- Xthe same command-line description) in order to test both the old and the new \
- Xsyntax for declaring argument arrays."
- X
- XCMD_ARGUMENTS
- X 'n', ARGREQ|ARGPOS, argStr, __ &Name, "name (name to look for)",
- X 's', ARGVALOPT, argStr, __ &Str, "STRing (optional string to use)",
- X 'g', ARGVEC, argStr, __ &Groups, "newsGROUPS (newsgroups to test)",
- X 'c', ARGOPT, argInt, __ &RepCount, "REP=count (repeat count per group)",
- X 'd', ARGOPT, argStr, __ &DirName, "DIRname (work directory)",
- X 'i', ARGVEC, argInt, __ &Integers, "INTegerS (vector of numbers)",
- X '#', ARGHIDDEN, argBool, __ &XRated, "XratedMODE (naughty! naughty!)",
- X
- X 'x', ARGOPT, argSBool, __ &XFlag, "Xflag (set X flag)",
- X 'y', ARGOPT, argUBool, __ &YFlag, "Yflag (unset Y flag)",
- X 'z', ARGOPT, argTBool, __ &ZFlag, "Zflag (toggle Z flag)",
- X
- X 't', ARGOPT, argChar, __ &TabChar, "TAB=char (field delimiter)",
- X 'r', ARGNOVAL, argMine, __ NULL, "raw (trigger raw-mode \
- Xbefore processing any more arguments on the command-line)",
- X
- X ' ', ARGLIST, listStr, __ &Argv, "file (list of files)",
- X
- X END_ARGUMENTS
- XCMD_END
- X
- X
- X/*************************************************************************/
- X /* declare an old style argument-descriptor array */
- Xstatic ARGDESC Args[] =
- X{
- X STARTOFARGS,
- X
- X 'n', ARGREQ|ARGPOS, argStr, __ &Name, "name (name to look for)",
- X 's', ARGVALOPT, argStr, __ &Str, "STRing (optional string to use)",
- X 'g', ARGVEC, argStr, __ &Groups, "newsGROUPS (newsgroups to test)",
- X 'c', ARGOPT, argInt, __ &RepCount, "REP=count (repeat count per group)",
- X 'd', ARGOPT, argStr, __ &DirName, "DIRname (work directory)",
- X 'i', ARGVEC, argInt, __ &Integers, "INTegerS (vector of numbers)",
- X '#', ARGHIDDEN, argBool, __ &XRated, "XratedMODE (naughty! naughty!)",
- X
- X 'x', ARGOPT, argSBool, __ &XFlag, "Xflag (set X flag)",
- X 'y', ARGOPT, argUBool, __ &YFlag, "Yflag (unset Y flag)",
- X 'z', ARGOPT, argTBool, __ &ZFlag, "Zflag (toggle Z flag)",
- X
- X 't', ARGOPT, argChar, __ &TabChar, "TAB=char (field delimiter)",
- X 'r', ARGNOVAL, argMine, __ NULL, "raw (trigger raw-mode \
- Xbefore processing any more arguments on the command-line)",
- X
- X ' ', ARGLIST, listStr, __ &Argv, "file (list of files)",
- X
- X ENDOFARGS
- X};
- X
- X
- X/***************************************************************************
- X** ^FUNCTION: reset_args - reset argument values for another pass
- X**
- X** ^SYNOPSIS:
- X*/
- X#ifndef __ANSI_C__
- X static VOID reset_args()
- X#endif
- X/*
- X** ^PARAMETERS:
- X** None.
- X**
- X** ^DESCRIPTION:
- X** Reset_args resets all the argument values to their corresponding
- X** default values so that we can (re)test the parseargs library.
- X**
- X** ^REQUIREMENTS:
- X** None.
- X**
- X** ^SIDE-EFFECTS:
- X** All the static-global argument variables are rewritten.
- X**
- X** ^RETURN-VALUE:
- X** None.
- X**
- X** ^ALGORITHM:
- X** Trivial.
- X***^^**********************************************************************/
- X#ifdef __ANSI_C__
- X static void reset_args( void )
- X#endif
- X{
- X RepCount = 0;
- X Name = CHARNULL;
- X Str = DEF_STR;
- X DirName = ".";
- X XRated = FALSE;
- X XFlag = FALSE;
- X YFlag = TRUE;
- X ZFlag = FALSE;
- X TabChar = ':';
- X
- X vecFree(Integers, int);
- X vecDeepFree(Groups, char *);
- X listFree( Argv );
- X Argv = ARGLISTNULL;
- X}
- X
- X
- X/***************************************************************************
- X** ^FUNCTION: print_args - print current argument values
- X**
- X** ^SYNOPSIS:
- X*/
- X#ifndef __ANSI_C__
- X static void print_args( argd )
- X/*
- X** ^PARAMETERS:
- X*/
- X ARGDESC *argd;
- X/* -- the command whose arg-values are to be printed
- X*/
- X#endif /* !__ANSI_C__ */
- X
- X/* ^DESCRIPTION:
- X** Print the current values of all the command-line settings
- X**
- X** ^REQUIREMENTS:
- X** The command-line should have already been parsed by one of the
- X** Xparseargs functions.
- X**
- X** ^SIDE-EFFECTS:
- X** Prints on stdout.
- X**
- X** ^RETURN-VALUE:
- X** None.
- X**
- X** ^ALGORITHM:
- X** Trivial.
- X***^^**********************************************************************/
- X#ifdef __ANSI_C__
- X static void print_args( const ARGDESC *argd )
- X#endif
- X{
- X int i;
- X argMask_t flags;
- X ArgList *ls;
- X
- X printf( "Name = \"%s\", DirName = \"%s\", RepCount = %d,\n",
- X Name, DirName, RepCount );
- X
- X printf( "XFlag = %d, YFlag = %d, ZFlag = %d, TabChar='%c'(%03o);\n",
- X XFlag, YFlag, ZFlag, TabChar, TabChar );
- X
- X printf( "XRated=%d, Raw-Mode = \"%s\"\n", XRated, Mode );
- X
- X /* to call parsecntl() to see if the optional value was supplied */
- X i = parsecntl( (ARGDESC *)argd, pc_ARGFLAGS, pc_READ, "string", &flags);
- X
- X if ( BTEST(flags, ARGGIVEN) && !BTEST(flags, ARGVALGIVEN) ) {
- X printf("String=!No Value Given on CmdLine!\n" );
- X }
- X else {
- X printf("String=\"%s\"\n", Str);
- X }
- X
- X if (Groups.count) {
- X printf("Newsgroups:");
- X for (i = 0 ; i < Groups.count ; i++ ) {
- X printf(" %s", Groups.array[i]);
- X }
- X putchar('\n');
- X }
- X
- X if (Integers.count) {
- X printf("Integers:");
- X for (i = 0 ; i < Integers.count ; i++ ) {
- X printf(" %d", Integers.array[i]);
- X }
- X putchar('\n');
- X }
- X
- X if (Argv) printf("Remaining args: ");
- X for ( ls = Argv ; ls ; L_ADVANCE(ls) ) {
- X printf("%s", L_STRING(ls));
- X if ( L_NEXT(ls) ) {
- X putchar(' ');
- X }
- X else {
- X putchar('\n');
- X }
- X }/*for*/
- X}
- X
- X
- X/*ARGSUSED*/
- XMAIN(argc, argv)
- X{
- X parseargs(argv, Cmd); /* parse the command-line */
- X print_args(Cmd); /* print what we found */
- X
- X putchar('\n');
- X reset_args(); /* reset args for another pass */
- X
- X parseargs(argv, Args); /* parse same command-line using old-style argd */
- X print_args(Args); /* print what we found (should be same as before) */
- X
- X#ifdef vms
- X exit(SS$_NORMAL);
- X#else
- X exit(0); /* wave bye-bye */
- X#endif
- X}
- END_OF_FILE
- if test 9296 -ne `wc -c <'stest.c'`; then
- echo shar: \"'stest.c'\" unpacked with wrong size!
- fi
- # end of 'stest.c'
- fi
- if test -f 'unix_man.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'unix_man.c'\"
- else
- echo shar: Extracting \"'unix_man.c'\" \(8905 characters\)
- sed "s/^X//" >'unix_man.c' <<'END_OF_FILE'
- X/*************************************************************************
- X** ^FILE: unix_man.c - print manual templates for user command
- X**
- X** ^DESCRIPTION:
- X** This file is the portion of parseargs(1) that prints a Unix
- X** manual template of a given command on the standard output.
- X** The template is formatted for {n|t}roff using the -man macros.
- X**
- X** ^HISTORY:
- X** 27/08/91 Earl Chew <cechew@bruce.cs.monash.edu.au>
- X** - Use ProgNameLen when accessing ProgName
- X** - Use get_argpfx() to access names
- X**
- X** 01/02/91 Brad Appleton <brad@ssd.csd.harris.com> Created
- X***^^**********************************************************************/
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <useful.h>
- X#include "strfuncs.h"
- X
- X#define PARSEARGS_PRIVATE /* include private definitions */
- X#include "parseargs.h"
- X
- XEXTERN VOID syserr ARGS((const char *, ...));
- XEXTERN VOID usrerr ARGS((const char *, ...));
- X
- X#define MAXCOLS 65
- X#define VAL(str) ((str) ? str : "")
- X#define COMMENT printf(".\\\"-----------------------------------\n")
- X#define TH(title,len,section) printf(".TH %.*s %d\n", len, title, section )
- X#define SH(title) printf(".SH %s\n", title )
- X#define TP(cols,title) printf(".TP %d\n%s\n", cols, title )
- X#define PP printf(".PP\n" )
- X
- X
- X/***************************************************************************
- X** ^FUNCTION: fmtarg - format command-argument syntax
- X**
- X** ^SYNOPSIS:
- X*/
- X#ifndef __ANSI_C__
- X static int fmtarg( ad, buf )
- X/*
- X** ^PARAMETERS:
- X*/
- X ARGDESC *ad;
- X/* -- pointer to the argument to format
- X*/
- X char *buf;
- X/* -- character buffer to hold the formatted result
- X*/
- X#endif /* !__ANSI_C__ */
- X
- X/* ^DESCRIPTION:
- X** Fmtarg will determine the proper command-line syntax for the
- X** given argument and write the result to the given buffer.
- X**
- X** ^REQUIREMENTS:
- X** buf must be large enough to hold the formatted result (100 characters
- X** should do the trick).
- X**
- X** ^SIDE-EFFECTS:
- X** buf is overwritten.
- X**
- X** ^RETURN-VALUE:
- X** The number of printable characters in the argument-syntax-string
- X**
- X** ^ALGORITHM:
- X** Print argument usage based on whether or not the argument is
- X** positional, hidden, multi-valued (list or vector), etc ....
- X** Optional arguments and values are enclosed in square braces.
- X***^^**********************************************************************/
- X#ifdef __ANSI_C__
- X static int fmtarg( const ARGDESC *ad , char *buf )
- X#endif
- X{
- X /* buf must already be large enough */
- X char *pos;
- X argName_t name;
- X
- X (VOID) get_argname( arg_sname(ad), name );
- X
- X if (ARG_isPOSITIONAL(ad)) {
- X if ( ARG_isMULTIVAL(ad) ) {
- X sprintf( buf, "\\fI%s\\fP\\ ...", name );
- X return (strlen(name) + 4);
- X }/*if list*/
- X
- X sprintf( buf, "\\fI%s\\fP", name );
- X return strlen(name);
- X }/*if parm*/
- X
- X#ifdef SVR4
- X sprintf(buf, "\\f4\\-%c\\fP", arg_cname(ad));
- X#else
- X sprintf(buf, "\\fB\\-%c\\fP", arg_cname(ad));
- X#endif
- X pos = buf + strlen(buf);
- X
- X if ( ARG_isVALTAKEN(ad) && !ARG_isBOOLEAN(ad) && !ARG_isPSEUDOARG(ad) ) {
- X if ( ARG_isMULTIVAL(ad) ) {
- X if ( ARG_isVALOPTIONAL(ad) ) {
- X sprintf(pos, "\\ \\s-1[\\s+1\\fI%s\\fP\\ ...\\s-1]\\s+1", name);
- X return (strlen(name) + 9);
- X }/*if optarg*/
- X
- X sprintf( pos, "\\ \\fI%s\\ ...\\fP", name );
- X return (strlen(name) + 7);
- X }/*if list*/
- X
- X if ( ARG_isVALOPTIONAL(ad) ) {
- X sprintf( pos, "\\ \\s-1[\\s+1\\fI%s\\fP\\s-1]\\s+1", name );
- X return (strlen(name) + 5);
- X }/*if optarg*/
- X
- X sprintf( pos, "\\ \\fI%s\\fP", name );
- X return (strlen(name) + 3);
- X }/*if*/
- X
- X return 2;
- X}
- X
- X
- X/***************************************************************************
- X** ^FUNCTION: manpage - print the manual template
- X**
- X** ^SYNOPSIS:
- X*/
- X#ifndef __ANSI_C__
- X VOID manpage ( argd )
- X/*
- X** ^PARAMETERS:
- X*/
- X ARGDESC *argd;
- X/* -- the command-argdesc-array
- X*/
- X#endif /* !__ANSI_C__ */
- X
- X/* ^DESCRIPTION:
- X** Manpage print on standard output, a Unix manual template for the
- X** given command. The NAME, SYNOPSIS, and OPTIONS sections are filled
- X** in and the DESCRIPTION section is partially filled in with any
- X** known command-description. The FILES, SEE ALSO, DIAGNOSTICS, CAVEATS,
- X** BUGS, AUTHOR, and HISTORY section titles are provided but the body
- X** of each section must be composed by the documentor.
- X**
- X** ^REQUIREMENTS:
- X** Argd should be a valid command-line descriptor array.
- X**
- X** ^SIDE-EFFECTS:
- X** Prints on standard-output.
- X**
- X** ^RETURN-VALUE:
- X** None.
- X**
- X** ^ALGORITHM:
- X** - print .TH setting followed by NAME section.
- X** - cycle through each argument and print is syntax for the SYNOPSIS.
- X** - print the description (if it exists).
- X** - cycle through each argument again and print its syntax and description
- X** for the OPTIONS section.
- X** - print just the headings for the remaining sections.
- X***^^**********************************************************************/
- X#ifdef __ANSI_C__
- X void manpage( const ARGDESC *argd )
- X#endif
- X{
- X register CONST ARGDESC *ad, *args, *cmd;
- X argName_t name;
- X CONST char *program, *purpose, *description;
- X int len, maxlen, positionals, namelen, programlen, purposelen;
- X
- X /* allow null argument descriptor */
- X if ( !argd ) return;
- X
- X if ( !CMD_isINIT(argd) ) init_args( (ARGDESC *)argd );
- X cmd = argd;
- X
- X name[0] = 0;
- X namelen = 0;
- X if ( cmd_name(cmd) ) {
- X (VOID) strcpy( name, cmd_name(cmd) );
- X if ( !BTEST(cmd_state(cmd), ps_USERNAME|ps_FREENAME) ) {
- X namelen = get_argpfx( name );
- X name[namelen] = 0;
- X }
- X else {
- X namelen = strlen( cmd_name(cmd) );
- X }
- X }
- X
- X program = 0;
- X programlen = 0;
- X if ( cmd_name(cmd) ) {
- X program = cmd_name(cmd);
- X programlen = namelen;
- X }
- X else if ( cmd_argv0(cmd) ) {
- X program = cmd_argv0(cmd);
- X programlen = strlen(program);
- X }
- X
- X purpose = cmd_purpose(cmd);
- X if ( !BTEST(cmd_state(cmd), ps_USERPURPOSE|ps_FREEPURPOSE) && purpose ) {
- X purpose = get_argdesc(purpose, &purposelen);
- X }
- X else {
- X purposelen = strlen(VAL(purpose));
- X }
- X description = cmd_description(cmd);
- X
- X printf(".\\\"---------- TO PRINT, USE: {n,t}roff -man file ----------\n");
- X printf(".if n .po 1\n");
- X printf(".if n .ll 78\n");
- X
- X COMMENT;
- X#ifdef SVR4
- X TH( name, namelen, 1 );
- X#else
- X TH( strupr(name), namelen, 1 );
- X#endif
- X
- X COMMENT;
- X SH( "NAME" );
- X printf( "%s \\- %.*s\n", VAL(program), purposelen, VAL(purpose) );
- X
- X COMMENT;
- X SH( "SYNOPSIS" );
- X
- X len = strlen( program ) + 1;
- X#ifdef SVR4
- X sprintf( name, "\\f4%.*s\\fP", programlen, program );
- X#else
- X sprintf( name, "\\fB%.*s\\fP", programlen, program );
- X#endif
- X TP( len, name );
- X
- X maxlen = 0;
- X for ( positionals = 0 ; positionals < 2 ; positionals++ ) {
- X for ( args = argd ; args ; args = cmd_defargs(args) ) {
- X for ( ad = ARG_FIRST(args) ; !ARG_isEND(ad) ; ARG_ADVANCE(ad) ) {
- X argName_t buf;
- X
- X /* don't display hidden arguments */
- X if ( ARG_isHIDDEN(ad) ) continue;
- X if ( !positionals && ARG_isPOSITIONAL(ad) ) continue;
- X if ( positionals && !ARG_isPOSITIONAL(ad) ) continue;
- X
- X len = fmtarg( ad, buf );
- X if ( len > maxlen ) maxlen = len;
- X
- X if ( ARG_isREQUIRED(ad) ) {
- X printf( "%s\n", buf );
- X }
- X else {
- X printf( "[%s]\n", buf );
- X }
- X }/*for each ad */
- X }/* for each argd */
- X }/* for each parm-type */
- X
- X COMMENT;
- X SH( "DESCRIPTION" );
- X PP;
- X indent_para(stdout, MAXCOLS, 0, "", 0, VAL(description), 0);
- X
- X COMMENT;
- X SH( "OPTIONS" );
- X
- X for ( positionals = 0 ; positionals < 2 ; positionals++ ) {
- X for ( args = argd ; args ; args = cmd_defargs(args) ) {
- X for ( ad = ARG_FIRST(args) ; !ARG_isEND(ad) ; ARG_ADVANCE(ad) ) {
- X argName_t buf;
- X char *desc;
- X int desclen;
- X
- X /* don't display hidden arguments */
- X if ( ARG_isHIDDEN(ad) ) continue;
- X if ( !positionals && ARG_isPOSITIONAL(ad) ) continue;
- X if ( positionals && !ARG_isPOSITIONAL(ad) ) continue;
- X
- X (VOID) fmtarg( ad, buf );
- X TP( maxlen + 2, buf );
- X desc = get_argdesc(arg_description(ad), &desclen);
- X indent_para(stdout, MAXCOLS, 0, "", 0, desc, desclen);
- X }/*for each ad */
- X }/* for each argd */
- X }/* for each parm-type */
- X
- X COMMENT;
- X SH( "FILES" );
- X PP;
- X
- X COMMENT;
- X SH( "ENVIRONMENT" );
- X PP;
- X
- X COMMENT;
- X SH( "SEE ALSO" );
- X PP;
- X
- X COMMENT;
- X SH( "DIAGNOSTICS" );
- X PP;
- X
- X COMMENT;
- X SH( "CAVEATS" );
- X PP;
- X
- X COMMENT;
- X SH( "BUGS" );
- X PP;
- X
- X COMMENT;
- X SH( "AUTHOR" );
- X PP;
- X
- X COMMENT;
- X SH( "HISTORY" );
- X PP;
- X}
- END_OF_FILE
- if test 8905 -ne `wc -c <'unix_man.c'`; then
- echo shar: \"'unix_man.c'\" unpacked with wrong size!
- fi
- # end of 'unix_man.c'
- fi
- if test -f 'useful.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'useful.h'\"
- else
- echo shar: Extracting \"'useful.h'\" \(8507 characters\)
- sed "s/^X//" >'useful.h' <<'END_OF_FILE'
- X/*************************************************************************
- X** ^FILE: useful.h - various definitions of general interest
- X**
- X** ^DESCRIPTION:
- X** This file #defines several macros that are either of very general
- X** use, or that assist in writing portable programs between various
- X** systems and/or compilers.
- X**
- X** ^HISTORY:
- X** --/--/-- Brad Appleton <brad@ssd.csd.harris.com>
- X** - Added OS specific #defines for unix, SYSV, BSD, etc ...
- X** - Added structured block comments
- X** - Added varargs/stdarg macros
- X** - Added BSET, BCLEAR, BTEST macros for handling bitmasks
- X** - #defined EXTERN to be extern "C" for C++
- X** - Added #defines for STDIN, STDOUT, and STDERR file descriptors
- X**
- X** --/--/-- Peter da Silva <peter@ferranti.com>
- X**
- X** --/--/-- Eric P. Allman <eric@Berkeley.EDU> Created
- X***^^**********************************************************************/
- X
- X/* $Header: useful.h,v 2.0 89/12/24 00:56:33 eric Exp $ */
- X
- X#ifndef _USEFUL_H_
- X#define _USEFUL_H_
- X
- X#if (defined(_unix) || defined(__unix) || defined(_unix_) || defined(__unix__))
- X# ifndef unix
- X# define unix
- X# endif
- X#endif /* _unix */
- X
- X#if (defined(_UNIX) || defined(__UNIX) || defined(_UNIX_) || defined(__UNIX__))
- X# ifndef unix
- X# define unix
- X# endif
- X#endif /* _UNIX */
- X
- X /* give a stab at the dual Unix universe dilemma (UCB vs AT&T) */
- X#ifdef unix
- X# if ( defined(_BSD) && !defined(BSD) )
- X# define BSD
- X# endif
- X# if ( defined(_SYSV) && !defined(SYSV) )
- X# define SYSV
- X# endif
- X
- X# ifndef BSD
- X# ifdef sun
- X# define BSD
- X# endif
- X# if ( defined(apollo) || defined(aegis) )
- X# define BSD
- X# endif
- X# if ( defined(_CX_UX) && defined(ucb_universe) )
- X# define BSD
- X# endif
- X# if ( defined(VAX_BSD) || defined(ULTRIX) || defined(ultrix) )
- X# define BSD
- X# endif
- X# if ( defined(DYNIX) || defined(dynix) )
- X# define BSD
- X# endif
- X# if ( defined(UTX) || defined(utx) )
- X# define BSD
- X# endif
- X# endif /* !BSD */
- X
- X# ifndef SYSV
- X# ifdef mips
- X# define SYSV
- X# endif
- X# ifdef DGUX
- X# define SYSV
- X# endif
- X# if ( defined(_CX_UX) && defined(att_universe) )
- X# define SYSV
- X# endif
- X# if ( defined(hpux) || defined(HPUX) )
- X# define SYSV
- X# endif
- X# if ( defined(irix) || defined(IRIX) )
- X# define SYSV
- X# endif
- X# if ( defined(aix) || defined(AIX) )
- X# define SYSV
- X# endif
- X# endif /* !SYSV */
- X#endif /* unix */
- X
- X#ifndef MSDOS
- X# if (defined(_MSDOS_)||defined(__MSDOS__)||defined(_MSDOS)||defined(__MSDOS))
- X# define MSDOS
- X# endif
- X#endif
- X
- X#ifndef OS2
- X# if ( defined(_OS2_) || defined(__OS2__) || defined(_OS2) || defined(__OS2) )
- X# define OS2
- X# endif
- X#endif
- X
- X#ifndef AmigaDOS
- X# if ( defined(AMIGA) || defined(MANX) || defined(AZTEC) )
- X# define AmigaDOS
- X# endif
- X#endif /* AmigaDOS */
- X
- X
- X#ifdef __STDC__
- X# include <stddef.h>
- X# include <stdlib.h>
- X#endif
- X
- X#if ( !defined(__STDC__) && defined(vms) )
- X# include <stdlib.h>
- X#endif
- X
- X#ifndef FILE
- X# include <stdio.h>
- X#endif
- X
- X#ifndef STDIN
- X# define STDIN 0
- X# define STDOUT 1
- X# define STDERR 2
- X#endif
- X
- X /* macros to portably convert character case */
- X#define TOUPPER(c) ( islower(c) ) ? toupper(c) : (c)
- X#define TOLOWER(c) ( isupper(c) ) ? tolower(c) : (c)
- X
- X /* give a stab at the multiple-language dilemma */
- X#ifdef __STDC__
- X# define ARGS(x) x
- X# define NOARGS ( void )
- X# define __ANSI_C__
- X#else
- X# if defined(c_plusplus) || defined(__cplusplus)
- X# define ARGS(x) x
- X# define NOARGS ()
- X# define __ANSI_C__
- X# else
- X# define ARGS(x) ()
- X# define NOARGS ()
- X# endif
- X#endif
- X
- X /* give a stab at the variable arguments dilemma --BDA */
- X#ifdef __STDC__
- X# ifndef va_arg
- X# include <stdarg.h>
- X# endif
- X# define VA_START(ap,last) va_start(ap, last)
- X# define VA_ARG(ap,type) va_arg(ap, type)
- X# define VA_END(ap) va_end(ap)
- X#else
- X# ifndef va_arg
- X# include <varargs.h>
- X# endif
- X# define VA_START(ap,last) va_start(ap)
- X# define VA_ARG(ap,type) va_arg(ap, type)
- X# define VA_END(ap) va_end(ap)
- X#endif
- X
- X#ifndef VOID
- X# if ( defined(__ANSI_C__) || !defined(NOVOID) )
- X# define VOID void
- X# else
- X# define VOID int
- X# endif
- X#endif
- X
- X#ifndef TRUE
- X# define TRUE 1
- X# define FALSE 0
- X#endif
- X
- X#ifndef STATIC
- X# ifndef NODEBUG
- X# define STATIC
- X# else
- X# define STATIC static
- X# endif
- X#endif
- X
- X#ifndef EXTERN
- X# if defined(c_plusplus) || defined(__cplusplus)
- X# define EXTERN extern "C"
- X# else
- X# define EXTERN extern
- X# endif
- X#endif
- X
- X#ifndef CONST
- X# ifdef __ANSI_C__
- X# define CONST const
- X# else
- X# define CONST
- X# endif
- X#endif
- X
- X#ifndef NULL
- X# define NULL 0
- X#endif
- X
- X#ifndef CHARNULL
- X# define CHARNULL ((char *) NULL)
- X#endif
- X
- X#ifndef FILENULL
- X# define FILENULL ((FILE *) NULL)
- X#endif
- X
- X#if ( defined(__ANSI_C__) || defined(vms) )
- X typedef void *ARBPTR;
- X#else
- X typedef char *ARBPTR;
- X#endif
- X
- X#define __ (ARBPTR)
- X#define ARBNULL (__ NULL)
- X
- X#ifndef BOOL
- X typedef char BOOL;
- X#endif
- X
- X#ifdef lint
- X# define VERSIONID(v)
- X#else
- X# define VERSIONID(v) static char _Version[] = v
- X#endif
- X
- X /* keep BITSET for compatibilty
- X ** but use BSET, BCLEAR, etc... instead --BDA
- X */
- X#define BITSET(bstr,mask) ( ((bstr) & (mask)) != 0 )
- X
- X#define BTEST(bstr,mask) ( ((bstr) & (mask)) != 0 )
- X#define BSET(bstr,mask) (bstr) |= (mask)
- X#define BCLEAR(bstr,mask) (bstr) &= ~(mask)
- X
- X#ifndef __STRING_H
- X# define __STRING_H
- X EXTERN char *strcat ARGS(( char *, const char * ));
- X EXTERN char *strncat ARGS(( char *, const char *, int ));
- X EXTERN int strcmp ARGS(( const char *, const char * ));
- X EXTERN int strncmp ARGS(( const char *, const char *, int ));
- X EXTERN char *strcpy ARGS(( char *, const char * ));
- X EXTERN char *strncpy ARGS(( char *, const char *, int ));
- X EXTERN int strlen ARGS(( const char * ));
- X
- X# ifndef BSD
- X# define index(s,c) strchr(s,c)
- X# define rindex(s,c) strrchr(s,c)
- X EXTERN char *strchr ARGS(( const char *, int ));
- X EXTERN char *strrchr ARGS(( const char *, int ));
- X EXTERN char *strpbrk ARGS(( const char *, const char * ));
- X EXTERN int strspn ARGS(( const char *, const char * ));
- X EXTERN int strcspn ARGS(( const char *, const char * ));
- X EXTERN char *strtok ARGS(( char *, const char * ));
- X
- X# else
- X# define strchr(s,c) index(s,c)
- X# define strrchr(s,c) rindex(s,c)
- X EXTERN char *index ARGS(( const char *, int ));
- X EXTERN char *rindex ARGS(( const char *, int ));
- X# endif /* !BSD */
- X
- X# ifndef BSD
- X# define bcmp(b1,b2,n) memcmp(b1,b2,n)
- X# define bcopy(b1,b2,n) memcpy(b2,b1,n)
- X# define bzero(b,n) memset(b,'\0',n)
- X# ifndef __MEMORY_H
- X# define __MEMORY_H
- X EXTERN ARBPTR memccpy ARGS(( ARBPTR, const ARBPTR, int, int ));
- X EXTERN ARBPTR memchr ARGS(( ARBPTR, int, int ));
- X EXTERN int memcmp ARGS(( const ARBPTR, const ARBPTR, int ));
- X EXTERN ARBPTR memcpy ARGS(( ARBPTR, const ARBPTR, int ));
- X EXTERN ARBPTR memmove ARGS(( ARBPTR, const ARBPTR, int ));
- X EXTERN ARBPTR memset ARGS(( ARBPTR, int, int ));
- X# endif /* __MEMORY_H */
- X
- X# else
- X# define memcmp(b1,b2,n) bcmp(b1,b2,n)
- X# define memcpy(b1,b2,n) bcopy(b2,b1,n)
- X# ifndef __BSTRING_H
- X# define __BSTRING_H
- X EXTERN VOID bcopy ARGS(( const ARBPTR, ARBPTR, int ));
- X EXTERN int bcmp ARGS(( const ARBPTR, const ARBPTR, int ));
- X EXTERN VOID bzero ARGS(( ARBPTR, int ));
- X EXTERN int ffs ARGS(( int ));
- X# endif /* __BSTRING_H */
- X# endif /* !BSD */
- X#endif /* __STRING_H */
- X
- X#if ( !defined(__ANSI_C__) && !defined(_SIZE_T_DEFINED) )
- X# if (defined(sun) && defined(BSD))
- X# include <sys/types.h>
- X# if (!defined (__sys_stdtypes_h) && !defined(_TYPES_))
- X /* size_t is also defined in <sys/stdtypes.h> in SunOS 4.1
- X ** and int <types.h> in SunOS 4.0.3
- X */
- X typedef int size_t;
- X# endif
- X# define _SIZE_T_DEFINED 1
- X# endif /* sun */
- X# if (defined(vms) && defined(__STDDEF_LOADED))
- X# define _SIZE_T_DEFINED 1
- X# endif /* vms */
- X# ifndef _SIZE_T_DEFINED
- X typedef unsigned int size_t;
- X# define _SIZE_T_DEFINED 1
- X# endif /* !_SIZE_T_DEFINED */
- X#endif
- X
- X#if ( !defined(__malloc_h) && !defined(__MALLOC_H) && !defined(vms) )
- X# include <malloc.h>
- X#else
- X EXTERN ARBPTR malloc ARGS(( size_t ));
- X EXTERN ARBPTR realloc ARGS(( ARBPTR, size_t ));
- X EXTERN VOID free ARGS(( ARBPTR ));
- X#endif /*__malloc_h*/
- X
- XEXTERN ARBPTR ckalloc ARGS(( size_t ));
- XEXTERN VOID exit ARGS(( int ));
- X
- X#define MAXINPUTLINE 200 /* maximum string input line */
- X#define MAXWORDLEN 100 /* maximum word (token) length */
- X
- X#endif /* _USEFUL_H_ */
- END_OF_FILE
- if test 8507 -ne `wc -c <'useful.h'`; then
- echo shar: \"'useful.h'\" unpacked with wrong size!
- fi
- # end of 'useful.h'
- fi
- echo shar: End of archive 4 \(of 10\).
- cp /dev/null ark4isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 10 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
- exit 0 # Just in case...
-