.\" -*-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 " .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,