1 /*
2   FUSE: Filesystem in Userspace
3   Copyright (C) 2001-2007  Miklos Szeredi <miklos@szeredi.hu>
4 
5   This program can be distributed under the terms of the GNU LGPLv2.
6   See the file COPYING.LIB.
7 */
8 
9 module c.fuse.fuse_opt;
10 
11 import core.stdc.config;
12 
13 extern (C):
14 
15 /**
16  * Option description
17  *
18  * This structure describes a single option, and action associated
19  * with it, in case it matches.
20  *
21  * More than one such match may occur, in which case the action for
22  * each match is executed.
23  *
24  * There are three possible actions in case of a match:
25  *
26  * i) An integer (int or unsigned) variable determined by 'offset' is
27  *    set to 'value'
28  *
29  * ii) The processing function is called, with 'value' as the key
30  *
31  * iii) An integer (any) or string (char *) variable determined by
32  *    'offset' is set to the value of an option parameter
33  *
34  * 'offset' should normally be either set to
35  *
36  *  - 'offsetof(struct foo, member)'  actions i) and iii)
37  *
38  *  - -1			      action ii)
39  *
40  * The 'offsetof()' macro is defined in the <stddef.h> header.
41  *
42  * The template determines which options match, and also have an
43  * effect on the action.  Normally the action is either i) or ii), but
44  * if a format is present in the template, then action iii) is
45  * performed.
46  *
47  * The types of templates are:
48  *
49  * 1) "-x", "-foo", "--foo", "--foo-bar", etc.	These match only
50  *   themselves.  Invalid values are "--" and anything beginning
51  *   with "-o"
52  *
53  * 2) "foo", "foo-bar", etc.  These match "-ofoo", "-ofoo-bar" or
54  *    the relevant option in a comma separated option list
55  *
56  * 3) "bar=", "--foo=", etc.  These are variations of 1) and 2)
57  *    which have a parameter
58  *
59  * 4) "bar=%s", "--foo=%lu", etc.  Same matching as above but perform
60  *    action iii).
61  *
62  * 5) "-x ", etc.  Matches either "-xparam" or "-x param" as
63  *    two separate arguments
64  *
65  * 6) "-x %s", etc.  Combination of 4) and 5)
66  *
67  * If the format is "%s", memory is allocated for the string unlike
68  * with scanf().
69  */
70 struct fuse_opt
71 {
72     /** Matching template and optional parameter formatting */
73     const char *templ;
74 
75     /**
76      * Offset of variable within 'data' parameter of fuse_opt_parse()
77      * or -1
78      */
79     c_ulong offset;
80 
81     /**
82      * Value to set the variable to, or to be passed as 'key' to the
83      * processing function.	 Ignored if template has a format
84      */
85     int value;
86 }
87 
88 /**
89  * Key option.	In case of a match, the processing function will be
90  * called with the specified key.
91  */
92 fuse_opt FUSE_OPT_KEY()(const char* templ, int key) { return fuse_opt(templ, -1U, key); }
93 
94 /**
95  * Last option.	 An array of 'struct fuse_opt' must end with a NULL
96  * template value
97  */
98 enum FUSE_OPT_END = fuse_opt(null, 0, 0);
99 
100 /**
101  * Argument list
102  */
103 struct fuse_args
104 {
105     /** Argument count */
106     int argc;
107 
108     /** Argument vector.  NULL terminated */
109     char **argv;
110 
111     /** Is 'argv' allocated? */
112     int allocated;
113 }
114 
115 /**
116  * Initializer for 'struct fuse_args'
117  */
118 fuse_args FUSE_ARGS_INIT()(int argc, char** argv) { return fuse_args(argc, argv, 0); }
119 
120 /**
121  * Key value passed to the processing function if an option did not
122  * match any template
123  */
124 enum FUSE_OPT_KEY_OPT     = -1;
125 
126 /**
127  * Key value passed to the processing function for all non-options
128  *
129  * Non-options are the arguments beginning with a character other than
130  * '-' or all arguments after the special '--' option
131  */
132 enum FUSE_OPT_KEY_NONOPT  = -2;
133 
134 /**
135  * Special key value for options to keep
136  *
137  * Argument is not passed to processing function, but behave as if the
138  * processing function returned 1
139  */
140 enum FUSE_OPT_KEY_KEEP = -3;
141 
142 /**
143  * Special key value for options to discard
144  *
145  * Argument is not passed to processing function, but behave as if the
146  * processing function returned zero
147  */
148 enum FUSE_OPT_KEY_DISCARD = -4;
149 
150 /**
151  * Processing function
152  *
153  * This function is called if
154  *    - option did not match any 'struct fuse_opt'
155  *    - argument is a non-option
156  *    - option did match and offset was set to -1
157  *
158  * The 'arg' parameter will always contain the whole argument or
159  * option including the parameter if exists.  A two-argument option
160  * ("-x foo") is always converted to single argument option of the
161  * form "-xfoo" before this function is called.
162  *
163  * Options of the form '-ofoo' are passed to this function without the
164  * '-o' prefix.
165  *
166  * The return value of this function determines whether this argument
167  * is to be inserted into the output argument vector, or discarded.
168  *
169  * @param data is the user data passed to the fuse_opt_parse() function
170  * @param arg is the whole argument or option
171  * @param key determines why the processing function was called
172  * @param outargs the current output argument list
173  * @return -1 on error, 0 if arg is to be discarded, 1 if arg should be kept
174  */
175 alias fuse_opt_proc_t = int function(void* data, const char* arg, int key,
176                    fuse_args* outargs);
177 
178 /**
179  * Option parsing function
180  *
181  * If 'args' was returned from a previous call to fuse_opt_parse() or
182  * it was constructed from
183  *
184  * A NULL 'args' is equivalent to an empty argument vector
185  *
186  * A NULL 'opts' is equivalent to an 'opts' array containing a single
187  * end marker
188  *
189  * A NULL 'proc' is equivalent to a processing function always
190  * returning '1'
191  *
192  * @param args is the input and output argument list
193  * @param data is the user data
194  * @param opts is the option description array
195  * @param proc is the processing function
196  * @return -1 on error, 0 on success
197  */
198 int fuse_opt_parse(fuse_args* args, void* data,
199            const fuse_opt* opts, fuse_opt_proc_t proc);
200 
201 /**
202  * Add an option to a comma separated option list
203  *
204  * @param opts is a pointer to an option list, may point to a NULL value
205  * @param opt is the option to add
206  * @return -1 on allocation error, 0 on success
207  */
208 int fuse_opt_add_opt(char** opts, const char* opt);
209 
210 /**
211  * Add an option, escaping commas, to a comma separated option list
212  *
213  * @param opts is a pointer to an option list, may point to a NULL value
214  * @param opt is the option to add
215  * @return -1 on allocation error, 0 on success
216  */
217 int fuse_opt_add_opt_escaped(char** opts, const char* opt);
218 
219 /**
220  * Add an argument to a NULL terminated argument vector
221  *
222  * @param args is the structure containing the current argument list
223  * @param arg is the new argument to add
224  * @return -1 on allocation error, 0 on success
225  */
226 int fuse_opt_add_arg(fuse_args* args, const char* arg);
227 
228 /**
229  * Add an argument at the specified position in a NULL terminated
230  * argument vector
231  *
232  * Adds the argument to the N-th position.  This is useful for adding
233  * options at the beginning of the array which must not come after the
234  * special '--' option.
235  *
236  * @param args is the structure containing the current argument list
237  * @param pos is the position at which to add the argument
238  * @param arg is the new argument to add
239  * @return -1 on allocation error, 0 on success
240  */
241 int fuse_opt_insert_arg(fuse_args* args, int pos, char* arg);
242 
243 /**
244  * Free the contents of argument list
245  *
246  * The structure itself is not freed
247  *
248  * @param args is the structure containing the argument list
249  */
250 void fuse_opt_free_args(fuse_args* args);
251 
252 
253 /**
254  * Check if an option matches
255  *
256  * @param opts is the option description array
257  * @param opt is the option to match
258  * @return 1 if a match is found, 0 if not
259  */
260 int fuse_opt_match(const fuse_opt* opts, const char *opt);