Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
GETARG(3)		    Library Functions Manual		     GETARG(3)

NAME
       getarg, arg_printusage -- collect command line options

SYNOPSIS
       #include	<getarg.h>

       int
       getarg(struct  getargs  *args,  size_t num_args,	int argc, char **argv,
	   int *optind);

       void
       arg_printusage(struct	 getargs     *args,	 size_t	     num_args,
	   const char *progname, const char *extra_string);

DESCRIPTION
       getarg()	 collects  any	command	 line options given to a program in an
       easily used way.	 arg_printusage() pretty-prints	the available options,
       with a short help text.

       args is the option specification	to use,	and it's an  array  of	struct
       getargs	elements.   num_args  is the size of args (in elements).  argc
       and argv	are the	argument count and argument vector to  extract	option
       from.   optind  is  a pointer to	an integer where the index to the last
       processed argument is stored, it	must be	initialised to the first index
       (minus one) to process (normally	0) before the first call.

       arg_printusage take the same args and num_args as getarg;  progname  is
       the name	of the program (to be used in the help text), and extra_string
       is  a  string  to print after the actual	options	to indicate more argu-
       ments. The usefulness of	this function is realised only be  people  who
       has  used  programs  that  has help strings that	doesn't	match what the
       code does.

       The getargs struct has the following elements.

       struct getargs{
	   const char *long_name;
	   char	short_name;
	   enum	{ arg_integer,
		  arg_string,
		  arg_flag,
		  arg_negative_flag,
		  arg_strings,
		  arg_double,
		  arg_collect
	   } type;
	   void	*value;
	   const char *help;
	   const char *arg_help;
       };

       long_name is the	long name of the option, it can	be NULL, if you	 don't
       want  a long name.  short_name is the characted to use as short option,
       it can be zero. If the option has a value the value field  gets	filled
       in with that value interpreted as specified by the type field.  help is
       a  longer  help string for the option as	a whole, if it's NULL the help
       text for	the option is omitted (but it's	still displayed	in the	synop-
       sis).   arg_help	 is  a	description of the argument, if	NULL a default
       value will be used, depending on	the type of the	option:

       arg_integer	  the argument is a signed integer, and	 value	should
			  point	to an int.

       arg_string	  the  argument	is a string, and value should point to
			  a char*.

       arg_flag		  the argument is a flag, and value should point to  a
			  int.	It gets	filled in with either zero or one, de-
			  pending  on how the option is	given, the normal case
			  being	one. Note that if the option isn't given,  the
			  value	 isn't altered,	so it should be	initialised to
			  some useful default.

       arg_negative_flag  this is the same as arg_flag	but  it	 reverses  the
			  meaning of the flag (a given short option clears the
			  flag), and the synopsis of a long option is negated.

       arg_strings	  the  argument	 can  be given multiple	times, and the
			  values are collected in an array; value should be  a
			  pointer  to a	struct getarg_strings structure, which
			  holds	a length and a string pointer.

       arg_double	  argument is a	double precision floating point	value,
			  and value should point to a double.

       arg_collect	  allows more fine-grained control of the option pars-
			  ing  process.	  value	 should	 be  a	pointer	 to  a
			  getarg_collect_info structure:

			  typedef int (*getarg_collect_func)(int short_opt,
							     int argc,
							     char **argv,
							     int *optind,
							     int *optarg,
							     void *data);

			  typedef struct getarg_collect_info {
			      getarg_collect_func func;
			      void *data;
			  } getarg_collect_info;

			  With	the func member	set to a function to call, and
			  data to some application specific data. The  parame-
			  ters to the collect function are:

			  short_flag  non-zero if this call is via a short op-
			  tion flag, zero otherwise

			  argc,	argv the whole argument	list

			  optind pointer to the	index in argv where  the  flag
			  is

			  optarg  pointer  to the index	in argv[*optind] where
			  the flag name	starts

			  data application specific data

			  You can modify *optind, and *optarg, but to do  this
			  correct  you	(more  or less)	have to	know about the
			  inner	workings of getarg.

			  You  can  skip  parts	 of  arguments	by  increasing
			  *optarg  (you	 could	implement the -z3 set of flags
			  from gzip with this),	or whole argument  strings  by
			  increasing *optind (let's say	you want a flag	-c x y
			  z  to	specify	a coordinate); if you also have	to set
			  *optarg to a sane value.

			  The  collect	 function   should   return   one   of
			  ARG_ERR_NO_MATCH,  ARG_ERR_BAD_ARG,  ARG_ERR_NO_ARG,
			  ENOMEM on error, zero	otherwise.

			  For  your   convenience   there   is	 a   function,
			  getarg_optarg(),  that returns the traditional argu-
			  ment string, and you pass  it	 all  arguments,  sans
			  data,	that where given to the	collection function.

			  Don't	 use this more this unless you absolutely have
			  to.

       Option parsing is similar to what getopt	uses.  Short  options  without
       arguments  can  be compressed (-xyz is the same as -x -y	-z), and short
       options with arguments take these as either the rest of the argv-string
       or as the next option (-ofoo, or	-o foo).

       Long option names are prefixed with -- (double  dash),  and  the	 value
       with a =	(equal), --foo=bar.  Long option flags can either be specified
       as they are (--help), or	with an	(boolean parsable) option (--help=yes,
       --help=true, or similar), or they can also be negated (--no-help	is the
       same  as	--help=no), and	if you're really confused you can do it	multi-
       ple times (--no-no-help=false, or even --no-no-help=maybe).

EXAMPLE
       #include	<stdio.h>
       #include	<string.h>
       #include	<getarg.h>

       char *source = "Ouagadougou";
       char *destination;
       int weight;
       int include_catalog = 1;
       int help_flag;

       struct getargs args[] = {
	   { "source",	    's', arg_string,  &source,
	     "source of	shippment", "city" },
	   { "destination", 'd', arg_string,  &destination,
	     "destination of shippment", "city"	},
	   { "weight",	    'w', arg_integer, &weight,
	     "weight of	shippment", "tons" },
	   { "catalog",	    'c', arg_negative_flag, &include_catalog,
	     "include product catalog" },
	   { "help",	    'h', arg_flag, &help_flag }
       };

       int num_args = sizeof(args) / sizeof(args[0]); /* number	of elements in args */

       const char *progname = "ship++";

       int
       main(int	argc, char **argv)
       {
	   int optind =	0;
	   if (getarg(args, num_args, argc, argv, &optind)) {
	       arg_printusage(args, num_args, progname,	"stuff...");
	       exit (1);
	   }
	   if (help_flag) {
	       arg_printusage(args, num_args, progname,	"stuff...");
	       exit (0);
	   }
	   if (destination == NULL) {
	       fprintf(stderr, "%s: must specify destination\n", progname);
	       exit(1);
	   }
	   if (strcmp(source, destination) == 0) {
	       fprintf(stderr, "%s: destination	must be	different from source\n");
	       exit(1);
	   }
	   /* include more stuff here ... */
	   exit(2);
       }

       The output help output from this	program	looks like this:

       $ ship++	--help
       Usage: ship++ [--source=city] [-s city] [--destination=city] [-d	city]
	  [--weight=tons] [-w tons] [--no-catalog] [-c]	[--help] [-h] stuff...
       -s city,	--source=city	   source of shippment
       -d city,	--destination=city destination of shippment
       -w tons,	--weight=tons	   weight of shippment
       -c, --no-catalog		   include product catalog

BUGS
       It should be more flexible, so it would be possible to use  other  more
       complicated  option  syntaxes, such as what ps(1), and tar(1), uses, or
       the AFS model where you can skip	the flag names as long as the  options
       come in the correct order.

       Options with multiple arguments should be handled better.

       Should be integrated with SL.

       It's very confusing that	the struct you pass in is called getargS.

SEE ALSO
       getopt(3)

ROKEN			      September	24, 1999		     GETARG(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=arg_printusage&sektion=3&manpath=FreeBSD+Ports+14.3.quarterly>

home | help