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>
14 .Fn getarg "struct getargs *args" "size_t num_args" "int argc" "char **argv" "int *optind"
17 .Fn arg_printusage "struct getargs *args" "size_t num_args" "const char *progname" "const char *extra_string"
21 collects any command line options given to a program in an easily used way.
23 pretty-prints the available options, with a short help text.
26 is the option specification to use, and it's an array of
36 are the argument count and argument vector to extract option from.
38 is a pointer to an integer where the index to the last processed
39 argument is stored, it must be initialised to the first index (minus
40 one) to process (normally 0) before the first call.
48 .Fa progname is the name of the program (to be used in the help text), and
50 is a string to print after the actual options to indicate more
51 arguments. The usefulness of this function is realised only be people
52 who has used programs that has help strings that doesn't match what
57 struct has the following elements.
61 const char *long_name;
78 is the long name of the option, it can be
80 if you don't want a long name.
82 is the characted to use as short option, it can be zero. If the option
85 field gets filled in with that value interpreted as specified by the
89 is a longer help string for the option as a whole, if it's
91 the help text for the option is omitted (but it's still displayed in
94 is a description of the argument, if
96 a default value will be used, depending on the type of the option:
98 .Bl -hang -width arg_negative_flag
100 the argument is a signed integer, and
105 the argument is a string, and
110 the argument is a flag, and
114 It gets filled in with either zero or one, depending on how the option
115 is given, the normal case beeing one. Note that if the option isn't
116 given, the value isn't altered, so it should be initialised to some
118 .It Fa arg_negative_flag
121 but it reverses the meaning of the flag (a given short option clears
122 the flag), and the synopsis of a long option is negated.
124 the argument can be given multiple times, and the values are collected
127 should be a pointer to a
128 .Fa struct getarg_strings
129 structure, which holds a length and a string pointer.
131 argument is a double precision floating point value, and
136 allows more fine-grained control of the option parsing process.
138 should be a pointer to a
139 .Fa getarg_collect_info
142 typedef int (*getarg_collect_func)(int short_opt,
149 typedef struct getarg_collect_info {
150 getarg_collect_func func;
152 } getarg_collect_info;
157 member set to a function to call, and
159 to some application specific data. The parameters to the collect function are:
162 non-zero if this call is via a short option flag, zero otherwise
164 the whole argument list
166 pointer to the index in argv where the flag is
168 pointer to the index in argv[*optind] where the flag name starts
170 application specific data
177 but to do this correct you (more or less) have to know about the inner
180 You can skip parts of arguments by increasing
187 with this), or whole argument strings by increasing
189 (let's say you want a flag
191 to specify a coordinate); if you also have to set
195 The collect function should return one of
196 .Dv ARG_ERR_NO_MATCH , ARG_ERR_BAD_ARG , ARG_ERR_NO_ARG
197 on error, zero otherwise.
199 For your convenience there is a function,
201 that returns the traditional argument string, and you pass it all
202 arguments, sans data, that where given to the collection function.
204 Don't use this more this unless you absolutely have to.
207 Option parsing is similar to what
209 uses. Short options without arguments can be compressed
214 options with arguments take these as either the rest of the
215 argv-string or as the next option
216 .Pf ( Fl o Ns Ar foo ,
220 Long option names are prefixed with -- (double dash), and the value
222 .Fl -foo= Ns Ar bar .
223 Long option flags can either be specified as they are
225 or with an (boolean parsable) option
226 .Pf ( Fl -help= Ns Ar yes ,
227 .Fl -help= Ns Ar true ,
228 or similar), or they can also be negated
232 and if you're really confused you can do it multiple times
233 .Pf ( Fl -no-no-help= Ns Ar false ,
235 .Fl -no-no-help= Ns Ar maybe ) .
244 char *source = "Ouagadougou";
247 int include_catalog = 1;
250 struct getargs args[] = {
251 { "source", 's', arg_string, &source,
252 "source of shippment", "city" },
253 { "destination", 'd', arg_string, &destination,
254 "destination of shippment", "city" },
255 { "weight", 'w', arg_integer, &weight,
256 "weight of shippment", "tons" },
257 { "catalog", 'c', arg_negative_flag, &include_catalog,
258 "include product catalog" },
259 { "help", 'h', arg_flag, &help_flag }
262 int num_args = sizeof(args) / sizeof(args[0]); /* number of elements in args */
264 const char *progname = "ship++";
267 main(int argc, char **argv)
270 if (getarg(args, num_args, argc, argv, &optind)) {
271 arg_printusage(args, num_args, progname, "stuff...");
275 arg_printusage(args, num_args, progname, "stuff...");
278 if (destination == NULL) {
279 fprintf(stderr, "%s: must specify destination\n", progname);
282 if (strcmp(source, destination) == 0) {
283 fprintf(stderr, "%s: destination must be different from source\n");
286 /* include more stuff here ... */
291 The output help output from this program looks like this:
294 Usage: ship++ [--source=city] [-s city] [--destination=city] [-d city]
295 [--weight=tons] [-w tons] [--no-catalog] [-c] [--help] [-h] stuff...
296 -s city, --source=city source of shippment
297 -d city, --destination=city destination of shippment
298 -w tons, --weight=tons weight of shippment
299 -c, --no-catalog include product catalog
303 It should be more flexible, so it would be possible to use other more
304 complicated option syntaxes, such as what
308 uses, or the AFS model where you can skip the flag names as long as
309 the options come in the correct order.
311 Options with multiple arguments should be handled better.
313 Should be integreated with SL.
315 It's very confusing that the struct you pass in is called getargS.