getopt_long(), getopt_long_only()
Get long and short options from a command-line argument list
Synopsis:
#include <getopt.h>
int getopt_long( int argc,
char * const *argv,
const char *optstring,
const struct option *longopts,
int *longindex);
int getopt_long_only( int argc,
char * const *argv,
const char *optstring,
const struct option *longopts,
int *longindex);
extern char *optarg;
extern int optind, opterr, optopt, optreset;
Arguments:
- argc
- The number of entries in the argument array.
- argv
- The argument array that you want to parse.
- optstring
- A string of short options; see below.
- longopts
- An array of type struct option that describes the long options; see below. End the array by including an element with its name field set to NULL.
- longindex
- NULL, or a pointer to a location where the function can store the index of the long option in the longopts array.
Library:
libc
Use the -l c option to qcc to link against this library. This library is usually included automatically.
Description:
The getopt_long() function is similar to getopt(), but it accepts short and long options. Long options can—but don't have to—correspond to short ones (e.g., to serve as memory aids for new users).
The optstring specifies the short options and consists of the following:
- A plus sign or a hyphen that affects the processing of
arguments that aren't options:
If you specify: Then getopt_long(): Neither Permutes the argument list so that non-options are eventually at the end A hyphen (-) Returns non-options as if they were associated with option character '\1' A plus sign (+) Stops processing options when it encounters the first non-option; this has the same effect as setting POSIXLY_CORRECT - An optional colon (:) that affects what getopt_long() does if
it determines that the user didn't supply a required argument for an option:
- If you include a colon, getopt_long() returns a colon.
- If you don't include a colon, getopt_long() returns a question mark and writes a diagnostic message to stderr.
Setting opterr to zero suppresses the diagnostic message without affecting which character getopt_long() returns.
- Zero or more short options, each of which is a single letter or digit:
- If a character is followed by a colon, the option requires an argument.
- If a character is followed by two colons (::), the argument is optional. If the user puts a space between the option and its argument, getopt_long() doesn't associate the argument with the option.
- These options can also include a W followed by a semicolon (W;). POSIX reserves the -W option for implementation extensions; getopt_long() interprets -W some_string[=value] as --some_string[=value].
Long options start with a double hyphen (--) and can be followed by an equals sign and an argument. For example:
myprogram --myoption=somevalue
The user can abbreviate long option names; if getopt_long() can't determine the option, it returns a question mark.
Use the option structure to define the long options:
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
The members include:
- name
- The option name without any leading hyphens.
- has_arg
- Whether the option has an argument; one of:
- no_argument — no argument to the option is expected
- required_argument — an argument to the option is required, but the equals sign is optional. If the user doesn't specify the equals sign, getopt_long() interprets the next array element as the argument.
- optional_argument — an argument to the option may be provided; optarg is non-NULL if the user specified an argument. The user needs to specify the equals sign, or else getopt_long() doesn't associate the argument with the option.
- flag, val
- How to report or act on the long option:
- If flag isn't NULL, then getopt_long() sets *flag to the value in the val field and then returns 0.
- If flag is NULL, then getopt_long() returns the value that you specified in val. Setting flag to NULL and setting val to the corresponding short option makes this function act like getopt().
If the longindex argument isn't NULL, then getopt_long() sets *longindex to the index of the long option in the longopts array.
If you want to use getopt_long() to evaluate multiple sets of arguments or to evaluate a single set of arguments multiple times, set optreset and optind to 1 before starting each additional set of calls to getopt_long().
The getopt_long_only() function behaves identically to getopt_long(), except that long options may start with a single or double hyphen (- or --). If an option starting with a single hyphen doesn't match a long option but does match a single-character option, the single-character option is returned. If getopt_long_only() can't determine the option, it returns a question mark.
Returns:
One of the following:
- the character corresponding to the next short option on the command line
- a value corresponding to the next long option on the command line:
- If the flag field in struct option is NULL, getopt_long() and getopt_long_only() return the value specified in the val field, which can be the corresponding short option.
- If flag isn't NULL, these functions return 0 and store val in the location pointed to by flag.
- a colon if the option is missing its argument and the first character (after the hyphen or plus sign, if present) of optstring is a colon.
- a question mark if the user specified an unknown or ambiguous option, or there was a missing option argument and the first character (after the hyphen or plus sign, if present) of optstring isn't a colon.
- -1 when all command-line options have been parsed.
Environment variables:
- POSIXLY_CORRECT
- If set, option processing stops when the first non-option is found, and a leading - or + in optstring is ignored.
Examples:
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int decompress_it = 0;
int loop = 0;
void usage()
{
printf ("Usage: my_program [-ab] [-f path] [-m [message]] [--buffered]\n");
printf (" [--decompress] [--filepath] [--loop [num_iterations]]\n");
}
int main (int argc, char **argv)
{
int fd = -1;
int longindex;
int i, ch;
int num_loops;
static struct option longopts[] = {
{ "buffered", no_argument, NULL, 'b' },
{ "file", required_argument, NULL, 'f' },
{ "decompress", no_argument, &decompress_it, 1 },
{ "loop", optional_argument, &loop, 1 },
{ NULL, 0, NULL, 0 }
};
/* Uncomment this to suppress getopt_long()'s messages about missing arguments: */
// opterr = 0;
while ((ch = getopt_long(argc, argv, "abf:m::", longopts, &longindex)) != -1) {
switch (ch) {
case '\1':
/* Non-options are sent here if optstring starts with a hyphen. */
printf (" Option \\1: %s\n", optarg == NULL ? "NULL" : optarg);
break;
case 'a':
printf (" -a\n");
break;
case 'b':
printf (" -b or --buffered\n");
break;
case 'f':
printf (" -f %s or --file=%s\n", optarg, optarg);
if ((fd = open(optarg, O_RDONLY, 0)) == -1)
printf(" Unable to open the file '%s'\n", optarg);
break;
case 'm':
if (optarg == NULL) {
printf (" -m with no argument\n");
} else {
printf (" -m %s\n", optarg);
}
break;
case 0:
/* Process any long options that set a variable. */
if (decompress_it) {
printf (" --decompress.\n");
}
if (loop) {
if (optarg == NULL) {
printf (" --loop with no argument; using the default of 10 loops.\n");
num_loops = 10;
} else {
num_loops = atoi (optarg);
printf (" --loop=%d\n", num_loops);
}
}
break;
case ':':
/* An argument is missing and optstring starts with a colon;
handle this appropriately. */
break;
case '?':
/* Ambiguous or unknown option, or an argument is missing and optstring
doesn't start with a colon; handle this appropriately. */
break;
default:
usage();
return EXIT_FAILURE;
}
}
printf ("Done processing the options; argc = %d; optind=%d\n", argc, optind);
for (i = optind; i < argc; i++) {
printf (" %s\n", argv[i]);
}
return EXIT_SUCCESS;
}
Classification:
Safety: | |
---|---|
Cancellation point | Yes |
Signal handler | No |
Thread | No |