]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - crypto/heimdal/lib/roken/getarg.3
This commit was generated by cvs2svn to compensate for changes in r55924,
[FreeBSD/FreeBSD.git] / crypto / heimdal / lib / roken / getarg.3
1 .\" Copyright (c) 1999 Kungliga Tekniska Högskolan
2 .\" $Id: getarg.3,v 1.2 1999/10/18 17:14:31 joda Exp $
3 .Dd September 24, 1999
4 .Dt GETARG 3
5 .Os ROKEN
6 .Sh NAME
7 .Nm getarg , 
8 .Nm arg_printusage
9 .Nd collect command line options
10 .Sh SYNOPSIS
11 .Fd #include <getarg.h>
12
13 .Ft int
14 .Fn getarg "struct getargs *args" "size_t num_args" "int argc" "char **argv" "int *optind"
15
16 .Ft void
17 .Fn arg_printusage "struct getargs *args" "size_t num_args" "const char *progname" "const char *extra_string"
18
19 .Sh DESCRIPTION
20 .Fn getarg
21 collects any command line options given to a program in an easily used way. 
22 .Fn arg_printusage 
23 pretty-prints the available options, with a short help text.
24 .Pp
25 .Fa args
26 is the option specification to use, and it's an array of 
27 .Fa struct getargs
28 elements.
29 .Fa num_args
30 is the size of
31 .Fa args
32 (in elements).
33 .Fa argc
34 and
35 .Fa argv
36 are the argument count and argument vector to extract option from.
37 .Fa optind
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.
41 .Pp
42 .Fa arg_printusage
43 take the same
44 .Fa args
45 and
46 .Fa num_args
47 as getarg;
48 .Fa progname is the name of the program (to be used in the help text), and 
49 .Fa extra_string
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
53 the code does.
54 .Pp
55 The
56 .Fa getargs
57 struct has the following elements.
58
59 .Bd -literal
60 struct getargs{
61     const char *long_name;
62     char short_name;
63     enum { arg_integer, 
64            arg_string, 
65            arg_flag, 
66            arg_negative_flag, 
67            arg_strings,
68            arg_double,
69            arg_collect
70     } type;
71     void *value;
72     const char *help;
73     const char *arg_help;
74 };
75 .Ed
76 .Pp
77 .Fa long_name
78 is the long name of the option, it can be 
79 .Dv NULL ,
80 if you don't want a long name.
81 .Fa short_name 
82 is the characted to use as short option, it can be zero. If the option
83 has a value the
84 .Fa value
85 field gets filled in with that value interpreted as specified by the 
86 .Fa type
87 field.
88 .Fa help
89 is a longer help string for the option as a whole, if it's
90 .Dv NULL
91 the help text for the option is omitted (but it's still displayed in
92 the synopsis).
93 .Fa arg_help
94 is a description of the argument, if
95 .Dv NULL
96 a default value will be used, depending on the type of the option:
97 .Pp
98 .Bl -hang -width arg_negative_flag
99 .It arg_integer
100 the argument is a signed integer, and
101 .Fa value
102 should point to an
103 .Fa int .
104 .It Fa arg_string
105 the argument is a string, and
106 .Fa value
107 should point to a
108 .Fa char* .
109 .It Fa arg_flag
110 the argument is a flag, and
111 .Fa value
112 should point to a
113 .Fa int . 
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
117 useful default.
118 .It Fa arg_negative_flag
119 this is the same as 
120 .Fa arg_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.
123 .It Fa arg_strings
124 the argument can be given multiple times, and the values are collected
125 in an array;
126 .Fa value
127 should be a pointer to a 
128 .Fa struct getarg_strings
129 structure, which holds a length and a string pointer.
130 .It Fa arg_double
131 argument is a double precision floating point value, and
132 .Fa value
133 should point to a
134 .Fa double .
135 .It Fa arg_collect
136 allows more fine-grained control of the option parsing process.
137 .Fa value
138 should be a pointer to a 
139 .Fa getarg_collect_info
140 structure:
141 .Bd -literal
142 typedef int (*getarg_collect_func)(int short_opt,
143                                    int argc,
144                                    char **argv,
145                                    int *optind,
146                                    int *optarg,
147                                    void *data);
148
149 typedef struct getarg_collect_info {
150     getarg_collect_func func;
151     void *data;
152 } getarg_collect_info;
153 .Ed
154 .Pp
155 With the
156 .Fa func
157 member set to a function to call, and 
158 .Fa data
159 to some application specific data. The parameters to the collect function are:
160 .Bl -inset
161 .It Fa short_flag
162 non-zero if this call is via a short option flag, zero otherwise
163 .It Fa argc , argv
164 the whole argument list
165 .It Fa optind
166 pointer to the index in argv where the flag is
167 .It Fa optarg
168 pointer to the index in argv[*optind] where the flag name starts
169 .It Fa data
170 application specific data
171 .El
172 .Pp
173 You can modify
174 .Fa *optind ,
175 and 
176 .Fa *optarg ,
177 but to do this correct you (more or less) have to know about the inner
178 workings of getarg.
179  
180 You can skip parts of arguments by increasing
181 .Fa *optarg
182 (you could
183 implement the 
184 .Fl z Ns Ar 3
185 set of flags from
186 .Nm gzip
187 with this), or whole argument strings by increasing
188 .Fa *optind
189 (let's say you want a flag 
190 .Fl c Ar x y z
191 to specify a coordinate); if you also have to set
192 .Fa *optarg
193 to a sane value.
194 .Pp
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.
198 .Pp
199 For your convenience there is a function,
200 .Fn getarg_optarg ,
201 that returns the traditional argument string, and you pass it all
202 arguments, sans data, that where given to the collection function.
203 .Pp
204 Don't use this more this unless you absolutely have to.
205 .El
206 .Pp
207 Option parsing is similar to what 
208 .Xr getopt
209 uses. Short options without arguments can be compressed
210 .Pf ( Fl xyz
211 is the same as
212 .Fl x y z ) ,
213 and short
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 ,
217 or
218 .Fl o Ar foo ) .
219 .Pp
220 Long option names are prefixed with -- (double dash), and the value
221 with a = (equal),
222 .Fl -foo= Ns Ar bar .
223 Long option flags can either be specified as they are 
224 .Pf ( Fl -help ) ,
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 
229 .Pf ( Fl -no-help
230 is the same as 
231 .Fl -help= Ns no ) ,
232 and if you're really confused you can do it multiple times
233 .Pf ( Fl -no-no-help= Ns Ar false ,
234 or even 
235 .Fl -no-no-help= Ns Ar maybe ) .
236
237 .Pp
238 .Sh EXAMPLE
239 .Bd -literal
240 #include <stdio.h>
241 #include <string.h>
242 #include <getarg.h>
243
244 char *source = "Ouagadougou";
245 char *destination;
246 int weight;
247 int include_catalog = 1;
248 int help_flag;
249
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 }
260 };
261
262 int num_args = sizeof(args) / sizeof(args[0]); /* number of elements in args */
263
264 const char *progname = "ship++";
265
266 int
267 main(int argc, char **argv)
268 {
269     int optind = 0;
270     if (getarg(args, num_args, argc, argv, &optind)) {
271         arg_printusage(args, num_args, progname, "stuff...");
272         exit (1);
273     }
274     if (help_flag) {
275         arg_printusage(args, num_args, progname, "stuff...");
276         exit (0);
277     }
278     if (destination == NULL) {
279         fprintf(stderr, "%s: must specify destination\n", progname);
280         exit(1);
281     }
282     if (strcmp(source, destination) == 0) {
283         fprintf(stderr, "%s: destination must be different from source\n");
284         exit(1);
285     }
286     /* include more stuff here ... */
287     exit(2);
288 }
289 .Ed
290 .Pp
291 The output help output from this program looks like this:
292 .Bd -literal
293 $ ship++ --help                                            
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
300 .Ed
301
302 .Sh BUGS
303 It should be more flexible, so it would be possible to use other more
304 complicated option syntaxes, such as what
305 .Xr ps 1 ,
306 and 
307 .Xr tar 1 ,
308 uses, or the AFS model where you can skip the flag names as long as
309 the options come in the correct order.
310 .Pp
311 Options with multiple arguments should be handled better.
312 .Pp
313 Should be integreated with SL.
314 .Pp
315 It's very confusing that the struct you pass in is called getargS.
316 .Sh SEE ALSO
317 .Xr getopt 3