1 .\" $NetBSD: getarg.3,v 1.1.1.3 2014/04/24 12:45:52 pettai Exp $
3 .\" Copyright (c) 1999 - 2002 Kungliga Tekniska Högskolan
4 .\" (Royal Institute of Technology, Stockholm, Sweden).
5 .\" All rights reserved.
7 .\" Redistribution and use in source and binary forms, with or without
8 .\" modification, are permitted provided that the following conditions
11 .\" 1. Redistributions of source code must retain the above copyright
12 .\" notice, this list of conditions and the following disclaimer.
14 .\" 2. Redistributions in binary form must reproduce the above copyright
15 .\" notice, this list of conditions and the following disclaimer in the
16 .\" documentation and/or other materials provided with the distribution.
18 .\" 3. Neither the name of the Institute nor the names of its contributors
19 .\" may be used to endorse or promote products derived from this software
20 .\" without specific prior written permission.
22 .\" THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
23 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 .\" ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
26 .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 .Dd September 24, 1999
41 .Nd collect command line options
45 .Fn getarg "struct getargs *args" "size_t num_args" "int argc" "char **argv" "int *optind"
47 .Fn arg_printusage "struct getargs *args" "size_t num_args" "const char *progname" "const char *extra_string"
50 collects any command line options given to a program in an easily used way.
52 pretty-prints the available options, with a short help text.
55 is the option specification to use, and it's an array of
65 are the argument count and argument vector to extract option from.
67 is a pointer to an integer where the index to the last processed
68 argument is stored, it must be initialised to the first index (minus
69 one) to process (normally 0) before the first call.
78 is the name of the program (to be used in the help text), and
80 is a string to print after the actual options to indicate more
81 arguments. The usefulness of this function is realised only be people
82 who has used programs that has help strings that doesn't match what
87 struct has the following elements.
90 const char *long_name;
102 const char *arg_help;
107 is the long name of the option, it can be
109 if you don't want a long name.
111 is the characted to use as short option, it can be zero. If the option
114 field gets filled in with that value interpreted as specified by the
118 is a longer help string for the option as a whole, if it's
120 the help text for the option is omitted (but it's still displayed in
123 is a description of the argument, if
125 a default value will be used, depending on the type of the option:
127 .Bl -hang -width arg_negative_flag
129 the argument is a signed integer, and
134 the argument is a string, and
139 the argument is a flag, and
143 It gets filled in with either zero or one, depending on how the option
144 is given, the normal case being one. Note that if the option isn't
145 given, the value isn't altered, so it should be initialised to some
147 .It Fa arg_negative_flag
150 but it reverses the meaning of the flag (a given short option clears
151 the flag), and the synopsis of a long option is negated.
153 the argument can be given multiple times, and the values are collected
156 should be a pointer to a
157 .Fa struct getarg_strings
158 structure, which holds a length and a string pointer.
160 argument is a double precision floating point value, and
165 allows more fine-grained control of the option parsing process.
167 should be a pointer to a
168 .Fa getarg_collect_info
171 typedef int (*getarg_collect_func)(int short_opt,
178 typedef struct getarg_collect_info {
179 getarg_collect_func func;
181 } getarg_collect_info;
186 member set to a function to call, and
188 to some application specific data. The parameters to the collect function are:
191 non-zero if this call is via a short option flag, zero otherwise
193 the whole argument list
195 pointer to the index in argv where the flag is
197 pointer to the index in argv[*optind] where the flag name starts
199 application specific data
206 but to do this correct you (more or less) have to know about the inner
209 You can skip parts of arguments by increasing
216 with this), or whole argument strings by increasing
218 (let's say you want a flag
220 to specify a coordinate); if you also have to set
224 The collect function should return one of
225 .Dv ARG_ERR_NO_MATCH , ARG_ERR_BAD_ARG , ARG_ERR_NO_ARG, ENOMEM
226 on error, zero otherwise.
228 For your convenience there is a function,
230 that returns the traditional argument string, and you pass it all
231 arguments, sans data, that where given to the collection function.
233 Don't use this more this unless you absolutely have to.
236 Option parsing is similar to what
238 uses. Short options without arguments can be compressed
243 options with arguments take these as either the rest of the
244 argv-string or as the next option
245 .Pf ( Fl o Ns Ar foo ,
249 Long option names are prefixed with -- (double dash), and the value
251 .Fl Fl foo= Ns Ar bar .
252 Long option flags can either be specified as they are
254 or with an (boolean parsable) option
255 .Pf ( Fl Fl help= Ns Ar yes ,
256 .Fl Fl help= Ns Ar true ,
257 or similar), or they can also be negated
260 .Fl Fl help= Ns no ) ,
261 and if you're really confused you can do it multiple times
262 .Pf ( Fl Fl no-no-help= Ns Ar false ,
264 .Fl Fl no-no-help= Ns Ar maybe ) .
271 char *source = "Ouagadougou";
274 int include_catalog = 1;
277 struct getargs args[] = {
278 { "source", 's', arg_string, &source,
279 "source of shippment", "city" },
280 { "destination", 'd', arg_string, &destination,
281 "destination of shippment", "city" },
282 { "weight", 'w', arg_integer, &weight,
283 "weight of shippment", "tons" },
284 { "catalog", 'c', arg_negative_flag, &include_catalog,
285 "include product catalog" },
286 { "help", 'h', arg_flag, &help_flag }
289 int num_args = sizeof(args) / sizeof(args[0]); /* number of elements in args */
291 const char *progname = "ship++";
294 main(int argc, char **argv)
297 if (getarg(args, num_args, argc, argv, &optind)) {
298 arg_printusage(args, num_args, progname, "stuff...");
302 arg_printusage(args, num_args, progname, "stuff...");
305 if (destination == NULL) {
306 fprintf(stderr, "%s: must specify destination\en", progname);
309 if (strcmp(source, destination) == 0) {
310 fprintf(stderr, "%s: destination must be different from source\en");
313 /* include more stuff here ... */
318 The output help output from this program looks like this:
321 Usage: ship++ [--source=city] [-s city] [--destination=city] [-d city]
322 [--weight=tons] [-w tons] [--no-catalog] [-c] [--help] [-h] stuff...
323 -s city, --source=city source of shippment
324 -d city, --destination=city destination of shippment
325 -w tons, --weight=tons weight of shippment
326 -c, --no-catalog include product catalog
329 It should be more flexible, so it would be possible to use other more
330 complicated option syntaxes, such as what
334 uses, or the AFS model where you can skip the flag names as long as
335 the options come in the correct order.
337 Options with multiple arguments should be handled better.
339 Should be integreated with SL.
341 It's very confusing that the struct you pass in is called getargS.