1 .\" Copyright (c) 1999 Kungliga Tekniska Högskolan
2 .\" $Id: getarg.3,v 1.2 1999/10/18 17:14:31 joda Exp $
9 .Nd collect command line options
11 .Fd #include <getarg.h>
13 .Fn getarg "struct getargs *args" "size_t num_args" "int argc" "char **argv" "int *optind"
15 .Fn arg_printusage "struct getargs *args" "size_t num_args" "const char *progname" "const char *extra_string"
18 collects any command line options given to a program in an easily used way.
20 pretty-prints the available options, with a short help text.
23 is the option specification to use, and it's an array of
33 are the argument count and argument vector to extract option from.
35 is a pointer to an integer where the index to the last processed
36 argument is stored, it must be initialised to the first index (minus
37 one) to process (normally 0) before the first call.
46 is the name of the program (to be used in the help text), and
48 is a string to print after the actual options to indicate more
49 arguments. The usefulness of this function is realised only be people
50 who has used programs that has help strings that doesn't match what
55 struct has the following elements.
58 const char *long_name;
75 is the long name of the option, it can be
77 if you don't want a long name.
79 is the characted to use as short option, it can be zero. If the option
82 field gets filled in with that value interpreted as specified by the
86 is a longer help string for the option as a whole, if it's
88 the help text for the option is omitted (but it's still displayed in
91 is a description of the argument, if
93 a default value will be used, depending on the type of the option:
95 .Bl -hang -width arg_negative_flag
97 the argument is a signed integer, and
102 the argument is a string, and
107 the argument is a flag, and
111 It gets filled in with either zero or one, depending on how the option
112 is given, the normal case beeing one. Note that if the option isn't
113 given, the value isn't altered, so it should be initialised to some
115 .It Fa arg_negative_flag
118 but it reverses the meaning of the flag (a given short option clears
119 the flag), and the synopsis of a long option is negated.
121 the argument can be given multiple times, and the values are collected
124 should be a pointer to a
125 .Fa struct getarg_strings
126 structure, which holds a length and a string pointer.
128 argument is a double precision floating point value, and
133 allows more fine-grained control of the option parsing process.
135 should be a pointer to a
136 .Fa getarg_collect_info
139 typedef int (*getarg_collect_func)(int short_opt,
146 typedef struct getarg_collect_info {
147 getarg_collect_func func;
149 } getarg_collect_info;
154 member set to a function to call, and
156 to some application specific data. The parameters to the collect function are:
159 non-zero if this call is via a short option flag, zero otherwise
161 the whole argument list
163 pointer to the index in argv where the flag is
165 pointer to the index in argv[*optind] where the flag name starts
167 application specific data
174 but to do this correct you (more or less) have to know about the inner
177 You can skip parts of arguments by increasing
184 with this), or whole argument strings by increasing
186 (let's say you want a flag
188 to specify a coordinate); if you also have to set
192 The collect function should return one of
193 .Dv ARG_ERR_NO_MATCH , ARG_ERR_BAD_ARG , ARG_ERR_NO_ARG
194 on error, zero otherwise.
196 For your convenience there is a function,
198 that returns the traditional argument string, and you pass it all
199 arguments, sans data, that where given to the collection function.
201 Don't use this more this unless you absolutely have to.
204 Option parsing is similar to what
206 uses. Short options without arguments can be compressed
211 options with arguments take these as either the rest of the
212 argv-string or as the next option
213 .Pf ( Fl o Ns Ar foo ,
217 Long option names are prefixed with -- (double dash), and the value
219 .Fl -foo= Ns Ar bar .
220 Long option flags can either be specified as they are
222 or with an (boolean parsable) option
223 .Pf ( Fl -help= Ns Ar yes ,
224 .Fl -help= Ns Ar true ,
225 or similar), or they can also be negated
229 and if you're really confused you can do it multiple times
230 .Pf ( Fl -no-no-help= Ns Ar false ,
232 .Fl -no-no-help= Ns Ar maybe ) .
239 char *source = "Ouagadougou";
242 int include_catalog = 1;
245 struct getargs args[] = {
246 { "source", 's', arg_string, &source,
247 "source of shippment", "city" },
248 { "destination", 'd', arg_string, &destination,
249 "destination of shippment", "city" },
250 { "weight", 'w', arg_integer, &weight,
251 "weight of shippment", "tons" },
252 { "catalog", 'c', arg_negative_flag, &include_catalog,
253 "include product catalog" },
254 { "help", 'h', arg_flag, &help_flag }
257 int num_args = sizeof(args) / sizeof(args[0]); /* number of elements in args */
259 const char *progname = "ship++";
262 main(int argc, char **argv)
265 if (getarg(args, num_args, argc, argv, &optind)) {
266 arg_printusage(args, num_args, progname, "stuff...");
270 arg_printusage(args, num_args, progname, "stuff...");
273 if (destination == NULL) {
274 fprintf(stderr, "%s: must specify destination\en", progname);
277 if (strcmp(source, destination) == 0) {
278 fprintf(stderr, "%s: destination must be different from source\en");
281 /* include more stuff here ... */
286 The output help output from this program looks like this:
289 Usage: ship++ [--source=city] [-s city] [--destination=city] [-d city]
290 [--weight=tons] [-w tons] [--no-catalog] [-c] [--help] [-h] stuff...
291 -s city, --source=city source of shippment
292 -d city, --destination=city destination of shippment
293 -w tons, --weight=tons weight of shippment
294 -c, --no-catalog include product catalog
297 It should be more flexible, so it would be possible to use other more
298 complicated option syntaxes, such as what
302 uses, or the AFS model where you can skip the flag names as long as
303 the options come in the correct order.
305 Options with multiple arguments should be handled better.
307 Should be integreated with SL.
309 It's very confusing that the struct you pass in is called getargS.