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

FreeBSD Manual Pages

  
 
  

home | help
GETARG(3)	       FreeBSD 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 eas-
     ily 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 arguments. The
     usefulness	of this	function is realised only be people who	has used pro-
     grams 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	synopsis).
     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 mean-
			ing 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 val-
			ues 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 parsing
			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 parameters
			to the collect function	are:

			short_flag non-zero if this call is via	a short	option
			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 in-
			ner 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 argument
			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 ar-
     guments can be compressed (-xyz is	the same as -x -y -z), and short op-
     tions 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 multiple
     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			 ROKEN

NAME | SYNOPSIS | DESCRIPTION | EXAMPLE | BUGS | SEE ALSO

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=getarg&sektion=3&manpath=FreeBSD+12.1-RELEASE+and+Ports>

home | help