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 ar-
     gument 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 de-
     scription 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, depending  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  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 cor-
			rect 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 coordi-
			nate); 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_op-
			targ(), 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  argu-
     ments  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 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  com-
     plicated  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=getarg&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help