#### 25.2.3 Parsing Long Options with `getopt_long`

To accept GNU-style long options as well as single-character options, use `getopt_long` instead of `getopt`. This function is declared in `getopt.h`, not `unistd.h`. You should make every program accept long options if it uses any options, for this takes little extra work and helps beginners remember how to use the program.

— Data Type: struct option

> This structure describes a single long option name for the sake of `getopt_long`. The argument longopts must be an array of these structures, one for each long option. Terminate the array with an element containing all zeros.

> The `struct option` structure has these fields:

> `const char *name`
>   This field is the name of the option. It is a string.
> `int has_arg`
>   This field says whether the option takes an argument. It is an integer, and there are three legitimate values: `no_argument`, `required_argument` and `optional_argument`.
> `int *flag`
> `int val`
>   These fields control how to report or act on the option when it occurs.

>   If `flag` is a null pointer, then the `val` is a value which identifies this option. Often these values are chosen to uniquely identify particular long options.

>   If `flag` is not a null pointer, it should be the address of an `int` variable which is the flag for this option. The value in `val` is the value to store in the flag to indicate that the option was seen.

— Function: int getopt_long (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *indexptr)

> Preliminary: | MT-Unsafe race:getopt env | AS-Unsafe heap i18n lock corrupt | AC-Unsafe mem lock corrupt | See POSIX Safety Concepts.

> Decode options from the vector argv (whose length is argc). The argument shortopts describes the short options to accept, just as it does in `getopt`. The argument longopts describes the long options to accept (see above).

> When `getopt_long` encounters a short option, it does the same thing that `getopt` would do: it returns the character code for the option, and stores the options argument (if it has one) in `optarg`.

> When `getopt_long` encounters a long option, it takes actions based on the `flag` and `val` fields of the definition of that option.

> If `flag` is a null pointer, then `getopt_long` returns the contents of `val` to indicate which option it found. You should arrange distinct values in the `val` field for options with different meanings, so you can decode these values after `getopt_long` returns. If the long option is equivalent to a short option, you can use the short option's character code in `val`.

> If `flag` is not a null pointer, that means this option should just set a flag in the program. The flag is a variable of type `int` that you define. Put the address of the flag in the `flag` field. Put in the `val` field the value you would like this option to store in the flag. In this case, `getopt_long` returns `0`.

> For any long option, `getopt_long` tells you the index in the array longopts of the options definition, by storing it into `*`indexptr. You can get the name of the option with longopts`[*`indexptr`].name`. So you can distinguish among long options either by the values in their `val` fields or by their indices. You can also distinguish in this way among long options that set flags.

> When a long option has an argument, `getopt_long` puts the argument value in the variable `optarg` before returning. When the option has no argument, the value in `optarg` is a null pointer. This is how you can tell whether an optional argument was supplied.

> When `getopt_long` has no more options to handle, it returns `-1`, and leaves in the variable `optind` the index in argv of the next remaining argument.

Since long option names were used before the `getopt_long` options was invented there are program interfaces which require programs to recognize options like ‘`-option value`’ instead of ‘`--option value`’. To enable these programs to use the GNU getopt functionality there is one more function available.

— Function: int getopt_long_only (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *indexptr)

> Preliminary: | MT-Unsafe race:getopt env | AS-Unsafe heap i18n lock corrupt | AC-Unsafe mem lock corrupt | See POSIX Safety Concepts.

> The `getopt_long_only` function is equivalent to the `getopt_long` function but it allows to specify the user of the application to pass long options with only ‘`-`’ instead of ‘`--`’. The ‘`--`’ prefix is still recognized but instead of looking through the short options if a ‘`-`’ is seen it is first tried whether this parameter names a long option. If not, it is parsed as a short option.

> Assuming `getopt_long_only` is used starting an application with

>                 app -foo

> the `getopt_long_only` will first look for a long option named ‘`foo`’. If this is not found, the short options ‘`f`’, ‘`o`’, and again ‘`o`’ are recognized.