1 .\" Copyright (c) 1999 - 2002 Kungliga Tekniska Högskolan
2 .\" (Royal Institute of Technology, Stockholm, Sweden).
3 .\" All rights reserved.
5 .\" Redistribution and use in source and binary forms, with or without
6 .\" modification, are permitted provided that the following conditions
9 .\" 1. Redistributions of source code must retain the above copyright
10 .\" notice, this list of conditions and the following disclaimer.
12 .\" 2. Redistributions in binary form must reproduce the above copyright
13 .\" notice, this list of conditions and the following disclaimer in the
14 .\" documentation and/or other materials provided with the distribution.
16 .\" 3. Neither the name of the Institute nor the names of its contributors
17 .\" may be used to endorse or promote products derived from this software
18 .\" without specific prior written permission.
20 .\" THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
21 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 .\" ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
24 .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 .Dd September 24, 1999
39 .Nd collect command line options
43 .Fn getarg "struct getargs *args" "size_t num_args" "int argc" "char **argv" "int *optind"
45 .Fn arg_printusage "struct getargs *args" "size_t num_args" "const char *progname" "const char *extra_string"
48 collects any command line options given to a program in an easily used way.
50 pretty-prints the available options, with a short help text.
53 is the option specification to use, and it's an array of
63 are the argument count and argument vector to extract option from.
65 is a pointer to an integer where the index to the last processed
66 argument is stored, it must be initialised to the first index (minus
67 one) to process (normally 0) before the first call.
76 is the name of the program (to be used in the help text), and
78 is a string to print after the actual options to indicate more
79 arguments. The usefulness of this function is realised only be people
80 who has used programs that has help strings that doesn't match what
85 struct has the following elements.
88 const char *long_name;
100 const char *arg_help;
105 is the long name of the option, it can be
107 if you don't want a long name.
109 is the characted to use as short option, it can be zero. If the option
112 field gets filled in with that value interpreted as specified by the
116 is a longer help string for the option as a whole, if it's
118 the help text for the option is omitted (but it's still displayed in
121 is a description of the argument, if
123 a default value will be used, depending on the type of the option:
125 .Bl -hang -width arg_negative_flag
127 the argument is a signed integer, and
132 the argument is a string, and
137 the argument is a flag, and
141 It gets filled in with either zero or one, depending on how the option
142 is given, the normal case being one. Note that if the option isn't
143 given, the value isn't altered, so it should be initialised to some
145 .It Fa arg_negative_flag
148 but it reverses the meaning of the flag (a given short option clears
149 the flag), and the synopsis of a long option is negated.
151 the argument can be given multiple times, and the values are collected
154 should be a pointer to a
155 .Fa struct getarg_strings
156 structure, which holds a length and a string pointer.
158 argument is a double precision floating point value, and
163 allows more fine-grained control of the option parsing process.
165 should be a pointer to a
166 .Fa getarg_collect_info
169 typedef int (*getarg_collect_func)(int short_opt,
176 typedef struct getarg_collect_info {
177 getarg_collect_func func;
179 } getarg_collect_info;
184 member set to a function to call, and
186 to some application specific data. The parameters to the collect function are:
189 non-zero if this call is via a short option flag, zero otherwise
191 the whole argument list
193 pointer to the index in argv where the flag is
195 pointer to the index in argv[*optind] where the flag name starts
197 application specific data
204 but to do this correct you (more or less) have to know about the inner
207 You can skip parts of arguments by increasing
214 with this), or whole argument strings by increasing
216 (let's say you want a flag
218 to specify a coordinate); if you also have to set
222 The collect function should return one of
223 .Dv ARG_ERR_NO_MATCH , ARG_ERR_BAD_ARG , ARG_ERR_NO_ARG, ENOMEM
224 on error, zero otherwise.
226 For your convenience there is a function,
228 that returns the traditional argument string, and you pass it all
229 arguments, sans data, that where given to the collection function.
231 Don't use this more this unless you absolutely have to.
234 Option parsing is similar to what
236 uses. Short options without arguments can be compressed
241 options with arguments take these as either the rest of the
242 argv-string or as the next option
243 .Pf ( Fl o Ns Ar foo ,
247 Long option names are prefixed with -- (double dash), and the value
249 .Fl Fl foo= Ns Ar bar .
250 Long option flags can either be specified as they are
252 or with an (boolean parsable) option
253 .Pf ( Fl Fl help= Ns Ar yes ,
254 .Fl Fl help= Ns Ar true ,
255 or similar), or they can also be negated
258 .Fl Fl help= Ns no ) ,
259 and if you're really confused you can do it multiple times
260 .Pf ( Fl Fl no-no-help= Ns Ar false ,
262 .Fl Fl no-no-help= Ns Ar maybe ) .
269 char *source = "Ouagadougou";
272 int include_catalog = 1;
275 struct getargs args[] = {
276 { "source", 's', arg_string, &source,
277 "source of shippment", "city" },
278 { "destination", 'd', arg_string, &destination,
279 "destination of shippment", "city" },
280 { "weight", 'w', arg_integer, &weight,
281 "weight of shippment", "tons" },
282 { "catalog", 'c', arg_negative_flag, &include_catalog,
283 "include product catalog" },
284 { "help", 'h', arg_flag, &help_flag }
287 int num_args = sizeof(args) / sizeof(args[0]); /* number of elements in args */
289 const char *progname = "ship++";
292 main(int argc, char **argv)
295 if (getarg(args, num_args, argc, argv, &optind)) {
296 arg_printusage(args, num_args, progname, "stuff...");
300 arg_printusage(args, num_args, progname, "stuff...");
303 if (destination == NULL) {
304 fprintf(stderr, "%s: must specify destination\en", progname);
307 if (strcmp(source, destination) == 0) {
308 fprintf(stderr, "%s: destination must be different from source\en");
311 /* include more stuff here ... */
316 The output help output from this program looks like this:
319 Usage: ship++ [--source=city] [-s city] [--destination=city] [-d city]
320 [--weight=tons] [-w tons] [--no-catalog] [-c] [--help] [-h] stuff...
321 -s city, --source=city source of shippment
322 -d city, --destination=city destination of shippment
323 -w tons, --weight=tons weight of shippment
324 -c, --no-catalog include product catalog
327 It should be more flexible, so it would be possible to use other more
328 complicated option syntaxes, such as what
332 uses, or the AFS model where you can skip the flag names as long as
333 the options come in the correct order.
335 Options with multiple arguments should be handled better.
337 Should be integrated with SL.
339 It's very confusing that the struct you pass in is called getargS.