roken: prevent rk_mkdir recursion due to macro
[heimdal.git] / lib / roken / getarg.3
blobdda6e7dbf3d3f9bac52ae076e6c99832bcdc1637
1 .\" Copyright (c) 1999 - 2002 Kungliga Tekniska Högskolan
2 .\" (Royal Institute of Technology, Stockholm, Sweden).
3 .\" All rights reserved.
4 .\"
5 .\" Redistribution and use in source and binary forms, with or without
6 .\" modification, are permitted provided that the following conditions
7 .\" are met:
8 .\"
9 .\" 1. Redistributions of source code must retain the above copyright
10 .\"    notice, this list of conditions and the following disclaimer.
11 .\"
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.
15 .\"
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.
19 .\"
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
30 .\" SUCH DAMAGE.
31 .\"
32 .\" $Id$
33 .Dd September 24, 1999
34 .Dt GETARG 3
35 .Os ROKEN
36 .Sh NAME
37 .Nm getarg ,
38 .Nm arg_printusage
39 .Nd collect command line options
40 .Sh SYNOPSIS
41 .In getarg.h
42 .Ft int
43 .Fn getarg "struct getargs *args" "size_t num_args" "int argc" "char **argv" "int *optind"
44 .Ft void
45 .Fn arg_printusage "struct getargs *args" "size_t num_args" "const char *progname" "const char *extra_string"
46 .Sh DESCRIPTION
47 .Fn getarg
48 collects any command line options given to a program in an easily used way.
49 .Fn arg_printusage
50 pretty-prints the available options, with a short help text.
51 .Pp
52 .Fa args
53 is the option specification to use, and it's an array of
54 .Fa struct getargs
55 elements.
56 .Fa num_args
57 is the size of
58 .Fa args
59 (in elements).
60 .Fa argc
61 and
62 .Fa argv
63 are the argument count and argument vector to extract option from.
64 .Fa optind
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.
68 .Pp
69 .Fa arg_printusage
70 take the same
71 .Fa args
72 and
73 .Fa num_args
74 as getarg;
75 .Fa progname
76 is the name of the program (to be used in the help text), and
77 .Fa extra_string
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
81 the code does.
82 .Pp
83 The
84 .Fa getargs
85 struct has the following elements.
86 .Bd -literal
87 struct getargs{
88     const char *long_name;
89     char short_name;
90     enum { arg_integer,
91            arg_string,
92            arg_flag,
93            arg_negative_flag,
94            arg_strings,
95            arg_double,
96            arg_collect
97     } type;
98     void *value;
99     const char *help;
100     const char *arg_help;
104 .Fa long_name
105 is the long name of the option, it can be
106 .Dv NULL ,
107 if you don't want a long name.
108 .Fa short_name
109 is the characted to use as short option, it can be zero. If the option
110 has a value the
111 .Fa value
112 field gets filled in with that value interpreted as specified by the
113 .Fa type
114 field.
115 .Fa help
116 is a longer help string for the option as a whole, if it's
117 .Dv NULL
118 the help text for the option is omitted (but it's still displayed in
119 the synopsis).
120 .Fa arg_help
121 is a description of the argument, if
122 .Dv NULL
123 a default value will be used, depending on the type of the option:
125 .Bl -hang -width arg_negative_flag
126 .It arg_integer
127 the argument is a signed integer, and
128 .Fa value
129 should point to an
130 .Fa int .
131 .It Fa arg_string
132 the argument is a string, and
133 .Fa value
134 should point to a
135 .Fa char* .
136 .It Fa arg_flag
137 the argument is a flag, and
138 .Fa value
139 should point to a
140 .Fa int .
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
144 useful default.
145 .It Fa arg_negative_flag
146 this is the same as
147 .Fa arg_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.
150 .It Fa arg_strings
151 the argument can be given multiple times, and the values are collected
152 in an array;
153 .Fa value
154 should be a pointer to a
155 .Fa struct getarg_strings
156 structure, which holds a length and a string pointer.
157 .It Fa arg_double
158 argument is a double precision floating point value, and
159 .Fa value
160 should point to a
161 .Fa double .
162 .It Fa arg_collect
163 allows more fine-grained control of the option parsing process.
164 .Fa value
165 should be a pointer to a
166 .Fa getarg_collect_info
167 structure:
168 .Bd -literal
169 typedef int (*getarg_collect_func)(int short_opt,
170                                    int argc,
171                                    char **argv,
172                                    int *optind,
173                                    int *optarg,
174                                    void *data);
176 typedef struct getarg_collect_info {
177     getarg_collect_func func;
178     void *data;
179 } getarg_collect_info;
182 With the
183 .Fa func
184 member set to a function to call, and
185 .Fa data
186 to some application specific data. The parameters to the collect function are:
187 .Bl -inset
188 .It Fa short_flag
189 non-zero if this call is via a short option flag, zero otherwise
190 .It Fa argc , argv
191 the whole argument list
192 .It Fa optind
193 pointer to the index in argv where the flag is
194 .It Fa optarg
195 pointer to the index in argv[*optind] where the flag name starts
196 .It Fa data
197 application specific data
200 You can modify
201 .Fa *optind ,
203 .Fa *optarg ,
204 but to do this correct you (more or less) have to know about the inner
205 workings of getarg.
207 You can skip parts of arguments by increasing
208 .Fa *optarg
209 (you could
210 implement the
211 .Fl z Ns Ar 3
212 set of flags from
213 .Nm gzip
214 with this), or whole argument strings by increasing
215 .Fa *optind
216 (let's say you want a flag
217 .Fl c Ar x y z
218 to specify a coordinate); if you also have to set
219 .Fa *optarg
220 to a sane value.
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,
227 .Fn getarg_optarg ,
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
235 .Xr getopt
236 uses. Short options without arguments can be compressed
237 .Pf ( Fl xyz
238 is the same as
239 .Fl x y z ) ,
240 and short
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 ,
245 .Fl o Ar foo ) .
247 Long option names are prefixed with -- (double dash), and the value
248 with a = (equal),
249 .Fl Fl foo= Ns Ar bar .
250 Long option flags can either be specified as they are
251 .Pf ( Fl Fl help ) ,
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
256 .Pf ( Fl Fl no-help
257 is the same as
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 ,
261 or even
262 .Fl Fl no-no-help= Ns Ar maybe ) .
263 .Sh EXAMPLE
264 .Bd -literal
265 #include <stdio.h>
266 #include <string.h>
267 #include <getarg.h>
269 char *source = "Ouagadougou";
270 char *destination;
271 int weight;
272 int include_catalog = 1;
273 int help_flag;
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)
294     int optind = 0;
295     if (getarg(args, num_args, argc, argv, &optind)) {
296         arg_printusage(args, num_args, progname, "stuff...");
297         exit (1);
298     }
299     if (help_flag) {
300         arg_printusage(args, num_args, progname, "stuff...");
301         exit (0);
302     }
303     if (destination == NULL) {
304         fprintf(stderr, "%s: must specify destination\en", progname);
305         exit(1);
306     }
307     if (strcmp(source, destination) == 0) {
308         fprintf(stderr, "%s: destination must be different from source\en");
309         exit(1);
310     }
311     /* include more stuff here ... */
312     exit(2);
316 The output help output from this program looks like this:
317 .Bd -literal
318 $ ship++ --help
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
326 .Sh BUGS
327 It should be more flexible, so it would be possible to use other more
328 complicated option syntaxes, such as what
329 .Xr ps 1 ,
331 .Xr tar 1 ,
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 integreated with SL.
339 It's very confusing that the struct you pass in is called getargS.
340 .Sh SEE ALSO
341 .Xr getopt 3