man pages section 3: Basic Library Functions

Exit Print View

Updated: July 2014
 
 

getopt_long(3C)

Name

getopt_long, getopt_long_only, getopt_clip - parse long command options

Synopsis

#include <getopt.h>

int getopt_long(int argc, char * const *argv, const char *shortopts,
     const struct option *longopts, int *indexptr);
int getopt_long_only(int argc, char * const *argv, const char *shortopts,
     const struct option *longopts, int *indexptr);
int getopt_clip(int argc, char * const *argv, const char *shortopts,
     const struct option *longopts, int *indexptr);
extern char *optarg;
extern int optind, opterr, optopt;

Description

These functions are provided as a porting aid for GNU/Freeware/OpenBSD utilities. The getopt_long() function is intended to be as closely compatible with the GNU and OpenBSD implementations as possible, but since these public implementations differ in some corner cases, it is not possible to be fully compatible with both. The differences are enumerated in the NOTES section.

The getopt_long() function is an aid for implementing the GNU command line argument conventions. See the GNU documentation for the details of these conventions (glibc 2.2.3). Note that the GNU conventions are not POSIX-conforming. Most notably, the GNU conventions allow for optional option-arguments and do not enforce that operands must follow options on the command line.

The getopt_clip() function provides an interface similar to getopt_long() except that it implements the Sun CLIP convention, which is slightly more restrictive than the GNU/Freeware conventions. CLIP is modeled after the GNU/Freeware conventions but removes POSIX violations and syntactic ambiguities (see Intro(1)). Specifically, getopt_clip() is a command line parser that can be used by applications that follow the Command Line Interface Paradigm or CLIP syntax guidelines 3, 4, 5, 6, 7, 9, 10, 15, and 16. The remaining guidelines are not addressed by getopt_clip() and are the responsibility of the application.

The getopt_long() function is similar to getopt(3C) except that it accepts options in two forms: words and characters, also referred to as long options and short options.

The getopt_long() function can be used in two ways. In the first way, every long option understood by the program is mapped to a single character that is usually a corresponding short option. The option structure is used only to translate from long options to short options. In the second way, a long option sets a flag specified in the option structure, or stores a pointer to the command line argument in the address passed to it for options that take arguments. These two methods apply individually to each long option. Both methods can be used in the same application.

The getopt_long() function accepts command lines that interleave options and operands. The getopt_long() function reorders the elements of the argv argument such that when all command line arguments have been processed, all operands follow options (and their option-arguments) in the argv array and optind points to the first operand. The order of options relative to other options and operands relative to other operands is maintained. The argument “--” is accepted as a delimiter indicating the end of options. No argument reorder occurs past this delimiter. Argument reordering can not be unambiguously performed in all cases. The getopt_long() function depends on a number of internal heuristics to perform the reordering. The argc and argv arguments are the argument count and argument array as passed to main() (see exec(2)).

The shortopts argument contains the short-option characters recognized by the command using these functions. If a letter is followed by a colon (:), the option is expected to have an option-argument that should be separated from it by white space. If a character is followed by two colons (::), the option takes an optional option-argument. Any text after the option name it is returned in optarg; otherwise, optarg is set to 0. A whitespace character can never be used to separate an optional option-argument from its associated option. If shortopts contains the character “W” followed by a semicolon (;), then –W foo is treated as the long option --foo.

If the first character of the shortopts argument is the plus sign (+), getopt_long() enforces the POSIX requirement that operands follow options on the command line by returning -1 and stopping argument processing upon encountering the first operand (or “--”). This behavior can also be specified by setting the environment variable POSIXLY_CORRECT.

A hyphen (-) as the first character of the shortopts argument specifies that options and operands can be intermixed in argv but no argument reordering is performed. Operands are returned as arguments to option `\1', and option processing does not stop until “--” or the end of argv is found.

If the first character of the shortopts argument (after a potential plus or minus character) is a colon (:), a colon is returned by getopt_long() in response to a missing argument; otherwise, a question mark (?) is returned for this condition.

The longopts argument describes the long options to accept. It is an array of struct option structures, one for each long option. The array is terminated with an element containing all zeros.

The struct option structure contains the following members:

const char *name

Contains a pointer to the name of the option.

int has_arg

Specifies whether the option takes an argument. The possible values, defined in <getopt.h>, are no_argument, optional_argument, and required_argument.

int *flag

Contains the address of an int variable that is the flag for this option. The value contained in val is stored in this location to indicate that the option was seen. If flag is a null pointer, then the value contained in val is returned when this option is encountered, otherwise zero is returned.

int val

Contains the value to be stored at the variable pointed to by flag or returned by getopt_long() if flag is a null pointer.

For any long option, getopt_long() returns the index in the array longopts of the options definition by storing it in indexptr. The name of the option can be retrieved with longopts[(*indexptr)]. name. Long options can be distinguished either by the values in their val members or by their indices. The indexptr variable can also distinguish long options that set flags. The value of indexptr after encountering a short option is undefined.

If an option has an argument, the optarg global variable is set to point to the start of the option argument on return from getopt_long(); otherwise it is set to null. A long option can take an argument in one of two forms: --option=arg or --option arg. If the long option argument is optional, only the “--option=arg” form can be used to specify the option argument. No argument is specified by the simple form “--option”. The form “--option=” specifies an empty string as the option argument.

Long-option names can be abbreviated if the abbreviation is unique or an exact match for some defined option. An exact match takes precedence over an abbreviated match. Thus, if foo and foobar are acceptable long-option names, then specifying --foo on the command line always matches the former. Specifying --f or --fo would not be accepted as a match for either.

The getopt_long() function places in optind the argv index of the next argument to be processed. The optind global variable is external and is initialized to 1 before the first call to getopt_long(). When all options have been processed (that is, up to the first non-option argument), getopt_long() returns -1. The special option “--” (two hyphens) can be used to delimit the end of the options; when it is encountered, -1 is returned and “—” is skipped. This ooption is useful in delimiting non-option arguments that begin with “-” (hyphen).

If getopt_long() encounters a short option character shortopts string or a long option not described in the longopts array, it returns the question mark (?) character. It also returns a question mark (?) character in response to a missing option argument unless the first character of shortopts is a colon (:) (or the second character, if the first character is either a plus (+) or a minus (-)), in which case it returns a colon (:). In either case, if the application has not set opterr to 0 and the first character of shortopts is not a colon (:), getopt_long() prints a diagnostic message to stderr.

The getopt_long_only() function is equivalent to the getopt_long() function except that it allows the user of the application to pass long options with only a single hyphen (-) instead of “--”. The “--” prefix is still recognized. However, when a single hyphen (-) is encountered, getopt_long_only() attempts to match this argument to a long option, including abbreviations of the long option. If a long option starts with the same character as a short option, a single hyphen followed by that character (and no other characters) will be recognized as a short option. Use of getopt_long_only() is strongly discouraged by Sun and GNU for new applications.

The behavior of getopt_clip() differs from that of getopt_long() in the following ways:

  • The getopt_clip() function does not perform argument reordering. The getopt_clip() function always enforces the POSIX behavior that all options should precede operands on the command line. Specifically, getopt_clip() does not reorder arguments but returns -1 and stops processing upon encountering the first operand argument.

  • The environment variable POSIXLY_CORRECT is ignored (the getopt_clip() function behaves as though it were set.)

  • The plus and minus characters do not have a special meaning as the first character of the shortopts argument. They are treated as any other character (other than the colon) would be treated.

  • Optional option-arguments are not allowed. The behavior of getopt_clip() when optional_argument is specified as the value of has_arg in the longopts argument or double colons are included in the shortopts argument is unspecified.

  • Long-option abbreviations are not recognized.

  • Short options are required to have at least one long-option equivalent. That is, each character in shortopts must appear as the val member in one or more option structures. Similarly, each long option must have a short option equivalent, meaning that the val member of each option structure must appear in the shortopts string. If these requirements are not met, getopt_clip() returns -1 and sets errno to EINVAL.

Return Values

For short options (other than –W when W; is in shortopts), these functions return the next option character specified on the command line. For long options, the value returned by these functions depends upon the value of the flag structure element for the identified option. If flag is NULL, the value contained in the val structure element for the long option encountered on the command line is returned. Otherwise, these functions return 0 (and the value specified in the val member for the long option is stored into the location pointed to by flag). When W; is in shortopts and –W is encountered in the command line and the option argument to –W matches a long-option name, the return state from these functions is as if the long option had been encountered. However, if no argument is specified to the long option, optarg is set to the option argument of –W (the long-option name or unique prefix). If the option argument of –W does not match a long option (or unique prefix), the return state is as for any other short option.

A colon (:) is returned if getopt_long() detects a missing argument and the first character of shortopts (other than a possible initial “+” or “-”) was a colon (':').

A question mark (?) is returned if getopt_long() encounters an option letter not included in shortopts or detects a missing argument and the first character of shortopts (other than a possible initial “+” or “-”) was not a colon (:).

The getopt_clip() function expects all short options to have one or more long-option equivalent and all long options to have one short option equivalent (see NOTES for details). If proper equivalents are not found, getopt_clip() returns -1 and sets errno to EINVAL.

Errors

The getopt_clip() function will fail if:

EINVAL

A short option does not have at least one long-option equivalent, or a long option does not have at least one short-option equivalent.

Examples

Example 1 Example using getopt().
#include <unistd.h>
#include <getopt.h>

/* Flag set by `--verbose'. */
static int verbose_flag;

int
main (int argc, char **argv)
{
  int c;

  while (1) {
    static struct option long_options[] = {
      /* These options set a flag. */
      {"verbose", no_argument, &verbose_flag, 1},
      {"brief",   no_argument, &verbose_flag, 0},
      /* The following options don't set a flag. */
      {"add",     no_argument, NULL, 'a'},
      {"append",  no_argument, NULL, 'b'},
      {"delete",  required_argument, NULL, 'd'},
      {"create",  required_argument, NULL, 'c'},
      {"file",    required_argument, NULL, 'f'},
      {0, 0, 0, 0}
    };
    /* getopt_long stores the option index here. */
    int option_index = 0;

    c = getopt_long (argc, argv, "abc:d:f:",
                     long_options, &option_index);

    /* Detect the end of the options. */
    if (c == -1)
      break;

    switch (c) {
      case 0:
        /* (In this example) only options which set */
        /* a flag return zero, so do nothing. */
        break;

      case 'a':
        puts ("option --add (-a)\n");
        break;

      case 'b':
        puts ("option --append (-b)\n");
        break;

      case 'c':
        printf ("option --create (-c) with value `%s'\n", optarg);
        break;

      case 'd':
        printf ("option --delete (-d) with value `%s'\n", optarg);
        break;

      case 'f':
        printf ("option --file (-f) with value `%s'\n", optarg);
        break;

      case '?':
        /* getopt_long already printed an error message. */
        break;

      default:
        abort ();
    }
  }  

  /* Instead of reporting `--verbose'
     and `--brief' as they are encountered,
     we report the final status resulting from them. */
  if (verbose_flag)
    puts ("verbose flag is set");

  /* Print any remaining command line arguments (not options). */
  if (optind < argc) {
      printf ("non-option ARGV-elements: ");
      while (optind < argc)
        printf ("%s ", argv[optind++]);
      putchar ('\n');
    }

  exit (0);
}

Environment Variables

See environ(5) for descriptions of the following environment variables that affect the execution of getopt_long(): LANG, LC_ALL, and LC_MESSAGES.

POSIXLY_CORRECT

When set (and the first character of the shortopts argument is neither a plus or minus sign), the POSIX rule that all operands must follow all options is enforced. Option processing terminates when the first operand is encountered. The getopt_clip() function ignores the setting of POSIXLY_CORRECT and always behaves as if it were set.

LC_CTYPE

Determine the locale for the interpretation of sequences of bytes as characters in shortopts and the longopts[].name structure members.

Usage

The getopt_long() function does not fully check for mandatory arguments because there is no unambiguous algorithm to do so. Given an option string a:b and the input -a -b, getopt_long() assumes that -b is the mandatory argument to the -a option and not that -a is missing a mandatory argument. Indeed, the only time a missing option argument can be reliably detected is when the option is the final option on the command line and is not followed by any command arguments.

Attributes

See attributes(5) for descriptions of the following attributes:

ATTRIBUTE TYPE
ATTRIBUTE VALUE
Interface Stability
Committed
MT-Level
Unsafe

See also

Intro(1), getopts(1), getopt(3C), getsubopt(3C), gettext(3C), setlocale(3C), attributes(5), environ(5), standards(5)

Notes

Use of getopt_long() is discouraged for applications targeted strictly for Solaris. It should be used only for applications targeted at Solaris and platforms that adhere to the GNU command line conventions. The getopt_long_only() function is provided by Solaris and GNU for legacy applications and its use is discouraged by both current conventions.

The differences between the Solaris/GNU and OpenBSD versions of these functions are as follows:

  • The handling of the hyphen (-) as the first character of the option string in presence of the environment variable POSIXLY_CORRECT:

    Solaris/GNU

    Operands are returned as arguments to option '\1', and option processing does not stop until “--” or the end of argv is found.

    OpenBSD

    obeys POSIXLY_CORRECT and stops at the first non-option.

  • The handling of the hyphen (-) within the shortopts parameter string when not the first character.

    Solaris/GNU

    treats a single hyphen (-) on the command line as an operand.

    OpenBSD

    treats a single hyphen (-) on the command line as an option. BSD recognizes this behavior as incorrect, but maintains it for compatibility.

  • The return value in the event of a missing argument if the first character after “+” or “-” in the option string is not a colon (:)

    Solaris/GNU

    returns “?”.

    OpenBSD

    returns “:” (since OpenBSD's getopt does).

  • The setting optopt for long options with flag != NULL:

    Solaris/GNU

    sets optopt to val.

    OpenBSD

    sets optopt to 0 (since val would never be returned).

  • The setting of optarg for long options without an argument that are invoked with –W (W; in option string):

    Solaris/GNU

    sets optarg to the option name (the argument of –W).

    OpenBSD

    sets optarg to NULL (the argument of the long option).

  • The handling of –W with an argument that is not (a prefix to) a known long option (W; in option string):

    Solaris/GNU

    returns 'W' with optarg set to the unknown option.

    OpenBSD

    treats as an error (unknown option) and returns “?” with optopt set to 0 and optarg set to NULL.

  • The error messages are different (all).

  • The implementations do not permute the argument vector at the same points in the calling sequence. The aspects normally used by the caller (ordering after -1 is returned, value of optind relative to current positions) are the same. Applications should not depend upon the ordering of the argument vector before -1 is returned.