source: heimdal/trunk/lib/roken/getarg.cat3@ 3

Last change on this file since 3 was 1, checked in by Paul Smedley, 10 years ago

Initial commit of Heimdal 1.5.3

File size: 11.0 KB
Line 
1
2GETARG(3) BSD Library Functions Manual GETARG(3)
3
4NNAAMMEE
5 ggeettaarrgg, aarrgg__pprriinnttuussaaggee -- collect command line options
6
7SSYYNNOOPPSSIISS
8 ##iinncclluuddee <<ggeettaarrgg..hh>>
9
10 _i_n_t
11 ggeettaarrgg(_s_t_r_u_c_t _g_e_t_a_r_g_s _*_a_r_g_s, _s_i_z_e___t _n_u_m___a_r_g_s, _i_n_t _a_r_g_c, _c_h_a_r _*_*_a_r_g_v,
12 _i_n_t _*_o_p_t_i_n_d);
13
14 _v_o_i_d
15 aarrgg__pprriinnttuussaaggee(_s_t_r_u_c_t _g_e_t_a_r_g_s _*_a_r_g_s, _s_i_z_e___t _n_u_m___a_r_g_s,
16 _c_o_n_s_t _c_h_a_r _*_p_r_o_g_n_a_m_e, _c_o_n_s_t _c_h_a_r _*_e_x_t_r_a___s_t_r_i_n_g);
17
18DDEESSCCRRIIPPTTIIOONN
19 ggeettaarrgg() collects any command line options given to a program in an eas-
20 ily used way. aarrgg__pprriinnttuussaaggee() pretty-prints the available options, with
21 a short help text.
22
23 _a_r_g_s is the option specification to use, and it's an array of _s_t_r_u_c_t
24 _g_e_t_a_r_g_s elements. _n_u_m___a_r_g_s is the size of _a_r_g_s (in elements). _a_r_g_c and
25 _a_r_g_v are the argument count and argument vector to extract option from.
26 _o_p_t_i_n_d is a pointer to an integer where the index to the last processed
27 argument is stored, it must be initialised to the first index (minus one)
28 to process (normally 0) before the first call.
29
30 _a_r_g___p_r_i_n_t_u_s_a_g_e take the same _a_r_g_s and _n_u_m___a_r_g_s as getarg; _p_r_o_g_n_a_m_e is the
31 name of the program (to be used in the help text), and _e_x_t_r_a___s_t_r_i_n_g is a
32 string to print after the actual options to indicate more arguments. The
33 usefulness of this function is realised only be people who has used pro-
34 grams that has help strings that doesn't match what the code does.
35
36 The _g_e_t_a_r_g_s struct has the following elements.
37
38 struct getargs{
39 const char *long_name;
40 char short_name;
41 enum { arg_integer,
42 arg_string,
43 arg_flag,
44 arg_negative_flag,
45 arg_strings,
46 arg_double,
47 arg_collect
48 } type;
49 void *value;
50 const char *help;
51 const char *arg_help;
52 };
53
54 _l_o_n_g___n_a_m_e is the long name of the option, it can be NULL, if you don't
55 want a long name. _s_h_o_r_t___n_a_m_e is the characted to use as short option, it
56 can be zero. If the option has a value the _v_a_l_u_e field gets filled in
57 with that value interpreted as specified by the _t_y_p_e field. _h_e_l_p is a
58 longer help string for the option as a whole, if it's NULL the help text
59 for the option is omitted (but it's still displayed in the synopsis).
60 _a_r_g___h_e_l_p is a description of the argument, if NULL a default value will
61 be used, depending on the type of the option:
62
63 arg_integer the argument is a signed integer, and _v_a_l_u_e should
64 point to an _i_n_t.
65
66 _a_r_g___s_t_r_i_n_g the argument is a string, and _v_a_l_u_e should point to a
67 _c_h_a_r_*.
68
69 _a_r_g___f_l_a_g the argument is a flag, and _v_a_l_u_e should point to a
70 _i_n_t. It gets filled in with either zero or one,
71 depending on how the option is given, the normal case
72 being one. Note that if the option isn't given, the
73 value isn't altered, so it should be initialised to
74 some useful default.
75
76 _a_r_g___n_e_g_a_t_i_v_e___f_l_a_g this is the same as _a_r_g___f_l_a_g but it reverses the mean-
77 ing of the flag (a given short option clears the
78 flag), and the synopsis of a long option is negated.
79
80 _a_r_g___s_t_r_i_n_g_s the argument can be given multiple times, and the val-
81 ues are collected in an array; _v_a_l_u_e should be a
82 pointer to a _s_t_r_u_c_t _g_e_t_a_r_g___s_t_r_i_n_g_s structure, which
83 holds a length and a string pointer.
84
85 _a_r_g___d_o_u_b_l_e argument is a double precision floating point value,
86 and _v_a_l_u_e should point to a _d_o_u_b_l_e.
87
88 _a_r_g___c_o_l_l_e_c_t allows more fine-grained control of the option parsing
89 process. _v_a_l_u_e should be a pointer to a
90 _g_e_t_a_r_g___c_o_l_l_e_c_t___i_n_f_o structure:
91
92 typedef int (*getarg_collect_func)(int short_opt,
93 int argc,
94 char **argv,
95 int *optind,
96 int *optarg,
97 void *data);
98
99 typedef struct getarg_collect_info {
100 getarg_collect_func func;
101 void *data;
102 } getarg_collect_info;
103
104 With the _f_u_n_c member set to a function to call, and
105 _d_a_t_a to some application specific data. The parameters
106 to the collect function are:
107
108 _s_h_o_r_t___f_l_a_g non-zero if this call is via a short option
109 flag, zero otherwise
110
111 _a_r_g_c, _a_r_g_v the whole argument list
112
113 _o_p_t_i_n_d pointer to the index in argv where the flag is
114
115 _o_p_t_a_r_g pointer to the index in argv[*optind] where the
116 flag name starts
117
118 _d_a_t_a application specific data
119
120 You can modify _*_o_p_t_i_n_d, and _*_o_p_t_a_r_g, but to do this
121 correct you (more or less) have to know about the
122 inner workings of getarg.
123
124 You can skip parts of arguments by increasing _*_o_p_t_a_r_g
125 (you could implement the --zz_3 set of flags from ggzziipp
126 with this), or whole argument strings by increasing
127 _*_o_p_t_i_n_d (let's say you want a flag --cc _x _y _z to specify
128 a coordinate); if you also have to set _*_o_p_t_a_r_g to a
129 sane value.
130
131 The collect function should return one of
132 ARG_ERR_NO_MATCH, ARG_ERR_BAD_ARG, ARG_ERR_NO_ARG,
133 ENOMEM on error, zero otherwise.
134
135 For your convenience there is a function,
136 ggeettaarrgg__ooppttaarrgg(), that returns the traditional argument
137 string, and you pass it all arguments, sans data, that
138 where given to the collection function.
139
140 Don't use this more this unless you absolutely have
141 to.
142
143 Option parsing is similar to what getopt uses. Short options without
144 arguments can be compressed (--xxyyzz is the same as --xx --yy --zz), and short
145 options with arguments take these as either the rest of the argv-string
146 or as the next option (--oo_f_o_o, or --oo _f_o_o).
147
148 Long option names are prefixed with -- (double dash), and the value with
149 a = (equal), ----ffoooo==_b_a_r. Long option flags can either be specified as
150 they are (----hheellpp), or with an (boolean parsable) option (----hheellpp==_y_e_s,
151 ----hheellpp==_t_r_u_e, or similar), or they can also be negated (----nnoo--hheellpp is the
152 same as ----hheellpp==no), and if you're really confused you can do it multiple
153 times (----nnoo--nnoo--hheellpp==_f_a_l_s_e, or even ----nnoo--nnoo--hheellpp==_m_a_y_b_e).
154
155EEXXAAMMPPLLEE
156 #include <stdio.h>
157 #include <string.h>
158 #include <getarg.h>
159
160 char *source = "Ouagadougou";
161 char *destination;
162 int weight;
163 int include_catalog = 1;
164 int help_flag;
165
166 struct getargs args[] = {
167 { "source", 's', arg_string, &source,
168 "source of shippment", "city" },
169 { "destination", 'd', arg_string, &destination,
170 "destination of shippment", "city" },
171 { "weight", 'w', arg_integer, &weight,
172 "weight of shippment", "tons" },
173 { "catalog", 'c', arg_negative_flag, &include_catalog,
174 "include product catalog" },
175 { "help", 'h', arg_flag, &help_flag }
176 };
177
178 int num_args = sizeof(args) / sizeof(args[0]); /* number of elements in args */
179
180 const char *progname = "ship++";
181
182 int
183 main(int argc, char **argv)
184 {
185 int optind = 0;
186 if (getarg(args, num_args, argc, argv, &optind)) {
187 arg_printusage(args, num_args, progname, "stuff...");
188 exit (1);
189 }
190 if (help_flag) {
191 arg_printusage(args, num_args, progname, "stuff...");
192 exit (0);
193 }
194 if (destination == NULL) {
195 fprintf(stderr, "%s: must specify destination\n", progname);
196 exit(1);
197 }
198 if (strcmp(source, destination) == 0) {
199 fprintf(stderr, "%s: destination must be different from source\n");
200 exit(1);
201 }
202 /* include more stuff here ... */
203 exit(2);
204 }
205
206 The output help output from this program looks like this:
207
208 $ ship++ --help
209 Usage: ship++ [--source=city] [-s city] [--destination=city] [-d city]
210 [--weight=tons] [-w tons] [--no-catalog] [-c] [--help] [-h] stuff...
211 -s city, --source=city source of shippment
212 -d city, --destination=city destination of shippment
213 -w tons, --weight=tons weight of shippment
214 -c, --no-catalog include product catalog
215
216BBUUGGSS
217 It should be more flexible, so it would be possible to use other more
218 complicated option syntaxes, such as what ps(1), and tar(1), uses, or the
219 AFS model where you can skip the flag names as long as the options come
220 in the correct order.
221
222 Options with multiple arguments should be handled better.
223
224 Should be integreated with SL.
225
226 It's very confusing that the struct you pass in is called getargS.
227
228SSEEEE AALLSSOO
229 getopt(3)
230
231ROKEN September 24, 1999 ROKEN
Note: See TracBrowser for help on using the repository browser.