chiark / gitweb /
Manpages: Move manpages (back?) into the top-level directory.
[mLib] / mdwopt.3
diff --git a/mdwopt.3 b/mdwopt.3
new file mode 100644 (file)
index 0000000..11111aa
--- /dev/null
+++ b/mdwopt.3
@@ -0,0 +1,433 @@
+.\" -*-nroff-*-
+.TH mdwopt 3 "6 July 1999" "Straylight/Edgeware" "mLib utilities library"
+.SH "NAME"
+mdwopt \- command-line option parser
+.\" @mdwopt
+.SH "SYNOPSIS"
+.nf
+.B "#include <mLib/mdwopt.h>"
+
+.BI "int mdwopt(int " argc ", char *const *" argv ,
+.BI "           const char *" shortopt ,
+.BI "           const struct option *" longopt ", int *" longind ,
+.BI "           mdwopt_data *" data ", int " flags );
+
+.BI "int getopt(int " argc ", char *const *" argv ", const char *" o );
+
+.BI "int getopt_long(int " argc ", char *const *" argv ,
+.BI "                const char * "shortopt ,
+.BI "                const struct option *" longopt ", int *" longind );
+
+.BI "int getopt_long_only(int " argc ", char *const *" argv ,
+.BI "                    const char * "shortopt ,
+.BI "                    const struct option *" longopt ", int *" longind );
+.fi
+.SH "OVERVIEW"
+The
+.B mdwopt
+function is a command line options parser which is (mostly) compatible
+with the standard POSIX and GNU
+.B getopt
+functions, although provides more features than either.  It's not the
+most featureful options parser around, but it's good enough for my
+purposes at the moment.
+.SH "OPTION SYNTAX"
+A command line consists of a number of
+.I words
+(which may contain spaces, according to various shell quoting
+conventions).  A word may be an option, an argument to an option, or a
+non-option.  An option begins with a special character, usually
+.RB ` \- ',
+although
+.RB ` + '
+is also used sometimes.  As special exceptions, the word containing only
+a
+.RB ` \- '
+is considered to be a non-option, since it usually represents standard
+input or output as a filename, and the word containing only a
+double-dash
+.RB ` \-\- '
+is used to mark all following words as being non-options regardless of
+their initial character.
+.PP
+Traditionally, all words after the first non-option have been considered
+to be non-options automatically, so that options must be specified
+before filenames.  However, this implementation can extract all the
+options from the command line regardless of their position.  This can
+usually be disabled by setting one of the environment variables
+.B POSIXLY_CORRECT
+or
+.BR _POSIX_OPTION_ORDER .
+.PP
+There are two different styles of options:
+.I short
+and
+.IR long .
+Traditional Unix (and POSIX) only uses short options.  The long options
+are a GNU convention.
+.SS "Short option syntax"
+Short options are the sort which Unix has known for ages: an option is a
+single letter, preceded by a
+.RB ` \- '.
+Short options can be joined together to save space (and possibly to make
+silly words): e.g., instead of giving options
+.RB ` "\-x \-y" ',
+a user could write
+.RB ` \-xy '.
+Some short options can have arguments which appear after the option
+letter, either immediately following, or in the next word; so an option
+with an argument could be written as
+.RB ` "\-o foo" '
+or as
+.RB ` \-ofoo ').
+Note that options with optional arguments must be written in the second
+style.
+.PP
+When a short option controls a flag setting, it is sometimes possible to
+explicitly turn the flag off, as well as turning it on, (usually to
+override default options).  This is usually done by using a
+.RB ` + '
+instead of a
+.RB ` \- '
+to introduce the option.  (Some programs use upper-case option letters
+to indicate this instead.)
+.SS "Long option syntax"
+Long options, as popularized by the GNU utilities, are given long-ish
+memorable names, preceded by a double-dash
+.RB ` \-\- '.
+Since their names are more than a single character, long options can't
+be combined in the same way as short options.  Arguments to long options
+may be given either in the same word, separated from the option name by
+an equals sign, or in the following word.
+.PP
+Long option names can be abbreviated if necessary, as long as the
+abbreviation is unique.  This means that options can have sensible and
+memorable names but still not require much typing from an experienced
+user.
+.PP
+Like short options, long options can control flag settings.  The options
+to manipulate these settings come in pairs: an option of the form
+.RB ` \-\-set\-flag '
+might set the flag, while an option of the form
+.RB ` \-\-no\-set\-flag '
+might clear it.
+.PP
+It is usual for applications to provide both short and long options with
+identical behaviour.  Some applications with lots of options may only
+provide long options (although they will often be only two or three
+characters long).  In this case, long options can be preceded with a
+single
+.RB ` \- '
+character, and negated by a
+.RB ` + '
+character.
+.SS "Numerical options"
+Finally, some (older) programs accept arguments of the form
+.RB ` \- \c
+.IR number ',
+to set some numerical parameter, typically a line count of some kind.
+.SH "PARSING OPTIONS WITH \fBmdwopt\fP"
+An application parses its options by calling
+.B mdwopt
+repeatedly.  Each time it is called,
+.B mdwopt
+returns a value describing the option just read, and stores information
+about the option in a data block.
+.PP
+The data block is a structure containing at least the following members:
+.TP
+.B "char *arg"
+Pointer to the argument of the current option, or null.  Argument
+strings persist for as long as the underlying command line argument
+array
+.I argv
+does, so it's usually safe just to remember the pointer.
+.TP
+.B "int opt"
+Value of the current option
+.TP
+.B "int ind"
+Must be initialized to 0 before the first call to
+.BR mdwopt .
+After the last call, it is the index into
+.I argv
+of the first nonoption argument.
+.TP
+.B "int err"
+Set to nonzero to allow
+.B mdwopt
+to emit error messages about illegal option syntax.  (This would be a
+flag setting, but it has to be here for
+.B getopt
+compatibility.)
+.TP
+.B "char *prog"
+Contains the program's name, stripped of any path prefix.  This is an
+obsolete feature: the
+.BR quis (3)
+module does the job in a more sensible way.
+.PP
+Prior to the first call to
+.BR mdwopt ,
+the
+.B err
+and
+.B ind
+members of the structure must be initialized.
+.PP
+The arguments
+.I argc
+and
+.I argv
+describe the command-line argument array which is to be parsed.  These
+will usually be exactly the arguments passed to the program's
+.B main
+function.
+.SS "Short option parsing"
+Short options are described by a string,
+.IR shortopt ,
+which once upon a time just contained the permitted option characters.
+Now the options string begins with a collection of flag characters, and
+various flag characters can be put after options characters to change
+their properties.
+.PP
+If the first character of the short options string is
+.RB ` + ',
+.RB ` \- '
+or
+.RB ` ! ',
+the order in which options are read is modified, as follows:
+.TP
+.RB ` + '
+Forces the POSIX order to be used. As soon as a non-option is found,
+.B mdwopt
+returns \-1.
+.TP
+.RB ` \- '
+Makes
+.B mdwopt
+treat non-options as being `special' sorts of option. When a non-option
+word is found, the value 0 is returned, and the actual text of the word
+is stored as being the option's argument.
+.TP
+.RB ` ! '
+forces the default order to be used regardless of environment variable
+settings.  The entire command line is scanned for options, which are
+returned in order.  However, during this process, the options are moved
+in the
+.I argv
+array, so that they appear before the non-options.
+.PP
+A
+.RB ` : '
+character may be placed after the ordering flag (or at the very
+beginning if no ordering flag is given) which indicates that the
+character
+.RB ` : ',
+rather than
+.RB ` ? ',
+should be returned if a missing argument error is detected.
+.PP
+Each option in the string can be followed by a
+.RB ` + '
+sign, indicating that it can be negated, a
+.RB ` : '
+sign indicating that it requires an argument, or a
+.RB ` :: '
+string, indicating an optional argument.  Both
+.RB ` + '
+and one of
+.RB ` : '
+or
+.RB ` :: '
+may be given, although the
+.RB ` + '
+must come first.
+.PP
+If an option is found, the option character is returned to the caller.
+A pointer to an argument is stored in the
+.B arg
+member of the data block; a null pointer is stored if there was no
+argument.  If a negated option was found, the option character is
+returned ORed with
+.B OPTF_NEGATED
+(bit 8 set).
+.SS "Long option parsing"
+Long options are described in a table.  Each entry in the
+table is of type
+.BR "struct option" ,
+which contains the following members (in order):
+.TP
+.B "const char *name"
+Pointer to the option's name.
+.TP
+.B "int has_arg"
+A flags word describing the option.  (The name is historical.)
+.TP
+.B "int *flag"
+Address of the flag variable to use when this option is matched.
+.TP
+.B "int val"
+Value to store or return when this option is matched.
+.PP
+The table is terminated by an entry whose
+.B name
+field is a null pointer.
+.PP
+When
+.B mdwopt
+finds a long option, it looks the name up in the table. The index of the
+matching entry is stored in the
+.I longind
+variable, passed to
+.B mdwopt
+(unless
+.I longind
+is null): a value of \-1 indicates that no long option was found. The
+behaviour is then dependent on the values in the table entry.
+.PP
+If the flag bit
+.B OPTF_ARGREQ
+is set in
+.B has_arg
+then the option has a required argument, which may be separated from the
+option name by an equals sign or placed in the following word.  If the
+flag bit
+.B OPTF_ARGOPT
+is set then the argument is optional.  If present, the argument must be
+in the same word as the option name, separated by an equals sign.  It is
+an error for both flags to be set; if neither is set then the option
+does not take an argument.
+.PP
+If
+.B flag
+is nonzero, it points to an integer to be modified by
+.BR mdwopt .
+Usually the value in the
+.B val
+field is simply stored in the
+.B flag
+variable. If the flag
+.B OPTF_SWITCH
+is set in the
+.B has_arg
+member, however, the value is combined with the existing value of the
+flags using a bitwise OR.  If
+.B OPTF_NEGATE
+is set in the
+.B has_arg
+field, then the flag bit will be cleared if a matching negated long
+option is found.  The value 0 is returned.
+.PP
+If
+.B flag
+is zero, the value in
+.B val
+is returned by
+.BR mdwopt ,
+possibly with bit 8 set if the option was
+negated.
+.PP
+Arguments from long options are stored in the
+.B arg
+member of the data block.
+.SS "Other optional features"
+The
+.I flags
+argument contains a bitmask of features which may be enabled:
+.TP
+.B OPTF_NOLONGS
+Don't allow any long options.  This makes
+.B mdwopt
+compatible with traditional Unix
+.BR getopt .
+.TP
+.B OPTF_NOSHORTS
+A slightly misnamed flag.  Short options are read normally.  However,
+long options may also begin with a single dash
+.RB ` \- '
+(or the
+.RB ` + '
+sign if negated).  Long options may not be combined with short options:
+an option word which begins with a short option must contain only short
+options.
+.TP
+.B OPTF_NUMBERS
+Read numeric options.  If a numeric option is found, the character
+.RB ` # '
+is returned and the text of the number is stored in the
+.B arg
+member of the data block.
+.TP
+.B OPTF_NEGATION
+Allow negation of options.  Negated options are returned ORed with
+.BR OPTF_NEGATED .
+.TP
+.B OPTF_ENVVAR
+Options will be read from an environment variable before scanning the
+actual command line provided.  The name of the environment variable is
+found by capitalizing the program name.  (This allows a user to have
+different default settings for a program, by calling it through
+different symbolic links.)
+.TP
+.B OPTF_NOPROGNAME
+Don't read the program name from
+.IR argv \c
+.BR [0] ,
+and don't set the
+.B prog
+data block member.  Options start right at the beginning of
+.IR argv .
+.TP
+.B OPTF_NEGNUMBER
+Allow negated numeric options.  Negated numeric options begin with a
+.RB ` + '
+rather than a
+.RB ` \- '.
+The return value is
+.RB ` # ' " | OPTF_NEGATED" .
+.SS "Compatibility features"
+The macros
+.BR getopt ,
+.B getopt_long
+and
+.B getopt_long_only
+correspond to calls to
+.B mdwopt
+with various flag settings.  See the macro definitions for the actual
+mappings, and the documentation for the functions to see how they're
+meant to work.
+.PP
+Additionally, there is a global data block, which is specified by
+passing a null
+.I data
+argument to
+.BR mdwopt .
+The members of this block may be referred to by their traditional names:
+.TP
+.B optarg
+The argument of the current option.
+.TP
+.B optopt
+Option code of the current option.
+.TP
+.B opterr
+Nonzero if
+.B mdwopt
+is to report errors.  This is the default.
+.TP
+.B optind
+Index of the first non-option argument.
+.TP
+.B optprog
+Name of the program, stripped of path prefix.
+.PP
+These names aren't considered deprecated: they help make the code easier
+to read by people used to the traditional
+.B getopt
+function.
+.SH "SEE ALSO"
+.BR getopt (3),
+.BR mLib (3).
+.SH "AUTHOR"
+Mark Wooding, <mdw@distorted.org.uk>