xref: /netbsd-src/crypto/external/bsd/heimdal/dist/lib/roken/getarg.3 (revision d3273b5b76f5afaafe308cead5511dbb8df8c5e9)
1.\"	$NetBSD: getarg.3,v 1.2 2017/01/28 21:31:50 christos Exp $
2.\"
3.\" Copyright (c) 1999 - 2002 Kungliga Tekniska Högskolan
4.\" (Royal Institute of Technology, Stockholm, Sweden).
5.\" All rights reserved.
6.\"
7.\" Redistribution and use in source and binary forms, with or without
8.\" modification, are permitted provided that the following conditions
9.\" are met:
10.\"
11.\" 1. Redistributions of source code must retain the above copyright
12.\"    notice, this list of conditions and the following disclaimer.
13.\"
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.
17.\"
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.
21.\"
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
32.\" SUCH DAMAGE.
33.\"
34.\" Id
35.Dd September 24, 1999
36.Dt GETARG 3
37.Os ROKEN
38.Sh NAME
39.Nm getarg ,
40.Nm arg_printusage
41.Nd collect command line options
42.Sh SYNOPSIS
43.In getarg.h
44.Ft int
45.Fn getarg "struct getargs *args" "size_t num_args" "int argc" "char **argv" "int *optind"
46.Ft void
47.Fn arg_printusage "struct getargs *args" "size_t num_args" "const char *progname" "const char *extra_string"
48.Sh DESCRIPTION
49.Fn getarg
50collects any command line options given to a program in an easily used way.
51.Fn arg_printusage
52pretty-prints the available options, with a short help text.
53.Pp
54.Fa args
55is the option specification to use, and it's an array of
56.Fa struct getargs
57elements.
58.Fa num_args
59is the size of
60.Fa args
61(in elements).
62.Fa argc
63and
64.Fa argv
65are the argument count and argument vector to extract option from.
66.Fa optind
67is a pointer to an integer where the index to the last processed
68argument is stored, it must be initialised to the first index (minus
69one) to process (normally 0) before the first call.
70.Pp
71.Fa arg_printusage
72take the same
73.Fa args
74and
75.Fa num_args
76as getarg;
77.Fa progname
78is the name of the program (to be used in the help text), and
79.Fa extra_string
80is a string to print after the actual options to indicate more
81arguments. The usefulness of this function is realised only be people
82who has used programs that has help strings that doesn't match what
83the code does.
84.Pp
85The
86.Fa getargs
87struct has the following elements.
88.Bd -literal
89struct getargs{
90    const char *long_name;
91    char short_name;
92    enum { arg_integer,
93	   arg_string,
94	   arg_flag,
95	   arg_negative_flag,
96	   arg_strings,
97	   arg_double,
98           arg_collect
99    } type;
100    void *value;
101    const char *help;
102    const char *arg_help;
103};
104.Ed
105.Pp
106.Fa long_name
107is the long name of the option, it can be
108.Dv NULL ,
109if you don't want a long name.
110.Fa short_name
111is the characted to use as short option, it can be zero. If the option
112has a value the
113.Fa value
114field gets filled in with that value interpreted as specified by the
115.Fa type
116field.
117.Fa help
118is a longer help string for the option as a whole, if it's
119.Dv NULL
120the help text for the option is omitted (but it's still displayed in
121the synopsis).
122.Fa arg_help
123is a description of the argument, if
124.Dv NULL
125a default value will be used, depending on the type of the option:
126.Pp
127.Bl -hang -width arg_negative_flag
128.It arg_integer
129the argument is a signed integer, and
130.Fa value
131should point to an
132.Fa int .
133.It Fa arg_string
134the argument is a string, and
135.Fa value
136should point to a
137.Fa char* .
138.It Fa arg_flag
139the argument is a flag, and
140.Fa value
141should point to a
142.Fa int .
143It gets filled in with either zero or one, depending on how the option
144is given, the normal case being one. Note that if the option isn't
145given, the value isn't altered, so it should be initialised to some
146useful default.
147.It Fa arg_negative_flag
148this is the same as
149.Fa arg_flag
150but it reverses the meaning of the flag (a given short option clears
151the flag), and the synopsis of a long option is negated.
152.It Fa arg_strings
153the argument can be given multiple times, and the values are collected
154in an array;
155.Fa value
156should be a pointer to a
157.Fa struct getarg_strings
158structure, which holds a length and a string pointer.
159.It Fa arg_double
160argument is a double precision floating point value, and
161.Fa value
162should point to a
163.Fa double .
164.It Fa arg_collect
165allows more fine-grained control of the option parsing process.
166.Fa value
167should be a pointer to a
168.Fa getarg_collect_info
169structure:
170.Bd -literal
171typedef int (*getarg_collect_func)(int short_opt,
172				   int argc,
173				   char **argv,
174				   int *optind,
175				   int *optarg,
176				   void *data);
177
178typedef struct getarg_collect_info {
179    getarg_collect_func func;
180    void *data;
181} getarg_collect_info;
182.Ed
183.Pp
184With the
185.Fa func
186member set to a function to call, and
187.Fa data
188to some application specific data. The parameters to the collect function are:
189.Bl -inset
190.It Fa short_flag
191non-zero if this call is via a short option flag, zero otherwise
192.It Fa argc , argv
193the whole argument list
194.It Fa optind
195pointer to the index in argv where the flag is
196.It Fa optarg
197pointer to the index in argv[*optind] where the flag name starts
198.It Fa data
199application specific data
200.El
201.Pp
202You can modify
203.Fa *optind ,
204and
205.Fa *optarg ,
206but to do this correct you (more or less) have to know about the inner
207workings of getarg.
208.Pp
209You can skip parts of arguments by increasing
210.Fa *optarg
211(you could
212implement the
213.Fl z Ns Ar 3
214set of flags from
215.Nm gzip
216with this), or whole argument strings by increasing
217.Fa *optind
218(let's say you want a flag
219.Fl c Ar x y z
220to specify a coordinate); if you also have to set
221.Fa *optarg
222to a sane value.
223.Pp
224The collect function should return one of
225.Dv ARG_ERR_NO_MATCH , ARG_ERR_BAD_ARG , ARG_ERR_NO_ARG, ENOMEM
226on error, zero otherwise.
227.Pp
228For your convenience there is a function,
229.Fn getarg_optarg ,
230that returns the traditional argument string, and you pass it all
231arguments, sans data, that where given to the collection function.
232.Pp
233Don't use this more this unless you absolutely have to.
234.El
235.Pp
236Option parsing is similar to what
237.Xr getopt
238uses. Short options without arguments can be compressed
239.Pf ( Fl xyz
240is the same as
241.Fl x y z ) ,
242and short
243options with arguments take these as either the rest of the
244argv-string or as the next option
245.Pf ( Fl o Ns Ar foo ,
246or
247.Fl o Ar foo ) .
248.Pp
249Long option names are prefixed with -- (double dash), and the value
250with a = (equal),
251.Fl Fl foo= Ns Ar bar .
252Long option flags can either be specified as they are
253.Pf ( Fl Fl help ) ,
254or with an (boolean parsable) option
255.Pf ( Fl Fl help= Ns Ar yes ,
256.Fl Fl help= Ns Ar true ,
257or similar), or they can also be negated
258.Pf ( Fl Fl no-help
259is the same as
260.Fl Fl help= Ns no ) ,
261and if you're really confused you can do it multiple times
262.Pf ( Fl Fl no-no-help= Ns Ar false ,
263or even
264.Fl Fl no-no-help= Ns Ar maybe ) .
265.Sh EXAMPLE
266.Bd -literal
267#include <stdio.h>
268#include <string.h>
269#include <getarg.h>
270
271char *source = "Ouagadougou";
272char *destination;
273int weight;
274int include_catalog = 1;
275int help_flag;
276
277struct 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 }
287};
288
289int num_args = sizeof(args) / sizeof(args[0]); /* number of elements in args */
290
291const char *progname = "ship++";
292
293int
294main(int argc, char **argv)
295{
296    int optind = 0;
297    if (getarg(args, num_args, argc, argv, &optind)) {
298	arg_printusage(args, num_args, progname, "stuff...");
299	exit (1);
300    }
301    if (help_flag) {
302	arg_printusage(args, num_args, progname, "stuff...");
303	exit (0);
304    }
305    if (destination == NULL) {
306	fprintf(stderr, "%s: must specify destination\en", progname);
307	exit(1);
308    }
309    if (strcmp(source, destination) == 0) {
310	fprintf(stderr, "%s: destination must be different from source\en");
311	exit(1);
312    }
313    /* include more stuff here ... */
314    exit(2);
315}
316.Ed
317.Pp
318The output help output from this program looks like this:
319.Bd -literal
320$ ship++ --help
321Usage: 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
327.Ed
328.Sh BUGS
329It should be more flexible, so it would be possible to use other more
330complicated option syntaxes, such as what
331.Xr ps 1 ,
332and
333.Xr tar 1 ,
334uses, or the AFS model where you can skip the flag names as long as
335the options come in the correct order.
336.Pp
337Options with multiple arguments should be handled better.
338.Pp
339Should be integrated with SL.
340.Pp
341It's very confusing that the struct you pass in is called getargS.
342.Sh SEE ALSO
343.Xr getopt 3
344