| /* Test program for argp argument parser | 
 |    Copyright (C) 1997-2016 Free Software Foundation, Inc. | 
 |    This file is part of the GNU C Library. | 
 |    Written by Miles Bader <miles@gnu.ai.mit.edu>. | 
 |  | 
 |    The GNU C Library is free software; you can redistribute it and/or | 
 |    modify it under the terms of the GNU Lesser General Public | 
 |    License as published by the Free Software Foundation; either | 
 |    version 2.1 of the License, or (at your option) any later version. | 
 |  | 
 |    The GNU C Library is distributed in the hope that it will be useful, | 
 |    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
 |    Lesser General Public License for more details. | 
 |  | 
 |    You should have received a copy of the GNU Lesser General Public | 
 |    License along with the GNU C Library; if not, see | 
 |    <http://www.gnu.org/licenses/>.  */ | 
 |  | 
 | #ifdef HAVE_CONFIG_H | 
 | #include <config.h> | 
 | #endif | 
 |  | 
 | #include <stdlib.h> | 
 | #include <time.h> | 
 | #include <string.h> | 
 | #include <argp.h> | 
 |  | 
 | const char *argp_program_version = "argp-test 1.0"; | 
 |  | 
 | struct argp_option sub_options[] = | 
 | { | 
 |   {"subopt1",       's',     0,  0, "Nested option 1"}, | 
 |   {"subopt2",       'S',     0,  0, "Nested option 2"}, | 
 |  | 
 |   { 0, 0, 0, 0, "Some more nested options:", 10}, | 
 |   {"subopt3",       'p',     0,  0, "Nested option 3"}, | 
 |  | 
 |   {"subopt4",       'q',     0,  0, "Nested option 4", 1}, | 
 |  | 
 |   {0} | 
 | }; | 
 |  | 
 | static const char sub_args_doc[] = "STRING...\n-"; | 
 | static const char sub_doc[] = "\vThis is the doc string from the sub-arg-parser."; | 
 |  | 
 | static error_t | 
 | sub_parse_opt (int key, char *arg, struct argp_state *state) | 
 | { | 
 |   switch (key) | 
 |     { | 
 |     case ARGP_KEY_NO_ARGS: | 
 |       printf ("NO SUB ARGS\n"); | 
 |       break; | 
 |     case ARGP_KEY_ARG: | 
 |       printf ("SUB ARG: %s\n", arg); | 
 |       break; | 
 |  | 
 |     case 's' : case 'S': case 'p': case 'q': | 
 |       printf ("SUB KEY %c\n", key); | 
 |       break; | 
 |  | 
 |     default: | 
 |       return ARGP_ERR_UNKNOWN; | 
 |     } | 
 |   return 0; | 
 | } | 
 |  | 
 | static char * | 
 | sub_help_filter (int key, const char *text, void *input) | 
 | { | 
 |   if (key == ARGP_KEY_HELP_EXTRA) | 
 |     return strdup ("This is some extra text from the sub parser (note that it \ | 
 | is preceded by a blank line)."); | 
 |   else | 
 |     return (char *)text; | 
 | } | 
 |  | 
 | static struct argp sub_argp = { | 
 |   sub_options, sub_parse_opt, sub_args_doc, sub_doc, 0, sub_help_filter | 
 | }; | 
 |  | 
 | /* Structure used to communicate with the parsing functions.  */ | 
 | struct params | 
 | { | 
 |   unsigned foonly;		/* Value parsed for foonly.  */ | 
 |   unsigned foonly_default;	/* Default value for it.  */ | 
 | }; | 
 |  | 
 | #define OPT_PGRP 1 | 
 | #define OPT_SESS 2 | 
 |  | 
 | struct argp_option options[] = | 
 | { | 
 |   {"pid",       'p',     "PID", 0, "List the process PID"}, | 
 |   {"pgrp",      OPT_PGRP,"PGRP",0, "List processes in the process group PGRP"}, | 
 |   {"no-parent", 'P',	 0,     0, "Include processes without parents"}, | 
 |   {0,           'x',     0,     OPTION_ALIAS}, | 
 |   {"all-fields",'Q',     0,     0, "Don't elide unusable fields (normally" | 
 | 				   " if there's some reason ps can't" | 
 | 				   " print a field for any process, it's" | 
 | 				   " removed from the output entirely)" }, | 
 |   {"reverse",   'r',    0,      0, "Reverse the order of any sort"}, | 
 |   {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS}, | 
 |   {"session",  OPT_SESS,"SID",  OPTION_ARG_OPTIONAL, | 
 | 				   "Add the processes from the session" | 
 | 				   " SID (which defaults to the sid of" | 
 | 				   " the current process)" }, | 
 |  | 
 |   {0,0,0,0, "Here are some more options:"}, | 
 |   {"foonly", 'f', "ZOT", OPTION_ARG_OPTIONAL, "Glork a foonly"}, | 
 |   {"zaza", 'z', 0, 0, "Snit a zar"}, | 
 |  | 
 |   {0} | 
 | }; | 
 |  | 
 | static const char args_doc[] = "STRING"; | 
 | static const char doc[] = "Test program for argp." | 
 |  "\vThis doc string comes after the options." | 
 |  "\nHey!  Some manual formatting!" | 
 |  "\nThe current time is: %s"; | 
 |  | 
 | static void | 
 | popt (int key, char *arg) | 
 | { | 
 |   char buf[10]; | 
 |   if (isprint (key)) | 
 |     sprintf (buf, "%c", key); | 
 |   else | 
 |     sprintf (buf, "%d", key); | 
 |   if (arg) | 
 |     printf ("KEY %s: %s\n", buf, arg); | 
 |   else | 
 |     printf ("KEY %s\n", buf); | 
 | } | 
 |  | 
 | static error_t | 
 | parse_opt (int key, char *arg, struct argp_state *state) | 
 | { | 
 |   struct params *params = state->input; | 
 |  | 
 |   switch (key) | 
 |     { | 
 |     case ARGP_KEY_NO_ARGS: | 
 |       printf ("NO ARGS\n"); | 
 |       break; | 
 |  | 
 |     case ARGP_KEY_ARG: | 
 |       if (state->arg_num > 0) | 
 | 	return ARGP_ERR_UNKNOWN; /* Leave it for the sub-arg parser.  */ | 
 |       printf ("ARG: %s\n", arg); | 
 |       break; | 
 |  | 
 |     case 'f': | 
 |       if (arg) | 
 | 	params->foonly = atoi (arg); | 
 |       else | 
 | 	params->foonly = params->foonly_default; | 
 |       popt (key, arg); | 
 |       break; | 
 |  | 
 |     case 'p': case 'P': case OPT_PGRP: case 'x': case 'Q': | 
 |     case 'r': case OPT_SESS: case 'z': | 
 |       popt (key, arg); | 
 |       break; | 
 |  | 
 |     default: | 
 |       return ARGP_ERR_UNKNOWN; | 
 |     } | 
 |   return 0; | 
 | } | 
 |  | 
 | static char * | 
 | help_filter (int key, const char *text, void *input) | 
 | { | 
 |   char *new_text; | 
 |   struct params *params = input; | 
 |  | 
 |   if (key == ARGP_KEY_HELP_POST_DOC && text) | 
 |     { | 
 |       time_t now = time (0); | 
 |       asprintf (&new_text, text, ctime (&now)); | 
 |     } | 
 |   else if (key == 'f') | 
 |     /* Show the default for the --foonly option.  */ | 
 |     asprintf (&new_text, "%s (ZOT defaults to %x)", | 
 | 	      text, params->foonly_default); | 
 |   else | 
 |     new_text = (char *)text; | 
 |  | 
 |   return new_text; | 
 | } | 
 |  | 
 | static struct argp_child argp_children[] = { { &sub_argp }, { 0 } }; | 
 | static struct argp argp = { | 
 |   options, parse_opt, args_doc, doc, argp_children, help_filter | 
 | }; | 
 |  | 
 | int | 
 | main (int argc, char **argv) | 
 | { | 
 |   struct params params; | 
 |   params.foonly = 0; | 
 |   params.foonly_default = random (); | 
 |   argp_parse (&argp, argc, argv, 0, 0, ¶ms); | 
 |   printf ("After parsing: foonly = %x\n", params.foonly); | 
 |   return 0; | 
 | } |