WvStreams
ex3.c
00001 /* Argp example #3 - a program with options and arguments using argp */
00002 
00003 /* This program uses the same features as example 2, and uses options and
00004    arguments.
00005 
00006    We now use the first four fields in ARGP, so here's a description of them:
00007      OPTIONS  - A pointer to a vector of struct argp_option (see below)
00008      PARSER   - A function to parse a single option, called by argp
00009      ARGS_DOC - A string describing how the non-option arguments should look
00010      DOC      - A descriptive string about this program; if it contains a
00011                  vertical tab character (\v), the part after it will be
00012                  printed *following* the options
00013 
00014    The function PARSER takes the following arguments:
00015      KEY  - An integer specifying which option this is (taken
00016              from the KEY field in each struct argp_option), or
00017              a special key specifying something else; the only
00018              special keys we use here are ARGP_KEY_ARG, meaning
00019              a non-option argument, and ARGP_KEY_END, meaning
00020              that all arguments have been parsed
00021      ARG  - For an option KEY, the string value of its
00022              argument, or NULL if it has none
00023      STATE- A pointer to a struct argp_state, containing
00024              various useful information about the parsing state; used here
00025              are the INPUT field, which reflects the INPUT argument to
00026              argp_parse, and the ARG_NUM field, which is the number of the
00027              current non-option argument being parsed
00028    It should return either 0, meaning success, ARGP_ERR_UNKNOWN, meaning the
00029    given KEY wasn't recognized, or an errno value indicating some other
00030    error.
00031 
00032    Note that in this example, main uses a structure to communicate with the
00033    parse_opt function, a pointer to which it passes in the INPUT argument to
00034    argp_parse.  Of course, it's also possible to use global variables
00035    instead, but this is somewhat more flexible.
00036 
00037    The OPTIONS field contains a pointer to a vector of struct argp_option's;
00038    that structure has the following fields (if you assign your option
00039    structures using array initialization like this example, unspecified
00040    fields will be defaulted to 0, and need not be specified):
00041      NAME   - The name of this option's long option (may be zero)
00042      KEY    - The KEY to pass to the PARSER function when parsing this option,
00043                *and* the name of this option's short option, if it is a
00044                printable ascii character
00045      ARG    - The name of this option's argument, if any
00046      FLAGS  - Flags describing this option; some of them are:
00047                  OPTION_ARG_OPTIONAL - The argument to this option is optional
00048                  OPTION_ALIAS        - This option is an alias for the
00049                                         previous option
00050                  OPTION_HIDDEN       - Don't show this option in -help output
00051      DOC    - A documentation string for this option, shown in -help output
00052 
00053    An options vector should be terminated by an option with all fields zero. */
00054 
00055 #include <argp.h>
00056 
00057 #include <stdlib.h>
00058 
00059 const char *argp_program_version =
00060   "argp-ex3 1.0";
00061 const char *argp_program_bug_address =
00062   "<bug-gnu-utils@gnu.org>";
00063 
00064 /* Program documentation. */
00065 static char doc[] =
00066   "Argp example #3 -- a program with options and arguments using argp";
00067 
00068 /* A description of the arguments we accept. */
00069 static char args_doc[] = "ARG1 ARG2";
00070 
00071 /* The options we understand. */
00072 static struct argp_option options[] = {
00073   {"verbose",  'v', 0,      0,  "Produce verbose output", 0},
00074   {"quiet",    'q', 0,      0,  "Don't produce any output", 0},
00075   {"silent",   's', 0,      OPTION_ALIAS, 0, 0},
00076   {"output",   'o', "FILE", 0,
00077    "Output to FILE instead of standard output", 0},
00078   {0, 0, 0, 0, 0, 0}
00079 };
00080 
00081 /* Used by `main' to communicate with `parse_opt'. */
00082 struct arguments
00083 {
00084   char *args[2];                /* ARG1 & ARG2 */
00085   int silent, verbose;
00086   char *output_file;
00087 };
00088 
00089 /* Parse a single option. */
00090 static error_t
00091 parse_opt (int key, char *arg, struct argp_state *state)
00092 {
00093   /* Get the INPUT argument from `argp_parse', which we
00094      know is a pointer to our arguments structure. */
00095   struct arguments *arguments = state->input;
00096 
00097   switch (key)
00098     {
00099     case 'q': case 's':
00100       arguments->silent = 1;
00101       break;
00102     case 'v':
00103       arguments->verbose = 1;
00104       break;
00105     case 'o':
00106       arguments->output_file = arg;
00107       break;
00108 
00109     case ARGP_KEY_ARG:
00110       if (state->arg_num >= 2)
00111         /* Too many arguments. */
00112         argp_usage (state);
00113 
00114       arguments->args[state->arg_num] = arg;
00115 
00116       break;
00117 
00118     case ARGP_KEY_END:
00119       if (state->arg_num < 2)
00120         /* Not enough arguments. */
00121         argp_usage (state);
00122       break;
00123 
00124     default:
00125       return ARGP_ERR_UNKNOWN;
00126     }
00127   return 0;
00128 }
00129 
00130 /* Our argp parser. */
00131 static struct argp argp = { options, parse_opt, args_doc, doc, 0, 0, 0 };
00132 
00133 int main (int argc, char **argv)
00134 {
00135   struct arguments arguments;
00136 
00137   /* Default values. */
00138   arguments.silent = 0;
00139   arguments.verbose = 0;
00140   arguments.output_file = "-";
00141 
00142   /* Parse our arguments; every option seen by `parse_opt' will
00143      be reflected in `arguments'. */
00144   argp_parse (&argp, argc, argv, 0, 0, &arguments);
00145 
00146   printf ("ARG1 = %s\nARG2 = %s\nOUTPUT_FILE = %s\n"
00147           "VERBOSE = %s\nSILENT = %s\n",
00148           arguments.args[0], arguments.args[1],
00149           arguments.output_file,
00150           arguments.verbose ? "yes" : "no",
00151           arguments.silent ? "yes" : "no");
00152 
00153   exit (0);
00154 }