A special function is provided to break (parse) the command line into options, and to check them for validity. It uses the GNU getopt routines (see getopt in The GNU C Library Reference Manual).
The getopt
function parses the command line arguments, as
supplied by argc and argv. The argc argument is the
argument count, and argv is an opaque data structure,
representing the array of arguments9. The operator vaptr
(see vaptr) is
provided to initialize this argument.
An argument that starts with ‘-’ (and is not exactly ‘-’ or ‘--’), is an option element. An argument that starts with a ‘-’ is called short or traditional option. The characters of this element, except for the initial ‘-’ are option characters. Each option character represents a separate option. An argument that starts with ‘--’ is called long or GNU option. The characters of this element, except for the initial ‘--’ form the option name.
Options may have arguments. The argument to a short option is supplied immediately after the option character, or as the next word in command line. E.g., if option -f takes a mandatory argument, then it may be given either as -farg or as -f arg. The argument to a long option is either given immediately after it and separated from the option name by an equals sign (as --file=arg), or is given as the next word in the command line (e.g. --file arg).
If the option argument is optional, i.e. it may not necessarily be given, then only the first form is allowed (i.e. either -farg or --file=arg.
The ‘--’ command line argument ends the option list. Any arguments following it are not considered options, even if they begin with a dash.
If getopt
is called repeatedly, it returns successively each of
the option characters from each of the option elements (for short
options) and each option name (for long options). In this case, the
actual arguments are supplied only to the first invocation.
Subsequent calls must be given two nulls as arguments. Such
invocation instructs getopt
to use the values saved on the
previous invocation.
When the function finds another option, it returns its character or name
updating the external variable optind
(see below) so that the
next call to getopt
can resume the scan with the following
option.
When there are no more options left, or a ‘--’ argument is
encountered, getopt
returns an empty string. Then
optind
gives the index in argv of the first element that
is not an option.
The legitimate options and their characteristics are supplied in
additional arguments to getopt
. Each such argument is a string
consisting of two parts, separated by a vertical bar (‘|’). Any
one of these parts is optional, but at least one of them must be
present. The first part specifies short option character. If it is
followed by a colon, this character takes mandatory argument. If it
is followed by two colons, this character takes an optional argument.
If only the first part is present, the ‘|’ separator may be
omitted. Examples:
Short option -c.
Short option -f, taking a mandatory argument.
Short option -f, taking an optional argument.
If the vertical bar is present and is followed by any characters, these characters specify the name of a long option, synonymous to the short one, specified by the first part. Any mandatory or optional arguments to the short option remain mandatory or optional for the corresponding long option. Examples:
Short option -f, or long option --file, requiring an argument.
Short option -f, or long option --file, taking an optional argument.
In any of the above cases, if this option appears in the command line,
getopt
returns its short option character.
To define a long option without a short equivalent, begin it with a bar, e.g.:
If this option is to take an argument, this is specified using the mechanism described above, except that the short option character is replaced with a minus sign. For example:
Long option --output, which takes a mandatory argument.
Long option --output, which takes an optional argument.
If an option is returned that has an argument in the command line,
getopt
stores this argument in the variable optarg
.
After each invocation, getopt
sets the variable optind
to the index of the next argv element to be parsed. Thus,
when the list of options is exhausted and the function returned an
empty string, optind
contains the index of the the first
element that is not an option.
When getopt
encounters an option that is not described in its
arguments or if it detects a missing option argument it prints an
error message using mailfromd
logging facilities, stores
the offending option in the variable optopt
, and returns ‘?’.
If printing error message is not desired (e.g. the application is going
to take care of error messaging), it can be disabled by setting the
variable opterr
to ‘0’.
The third argument to getopt
, called controlling argument,
may be used to control the behavior of the function. If it is a
colon, it disables printing the error message for unrecognized options
and missing option arguments (as setting opterr
to ‘0’
does). In this case getopt
returns ‘:’, instead of
‘?’ to indicate missing option argument.
If the controlling argument is a plus sign, or the environment
variable POSIXLY_CORRECT
is set, then option processing stops as
soon as a non-option argument is encountered. By default, if options
and non optional arguments are intermixed in argv, getopt
permutes them so that the options go first, followed by non-optional
arguments.
If the controlling argument is ‘-’, then each non-option element in argv is handled as if it were the argument of an option with character code 1 (‘"\001"’, in MFL notation. This can used by programs that are written to expect options and other argv-elements in any order and that care about the ordering of the two.
Any other value of the controlling argument is handled as an option definition.
A special language construct is provided to supply the second
argument (argv) to getopt
and similar functions:
vaptr(param)
where param is a positional parameter, from which to start the array of argv. For example:
func main(...) returns number do set rc getopt($#, vaptr($1), "|help") ...
Here, vaptr($1)
constructs the argv array from all the
arguments, supplied to the function main
.
To illustrate the use of getopt
function, let’s suppose you
write a script that takes the following options:
Then, the corresponding getopt
invocation will be:
func main(...) returns number do loop for string rc getopt($#, vaptr($1), "f:|file", "-::|output", "h|help"), while rc != "", set rc getopt(0, 0) do switch rc do case "f": set file optarg case "output" set output 1 set output_dir optarg case "h" help() default: return 1 done ...