(root)/
glibc-2.38/
manual/
examples/
argp-ex3.c
       1  /* Argp example #3 -- a program with options and arguments using argp
       2     Copyright (C) 1991-2023 Free Software Foundation, Inc.
       3  
       4     This program is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU General Public License
       6     as published by the Free Software Foundation; either version 2
       7     of the License, or (at your option) any later version.
       8  
       9     This program is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12     GNU General Public License for more details.
      13  
      14     You should have received a copy of the GNU General Public License
      15     along with this program; if not, see <https://www.gnu.org/licenses/>.
      16  */
      17  
      18  /* This program uses the same features as example 2, and uses options and
      19     arguments.
      20  
      21     We now use the first four fields in ARGP, so here's a description of them:
      22       OPTIONS  -- A pointer to a vector of struct argp_option (see below)
      23       PARSER   -- A function to parse a single option, called by argp
      24       ARGS_DOC -- A string describing how the non-option arguments should look
      25       DOC      -- A descriptive string about this program; if it contains a
      26                   vertical tab character (\v), the part after it will be
      27                   printed *following* the options
      28  
      29     The function PARSER takes the following arguments:
      30       KEY  -- An integer specifying which option this is (taken
      31               from the KEY field in each struct argp_option), or
      32               a special key specifying something else; the only
      33               special keys we use here are ARGP_KEY_ARG, meaning
      34               a non-option argument, and ARGP_KEY_END, meaning
      35               that all arguments have been parsed
      36       ARG  -- For an option KEY, the string value of its
      37               argument, or NULL if it has none
      38       STATE-- A pointer to a struct argp_state, containing
      39               various useful information about the parsing state; used here
      40               are the INPUT field, which reflects the INPUT argument to
      41               argp_parse, and the ARG_NUM field, which is the number of the
      42               current non-option argument being parsed
      43     It should return either 0, meaning success, ARGP_ERR_UNKNOWN, meaning the
      44     given KEY wasn't recognized, or an errno value indicating some other
      45     error.
      46  
      47     Note that in this example, main uses a structure to communicate with the
      48     parse_opt function, a pointer to which it passes in the INPUT argument to
      49     argp_parse.  Of course, it's also possible to use global variables
      50     instead, but this is somewhat more flexible.
      51  
      52     The OPTIONS field contains a pointer to a vector of struct argp_option's;
      53     that structure has the following fields (if you assign your option
      54     structures using array initialization like this example, unspecified
      55     fields will be defaulted to 0, and need not be specified):
      56       NAME   -- The name of this option's long option (may be zero)
      57       KEY    -- The KEY to pass to the PARSER function when parsing this option,
      58                 *and* the name of this option's short option, if it is a
      59                 printable ascii character
      60       ARG    -- The name of this option's argument, if any
      61       FLAGS  -- Flags describing this option; some of them are:
      62                   OPTION_ARG_OPTIONAL -- The argument to this option is optional
      63                   OPTION_ALIAS        -- This option is an alias for the
      64                                          previous option
      65                   OPTION_HIDDEN       -- Don't show this option in --help output
      66       DOC    -- A documentation string for this option, shown in --help output
      67  
      68     An options vector should be terminated by an option with all fields zero. */
      69  
      70  #include <stdlib.h>
      71  #include <argp.h>
      72  
      73  const char *argp_program_version =
      74    "argp-ex3 1.0";
      75  const char *argp_program_bug_address =
      76    "<bug-gnu-utils@@gnu.org>";
      77  
      78  /* Program documentation.  */
      79  static char doc[] =
      80    "Argp example #3 -- a program with options and arguments using argp";
      81  
      82  /* A description of the arguments we accept.  */
      83  static char args_doc[] = "ARG1 ARG2";
      84  
      85  /* The options we understand.  */
      86  static struct argp_option options[] = {
      87    {"verbose",  'v', 0,      0,  "Produce verbose output" },
      88    {"quiet",    'q', 0,      0,  "Don't produce any output" },
      89    {"silent",   's', 0,      OPTION_ALIAS },
      90    {"output",   'o', "FILE", 0,
      91     "Output to FILE instead of standard output" },
      92    { 0 }
      93  };
      94  
      95  /* Used by @code{main} to communicate with @code{parse_opt}.  */
      96  struct arguments
      97  {
      98    char *args[2];		/* @var{arg1} & @var{arg2} */
      99    int silent, verbose;
     100    char *output_file;
     101  };
     102  
     103  /* Parse a single option.  */
     104  static error_t
     105  parse_opt (int key, char *arg, struct argp_state *state)
     106  {
     107    /* Get the @var{input} argument from @code{argp_parse}, which we
     108       know is a pointer to our arguments structure.  */
     109    struct arguments *arguments = state->input;
     110  
     111    switch (key)
     112      {
     113      case 'q': case 's':
     114        arguments->silent = 1;
     115        break;
     116      case 'v':
     117        arguments->verbose = 1;
     118        break;
     119      case 'o':
     120        arguments->output_file = arg;
     121        break;
     122  
     123      case ARGP_KEY_ARG:
     124        if (state->arg_num >= 2)
     125  	/* Too many arguments.  */
     126  	argp_usage (state);
     127  
     128        arguments->args[state->arg_num] = arg;
     129  
     130        break;
     131  
     132      case ARGP_KEY_END:
     133        if (state->arg_num < 2)
     134  	/* Not enough arguments.  */
     135  	argp_usage (state);
     136        break;
     137  
     138      default:
     139        return ARGP_ERR_UNKNOWN;
     140      }
     141    return 0;
     142  }
     143  
     144  /* Our argp parser.  */
     145  static struct argp argp = { options, parse_opt, args_doc, doc };
     146  
     147  int
     148  main (int argc, char **argv)
     149  {
     150    struct arguments arguments;
     151  
     152    /* Default values.  */
     153    arguments.silent = 0;
     154    arguments.verbose = 0;
     155    arguments.output_file = "-";
     156  
     157    /* Parse our arguments; every option seen by @code{parse_opt} will
     158       be reflected in @code{arguments}.  */
     159    argp_parse (&argp, argc, argv, 0, 0, &arguments);
     160  
     161    printf ("ARG1 = %s\nARG2 = %s\nOUTPUT_FILE = %s\n"
     162  	  "VERBOSE = %s\nSILENT = %s\n",
     163  	  arguments.args[0], arguments.args[1],
     164  	  arguments.output_file,
     165  	  arguments.verbose ? "yes" : "no",
     166  	  arguments.silent ? "yes" : "no");
     167  
     168    exit (0);
     169  }