|
Packit |
6c4009 |
/* Argp example #3 -- a program with options and arguments using argp
|
|
Packit |
6c4009 |
Copyright (C) 1991-2018 Free Software Foundation, Inc.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
This program is free software; you can redistribute it and/or
|
|
Packit |
6c4009 |
modify it under the terms of the GNU General Public License
|
|
Packit |
6c4009 |
as published by the Free Software Foundation; either version 2
|
|
Packit |
6c4009 |
of the License, or (at your option) any later version.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
This program is distributed in the hope that it will be useful,
|
|
Packit |
6c4009 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
6c4009 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
6c4009 |
GNU General Public License for more details.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
You should have received a copy of the GNU General Public License
|
|
Packit |
6c4009 |
along with this program; if not, if not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
6c4009 |
*/
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
/* This program uses the same features as example 2, and uses options and
|
|
Packit |
6c4009 |
arguments.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
We now use the first four fields in ARGP, so here's a description of them:
|
|
Packit |
6c4009 |
OPTIONS -- A pointer to a vector of struct argp_option (see below)
|
|
Packit |
6c4009 |
PARSER -- A function to parse a single option, called by argp
|
|
Packit |
6c4009 |
ARGS_DOC -- A string describing how the non-option arguments should look
|
|
Packit |
6c4009 |
DOC -- A descriptive string about this program; if it contains a
|
|
Packit |
6c4009 |
vertical tab character (\v), the part after it will be
|
|
Packit |
6c4009 |
printed *following* the options
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
The function PARSER takes the following arguments:
|
|
Packit |
6c4009 |
KEY -- An integer specifying which option this is (taken
|
|
Packit |
6c4009 |
from the KEY field in each struct argp_option), or
|
|
Packit |
6c4009 |
a special key specifying something else; the only
|
|
Packit |
6c4009 |
special keys we use here are ARGP_KEY_ARG, meaning
|
|
Packit |
6c4009 |
a non-option argument, and ARGP_KEY_END, meaning
|
|
Packit |
6c4009 |
that all arguments have been parsed
|
|
Packit |
6c4009 |
ARG -- For an option KEY, the string value of its
|
|
Packit |
6c4009 |
argument, or NULL if it has none
|
|
Packit |
6c4009 |
STATE-- A pointer to a struct argp_state, containing
|
|
Packit |
6c4009 |
various useful information about the parsing state; used here
|
|
Packit |
6c4009 |
are the INPUT field, which reflects the INPUT argument to
|
|
Packit |
6c4009 |
argp_parse, and the ARG_NUM field, which is the number of the
|
|
Packit |
6c4009 |
current non-option argument being parsed
|
|
Packit |
6c4009 |
It should return either 0, meaning success, ARGP_ERR_UNKNOWN, meaning the
|
|
Packit |
6c4009 |
given KEY wasn't recognized, or an errno value indicating some other
|
|
Packit |
6c4009 |
error.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
Note that in this example, main uses a structure to communicate with the
|
|
Packit |
6c4009 |
parse_opt function, a pointer to which it passes in the INPUT argument to
|
|
Packit |
6c4009 |
argp_parse. Of course, it's also possible to use global variables
|
|
Packit |
6c4009 |
instead, but this is somewhat more flexible.
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
The OPTIONS field contains a pointer to a vector of struct argp_option's;
|
|
Packit |
6c4009 |
that structure has the following fields (if you assign your option
|
|
Packit |
6c4009 |
structures using array initialization like this example, unspecified
|
|
Packit |
6c4009 |
fields will be defaulted to 0, and need not be specified):
|
|
Packit |
6c4009 |
NAME -- The name of this option's long option (may be zero)
|
|
Packit |
6c4009 |
KEY -- The KEY to pass to the PARSER function when parsing this option,
|
|
Packit |
6c4009 |
*and* the name of this option's short option, if it is a
|
|
Packit |
6c4009 |
printable ascii character
|
|
Packit |
6c4009 |
ARG -- The name of this option's argument, if any
|
|
Packit |
6c4009 |
FLAGS -- Flags describing this option; some of them are:
|
|
Packit |
6c4009 |
OPTION_ARG_OPTIONAL -- The argument to this option is optional
|
|
Packit |
6c4009 |
OPTION_ALIAS -- This option is an alias for the
|
|
Packit |
6c4009 |
previous option
|
|
Packit |
6c4009 |
OPTION_HIDDEN -- Don't show this option in --help output
|
|
Packit |
6c4009 |
DOC -- A documentation string for this option, shown in --help output
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
An options vector should be terminated by an option with all fields zero. */
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
#include <stdlib.h>
|
|
Packit |
6c4009 |
#include <argp.h>
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
const char *argp_program_version =
|
|
Packit |
6c4009 |
"argp-ex3 1.0";
|
|
Packit |
6c4009 |
const char *argp_program_bug_address =
|
|
Packit |
6c4009 |
"<bug-gnu-utils@@gnu.org>";
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
/* Program documentation. */
|
|
Packit |
6c4009 |
static char doc[] =
|
|
Packit |
6c4009 |
"Argp example #3 -- a program with options and arguments using argp";
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
/* A description of the arguments we accept. */
|
|
Packit |
6c4009 |
static char args_doc[] = "ARG1 ARG2";
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
/* The options we understand. */
|
|
Packit |
6c4009 |
static struct argp_option options[] = {
|
|
Packit |
6c4009 |
{"verbose", 'v', 0, 0, "Produce verbose output" },
|
|
Packit |
6c4009 |
{"quiet", 'q', 0, 0, "Don't produce any output" },
|
|
Packit |
6c4009 |
{"silent", 's', 0, OPTION_ALIAS },
|
|
Packit |
6c4009 |
{"output", 'o', "FILE", 0,
|
|
Packit |
6c4009 |
"Output to FILE instead of standard output" },
|
|
Packit |
6c4009 |
{ 0 }
|
|
Packit |
6c4009 |
};
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
/* Used by @code{main} to communicate with @code{parse_opt}. */
|
|
Packit |
6c4009 |
struct arguments
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
char *args[2]; /* @var{arg1} & @var{arg2} */
|
|
Packit |
6c4009 |
int silent, verbose;
|
|
Packit |
6c4009 |
char *output_file;
|
|
Packit |
6c4009 |
};
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
/* Parse a single option. */
|
|
Packit |
6c4009 |
static error_t
|
|
Packit |
6c4009 |
parse_opt (int key, char *arg, struct argp_state *state)
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
/* Get the @var{input} argument from @code{argp_parse}, which we
|
|
Packit |
6c4009 |
know is a pointer to our arguments structure. */
|
|
Packit |
6c4009 |
struct arguments *arguments = state->input;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
switch (key)
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
case 'q': case 's':
|
|
Packit |
6c4009 |
arguments->silent = 1;
|
|
Packit |
6c4009 |
break;
|
|
Packit |
6c4009 |
case 'v':
|
|
Packit |
6c4009 |
arguments->verbose = 1;
|
|
Packit |
6c4009 |
break;
|
|
Packit |
6c4009 |
case 'o':
|
|
Packit |
6c4009 |
arguments->output_file = arg;
|
|
Packit |
6c4009 |
break;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
case ARGP_KEY_ARG:
|
|
Packit |
6c4009 |
if (state->arg_num >= 2)
|
|
Packit |
6c4009 |
/* Too many arguments. */
|
|
Packit |
6c4009 |
argp_usage (state);
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
arguments->args[state->arg_num] = arg;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
break;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
case ARGP_KEY_END:
|
|
Packit |
6c4009 |
if (state->arg_num < 2)
|
|
Packit |
6c4009 |
/* Not enough arguments. */
|
|
Packit |
6c4009 |
argp_usage (state);
|
|
Packit |
6c4009 |
break;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
default:
|
|
Packit |
6c4009 |
return ARGP_ERR_UNKNOWN;
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
return 0;
|
|
Packit |
6c4009 |
}
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
/* Our argp parser. */
|
|
Packit |
6c4009 |
static struct argp argp = { options, parse_opt, args_doc, doc };
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
int
|
|
Packit |
6c4009 |
main (int argc, char **argv)
|
|
Packit |
6c4009 |
{
|
|
Packit |
6c4009 |
struct arguments arguments;
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
/* Default values. */
|
|
Packit |
6c4009 |
arguments.silent = 0;
|
|
Packit |
6c4009 |
arguments.verbose = 0;
|
|
Packit |
6c4009 |
arguments.output_file = "-";
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
/* Parse our arguments; every option seen by @code{parse_opt} will
|
|
Packit |
6c4009 |
be reflected in @code{arguments}. */
|
|
Packit |
6c4009 |
argp_parse (&argp, argc, argv, 0, 0, &arguments);
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
printf ("ARG1 = %s\nARG2 = %s\nOUTPUT_FILE = %s\n"
|
|
Packit |
6c4009 |
"VERBOSE = %s\nSILENT = %s\n",
|
|
Packit |
6c4009 |
arguments.args[0], arguments.args[1],
|
|
Packit |
6c4009 |
arguments.output_file,
|
|
Packit |
6c4009 |
arguments.verbose ? "yes" : "no",
|
|
Packit |
6c4009 |
arguments.silent ? "yes" : "no");
|
|
Packit |
6c4009 |
|
|
Packit |
6c4009 |
exit (0);
|
|
Packit |
6c4009 |
}
|