xref: /netbsd-src/tests/lib/librefuse/t_refuse_opt.c (revision ef23f679e4b4ab77b4afae233ccf5f85cfb01ba6)
1*ef23f679Sriastradh /*	$NetBSD: t_refuse_opt.c,v 1.10 2023/11/24 17:31:03 riastradh Exp $ */
27768b995Spho 
37768b995Spho /*-
4111da591Spho  * Copyright (c) 2016 The NetBSD Foundation, Inc.
57768b995Spho  * All rights reserved.
67768b995Spho  *
77768b995Spho  * Redistribution and use in source and binary forms, with or without
87768b995Spho  * modification, are permitted provided that the following conditions
97768b995Spho  * are met:
107768b995Spho  * 1. Redistributions of source code must retain the above copyright
117768b995Spho  *    notice, this list of conditions and the following disclaimer.
127768b995Spho  * 2. Redistributions in binary form must reproduce the above copyright
137768b995Spho  *    notice, this list of conditions and the following disclaimer in the
147768b995Spho  *    documentation and/or other materials provided with the distribution.
157768b995Spho  *
167768b995Spho  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
177768b995Spho  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
187768b995Spho  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
197768b995Spho  * PURPOSE ARE DISCLAIMED.	IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
207768b995Spho  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
217768b995Spho  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
227768b995Spho  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
237768b995Spho  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
247768b995Spho  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
257768b995Spho  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
267768b995Spho  * POSSIBILITY OF SUCH DAMAGE.
277768b995Spho  */
287768b995Spho #include <sys/cdefs.h>
29*ef23f679Sriastradh __RCSID("$NetBSD: t_refuse_opt.c,v 1.10 2023/11/24 17:31:03 riastradh Exp $");
309e327c59Smartin 
31a0a2e867Schristos #include <sys/types.h>
327768b995Spho 
337768b995Spho #include <atf-c.h>
347768b995Spho 
351f6f9b83Spho #define FUSE_USE_VERSION FUSE_MAKE_VERSION(2, 6)
367768b995Spho #include <fuse.h>
377768b995Spho 
38c54cb811Schristos #include "h_macros.h"
397768b995Spho 
40b146e1b7Spho ATF_TC(t_fuse_opt_add_arg);
ATF_TC_HEAD(t_fuse_opt_add_arg,tc)41b146e1b7Spho ATF_TC_HEAD(t_fuse_opt_add_arg, tc)
427768b995Spho {
437768b995Spho 	atf_tc_set_md_var(tc, "descr", "Check that fuse_opt_add_arg(3) works");
447768b995Spho }
457768b995Spho 
ATF_TC_BODY(t_fuse_opt_add_arg,tc)46b146e1b7Spho ATF_TC_BODY(t_fuse_opt_add_arg, tc)
477768b995Spho {
487768b995Spho 	struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
497768b995Spho 
50*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "foo"));
51*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "bar"));
527768b995Spho 
537768b995Spho 	ATF_REQUIRE_EQ(args.argc, 2);
547768b995Spho 	ATF_CHECK_STREQ(args.argv[0], "foo");
557768b995Spho 	ATF_CHECK_STREQ(args.argv[1], "bar");
567768b995Spho 	ATF_CHECK(args.allocated != 0);
577768b995Spho }
587768b995Spho 
59b146e1b7Spho ATF_TC(t_fuse_opt_insert_arg);
ATF_TC_HEAD(t_fuse_opt_insert_arg,tc)60b146e1b7Spho ATF_TC_HEAD(t_fuse_opt_insert_arg, tc)
617768b995Spho {
627768b995Spho 	atf_tc_set_md_var(tc, "descr", "Check that fuse_opt_insert_arg(3) works");
637768b995Spho }
647768b995Spho 
ATF_TC_BODY(t_fuse_opt_insert_arg,tc)65b146e1b7Spho ATF_TC_BODY(t_fuse_opt_insert_arg, tc)
667768b995Spho {
677768b995Spho 	struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
687768b995Spho 
69*ef23f679Sriastradh 	RL(fuse_opt_insert_arg(&args, 0, "foo"));
70*ef23f679Sriastradh 	RL(fuse_opt_insert_arg(&args, 0, "bar"));
717768b995Spho 
727768b995Spho 	ATF_REQUIRE_EQ(args.argc, 2);
737768b995Spho 	ATF_CHECK_STREQ(args.argv[0], "bar");
747768b995Spho 	ATF_CHECK_STREQ(args.argv[1], "foo");
757768b995Spho 	ATF_CHECK(args.allocated != 0);
767768b995Spho }
777768b995Spho 
78b146e1b7Spho ATF_TC(t_fuse_opt_add_opt);
ATF_TC_HEAD(t_fuse_opt_add_opt,tc)79b146e1b7Spho ATF_TC_HEAD(t_fuse_opt_add_opt, tc)
807768b995Spho {
817768b995Spho 	atf_tc_set_md_var(tc, "descr", "Check that fuse_opt_add_opt(3) works");
827768b995Spho }
837768b995Spho 
ATF_TC_BODY(t_fuse_opt_add_opt,tc)84b146e1b7Spho ATF_TC_BODY(t_fuse_opt_add_opt, tc)
857768b995Spho {
867768b995Spho 	char* opt = NULL;
877768b995Spho 
88*ef23f679Sriastradh 	RL(fuse_opt_add_opt(&opt, "fo\\o"));
89111da591Spho 	ATF_CHECK_STREQ(opt, "fo\\o");
907768b995Spho 
91*ef23f679Sriastradh 	RL(fuse_opt_add_opt(&opt, "ba,r"));
92111da591Spho 	ATF_CHECK_STREQ(opt, "fo\\o,ba,r");
93111da591Spho }
947768b995Spho 
95b146e1b7Spho ATF_TC(t_fuse_opt_add_opt_escaped);
ATF_TC_HEAD(t_fuse_opt_add_opt_escaped,tc)96b146e1b7Spho ATF_TC_HEAD(t_fuse_opt_add_opt_escaped, tc)
97111da591Spho {
98111da591Spho 	atf_tc_set_md_var(tc, "descr", "Check that fuse_opt_add_opt_escaped(3) works");
99111da591Spho }
100111da591Spho 
ATF_TC_BODY(t_fuse_opt_add_opt_escaped,tc)101b146e1b7Spho ATF_TC_BODY(t_fuse_opt_add_opt_escaped, tc)
102111da591Spho {
103111da591Spho 	char* opt = NULL;
104111da591Spho 
105*ef23f679Sriastradh 	RL(fuse_opt_add_opt_escaped(&opt, "fo\\o"));
106111da591Spho 	ATF_CHECK_STREQ(opt, "fo\\\\o");
107111da591Spho 
108*ef23f679Sriastradh 	RL(fuse_opt_add_opt_escaped(&opt, "ba,r"));
109111da591Spho 	ATF_CHECK_STREQ(opt, "fo\\\\o,ba\\,r");
1107768b995Spho }
1117768b995Spho 
112b146e1b7Spho ATF_TC(t_fuse_opt_match);
ATF_TC_HEAD(t_fuse_opt_match,tc)113b146e1b7Spho ATF_TC_HEAD(t_fuse_opt_match, tc)
114ed2b9846Spho {
115ed2b9846Spho 	atf_tc_set_md_var(tc, "descr", "Check that fuse_opt_match(3) works"
116ed2b9846Spho 					  " for every form of templates");
117ed2b9846Spho }
118ed2b9846Spho 
ATF_TC_BODY(t_fuse_opt_match,tc)119b146e1b7Spho ATF_TC_BODY(t_fuse_opt_match, tc)
120ed2b9846Spho {
121ed2b9846Spho 	struct fuse_opt o1[] = { FUSE_OPT_KEY("-x"    , 0), FUSE_OPT_END };
122ed2b9846Spho 	struct fuse_opt o2[] = { FUSE_OPT_KEY("foo"   , 0), FUSE_OPT_END };
123ed2b9846Spho 	struct fuse_opt o3[] = { FUSE_OPT_KEY("foo="  , 0), FUSE_OPT_END };
124ed2b9846Spho 	struct fuse_opt o4[] = { FUSE_OPT_KEY("foo=%s", 0), FUSE_OPT_END };
125ed2b9846Spho 	struct fuse_opt o5[] = { FUSE_OPT_KEY("-x "   , 0), FUSE_OPT_END };
126ed2b9846Spho 	struct fuse_opt o6[] = { FUSE_OPT_KEY("-x %s" , 0), FUSE_OPT_END };
127ed2b9846Spho 
128ed2b9846Spho 	ATF_CHECK(fuse_opt_match(o1, "-x") == 1);
129ed2b9846Spho 	ATF_CHECK(fuse_opt_match(o1,  "x") == 0);
130ed2b9846Spho 
131ed2b9846Spho 	ATF_CHECK(fuse_opt_match(o2,  "foo") == 1);
132ed2b9846Spho 	ATF_CHECK(fuse_opt_match(o2, "-foo") == 0);
133ed2b9846Spho 
134ed2b9846Spho 	ATF_CHECK(fuse_opt_match(o3, "foo=bar") == 1);
135ed2b9846Spho 	ATF_CHECK(fuse_opt_match(o3, "foo"    ) == 0);
136ed2b9846Spho 
137ed2b9846Spho 	ATF_CHECK(fuse_opt_match(o4, "foo=bar") == 1);
138ed2b9846Spho 	ATF_CHECK(fuse_opt_match(o4, "foo"    ) == 0);
139ed2b9846Spho 
140ed2b9846Spho 	ATF_CHECK(fuse_opt_match(o5, "-xbar" ) == 1);
141ed2b9846Spho 	ATF_CHECK(fuse_opt_match(o5, "-x"    ) == 1);
142ed2b9846Spho 	ATF_CHECK(fuse_opt_match(o5, "-x=bar") == 1);
143ed2b9846Spho 	ATF_CHECK(fuse_opt_match(o5, "bar"   ) == 0);
144ed2b9846Spho 
145ed2b9846Spho 	ATF_CHECK(fuse_opt_match(o6, "-xbar" ) == 1);
146ed2b9846Spho 	ATF_CHECK(fuse_opt_match(o6, "-x"    ) == 1);
147ed2b9846Spho 	ATF_CHECK(fuse_opt_match(o6, "-x=bar") == 1);
148ed2b9846Spho 	ATF_CHECK(fuse_opt_match(o6, "bar"   ) == 0);
149ed2b9846Spho }
150ed2b9846Spho 
151fd862595Spho struct foofs_config {
152fd862595Spho 	int number;
153fd862595Spho 	char *string;
154fd862595Spho 	char* nonopt;
155fd862595Spho };
156fd862595Spho 
157fd862595Spho #define FOOFS_OPT(t, p, v) { t, offsetof(struct foofs_config, p), v }
158fd862595Spho 
159fd862595Spho static struct fuse_opt foofs_opts[] = {
160fd862595Spho 	FOOFS_OPT("number=%i"     , number, 0),
161fd862595Spho 	FOOFS_OPT("-n %i"         , number, 0),
162fd862595Spho 	FOOFS_OPT("string=%s"     , string, 0),
163fd862595Spho 	FOOFS_OPT("number1"       , number, 1),
164fd862595Spho 	FOOFS_OPT("number2"       , number, 2),
165fd862595Spho 	FOOFS_OPT("--number=three", number, 3),
166fd862595Spho 	FOOFS_OPT("--number=four" , number, 4),
167fd862595Spho 	FUSE_OPT_END
168fd862595Spho };
169fd862595Spho 
foo_opt_proc(void * data,const char * arg,int key,struct fuse_args * outargs)170fd862595Spho static int foo_opt_proc(void *data, const char *arg, int key, struct fuse_args *outargs) {
171fd862595Spho 	struct foofs_config *config = data;
172fd862595Spho 
173fd862595Spho 	if (key == FUSE_OPT_KEY_NONOPT && config->nonopt == NULL) {
174fd862595Spho 		config->nonopt = strdup(arg);
175fd862595Spho 		return 0;
176fd862595Spho 	}
177fd862595Spho 	else {
178fd862595Spho 		return 1;
179fd862595Spho 	}
180fd862595Spho }
181fd862595Spho 
182fd862595Spho ATF_TC(t_fuse_opt_parse_null_args);
ATF_TC_HEAD(t_fuse_opt_parse_null_args,tc)183fd862595Spho ATF_TC_HEAD(t_fuse_opt_parse_null_args, tc)
184fd862595Spho {
185fd862595Spho 	atf_tc_set_md_var(tc, "descr", "NULL args means an empty arguments vector");
186fd862595Spho }
187fd862595Spho 
ATF_TC_BODY(t_fuse_opt_parse_null_args,tc)188fd862595Spho ATF_TC_BODY(t_fuse_opt_parse_null_args, tc)
189fd862595Spho {
190fd862595Spho 	struct foofs_config config;
191fd862595Spho 
192fd862595Spho 	memset(&config, 0, sizeof(config));
193fd862595Spho 	ATF_CHECK(fuse_opt_parse(NULL, &config, NULL, NULL) == 0);
194fd862595Spho 	ATF_CHECK_EQ(config.number, 0);
195fd862595Spho 	ATF_CHECK_EQ(config.string, NULL);
196fd862595Spho 	ATF_CHECK_EQ(config.nonopt, NULL);
197fd862595Spho }
198fd862595Spho 
199fd862595Spho ATF_TC(t_fuse_opt_parse_null_opts);
ATF_TC_HEAD(t_fuse_opt_parse_null_opts,tc)200fd862595Spho ATF_TC_HEAD(t_fuse_opt_parse_null_opts, tc)
201fd862595Spho {
202fd862595Spho 	atf_tc_set_md_var(tc, "descr", "NULL opts means an opts array which only has FUSE_OPT_END");
203fd862595Spho }
204fd862595Spho 
ATF_TC_BODY(t_fuse_opt_parse_null_opts,tc)205fd862595Spho ATF_TC_BODY(t_fuse_opt_parse_null_opts, tc)
206fd862595Spho {
207fd862595Spho 	struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
208fd862595Spho 	struct foofs_config config;
209fd862595Spho 
210*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "foofs"));
211*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "-o"));
212*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "number=1,string=foo"));
213*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "bar"));
214fd862595Spho 
215fd862595Spho 	memset(&config, 0, sizeof(config));
216fd862595Spho 	ATF_CHECK(fuse_opt_parse(&args, &config, NULL, NULL) == 0);
217fd862595Spho 	ATF_CHECK_EQ(config.number, 0);
218fd862595Spho 	ATF_CHECK_EQ(config.string, NULL);
219fd862595Spho 	ATF_CHECK_EQ(config.nonopt, NULL);
220fd862595Spho 	ATF_CHECK_EQ(args.argc, 4);
221fd862595Spho 	ATF_CHECK_STREQ(args.argv[0], "foofs");
222fd862595Spho 	ATF_CHECK_STREQ(args.argv[1], "-o");
223fd862595Spho 	ATF_CHECK_STREQ(args.argv[2], "number=1,string=foo");
224fd862595Spho 	ATF_CHECK_STREQ(args.argv[3], "bar");
225fd862595Spho }
226fd862595Spho 
227fd862595Spho ATF_TC(t_fuse_opt_parse_null_proc);
ATF_TC_HEAD(t_fuse_opt_parse_null_proc,tc)228fd862595Spho ATF_TC_HEAD(t_fuse_opt_parse_null_proc, tc)
229fd862595Spho {
230fd862595Spho 	atf_tc_set_md_var(tc, "descr", "NULL proc means a processor function always returning 1,"
231fd862595Spho 					  " i.e. keep the argument");
232fd862595Spho }
233fd862595Spho 
ATF_TC_BODY(t_fuse_opt_parse_null_proc,tc)234fd862595Spho ATF_TC_BODY(t_fuse_opt_parse_null_proc, tc)
235fd862595Spho {
236fd862595Spho 	struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
237fd862595Spho 	struct foofs_config config;
238fd862595Spho 
239*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "foofs"));
240*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "-o"));
241*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "number=1,string=foo"));
242*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "bar"));
243fd862595Spho 
244fd862595Spho 	memset(&config, 0, sizeof(config));
245fd862595Spho 	ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, NULL) == 0);
246fd862595Spho 	ATF_CHECK_EQ(config.number, 1);
247fd862595Spho 	ATF_CHECK_STREQ(config.string, "foo");
248fd862595Spho 	ATF_CHECK_EQ(config.nonopt, NULL);
249fd862595Spho 	ATF_CHECK_EQ(args.argc, 2);
250fd862595Spho 	ATF_CHECK_STREQ(args.argv[0], "foofs");
251fd862595Spho 	ATF_CHECK_STREQ(args.argv[1], "bar");
252fd862595Spho }
253fd862595Spho 
254fd862595Spho ATF_TC(t_fuse_opt_parse);
ATF_TC_HEAD(t_fuse_opt_parse,tc)255fd862595Spho ATF_TC_HEAD(t_fuse_opt_parse, tc)
256fd862595Spho {
257fd862595Spho 	atf_tc_set_md_var(tc, "descr", "Check that fuse_opt_parse(3) fully works");
258fd862595Spho }
259fd862595Spho 
ATF_TC_BODY(t_fuse_opt_parse,tc)260fd862595Spho ATF_TC_BODY(t_fuse_opt_parse, tc)
261fd862595Spho {
262fd862595Spho 	struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
263fd862595Spho 	struct foofs_config config;
264fd862595Spho 
265fd862595Spho     /* Standard form */
266fd862595Spho 	fuse_opt_free_args(&args);
267*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "foofs"));
268*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "-o"));
269*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "number=1,string=foo"));
270*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "bar"));
271fd862595Spho 
272fd862595Spho 	memset(&config, 0, sizeof(config));
273fd862595Spho 	ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0);
274fd862595Spho 	ATF_CHECK_EQ(config.number, 1);
275fd862595Spho 	ATF_CHECK_STREQ(config.string, "foo");
276fd862595Spho 	ATF_CHECK_STREQ(config.nonopt, "bar");
277fd862595Spho 	ATF_CHECK_EQ(args.argc, 1);
278fd862595Spho 	ATF_CHECK_STREQ(args.argv[0], "foofs");
279fd862595Spho 
280fd862595Spho     /* Concatenated -o */
281fd862595Spho 	fuse_opt_free_args(&args);
282*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "foofs"));
283*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "-onumber=1,unknown,string=foo"));
284*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "bar"));
285fd862595Spho 
286fd862595Spho 	memset(&config, 0, sizeof(config));
287fd862595Spho 	ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0);
288fd862595Spho 	ATF_CHECK_EQ(config.number, 1);
289fd862595Spho 	ATF_CHECK_STREQ(config.string, "foo");
290fd862595Spho 	ATF_CHECK_STREQ(config.nonopt, "bar");
291fd862595Spho 	ATF_CHECK_EQ(args.argc, 3);
292fd862595Spho 	ATF_CHECK_STREQ(args.argv[0], "foofs");
293fd862595Spho 	ATF_CHECK_STREQ(args.argv[1], "-o");
294fd862595Spho 	ATF_CHECK_STREQ(args.argv[2], "unknown");
295fd862595Spho 
296fd862595Spho 	/* Sparse -o */
297fd862595Spho 	fuse_opt_free_args(&args);
298*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "foofs"));
299*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "bar"));
300*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "baz"));
301*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "-o"));
302*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "number=1"));
303*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "-o"));
304*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "unknown"));
305*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "-o"));
306*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "string=foo"));
307fd862595Spho 
308fd862595Spho 	memset(&config, 0, sizeof(config));
309fd862595Spho 	ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0);
310fd862595Spho 	ATF_CHECK_EQ(config.number, 1);
311fd862595Spho 	ATF_CHECK_STREQ(config.string, "foo");
312fd862595Spho 	ATF_CHECK_STREQ(config.nonopt, "bar");
313fd862595Spho 	ATF_CHECK_EQ(args.argc, 4);
314fd862595Spho 	ATF_CHECK_STREQ(args.argv[0], "foofs");
315fd862595Spho 	ATF_CHECK_STREQ(args.argv[1], "-o");
316fd862595Spho 	ATF_CHECK_STREQ(args.argv[2], "unknown");
317fd862595Spho 	ATF_CHECK_STREQ(args.argv[3], "baz");
318fd862595Spho 
319fd862595Spho 	/* Separate -n %i */
320fd862595Spho 	fuse_opt_free_args(&args);
321*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "foofs"));
322*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "-n"));
323*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "3"));
324fd862595Spho 
325fd862595Spho 	memset(&config, 0, sizeof(config));
326fd862595Spho 	ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0);
327fd862595Spho 	ATF_CHECK_EQ(config.number, 3);
328fd862595Spho 	ATF_CHECK_EQ(config.string, NULL);
329fd862595Spho 	ATF_CHECK_EQ(config.nonopt, NULL);
330fd862595Spho 	ATF_CHECK_EQ(args.argc, 1);
331fd862595Spho 	ATF_CHECK_STREQ(args.argv[0], "foofs");
332fd862595Spho 
333fd862595Spho 	/* Concatenated -n %i */
334fd862595Spho 	fuse_opt_free_args(&args);
335*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "foofs"));
336*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "-n3"));
337fd862595Spho 
338fd862595Spho 	memset(&config, 0, sizeof(config));
339fd862595Spho 	ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0);
340fd862595Spho 	ATF_CHECK_EQ(config.number, 3);
341fd862595Spho 	ATF_CHECK_EQ(config.string, NULL);
342fd862595Spho 	ATF_CHECK_EQ(config.nonopt, NULL);
343fd862595Spho 	ATF_CHECK_EQ(args.argc, 1);
344fd862595Spho 	ATF_CHECK_STREQ(args.argv[0], "foofs");
345fd862595Spho 
346fd862595Spho 	/* -o constant */
347fd862595Spho 	fuse_opt_free_args(&args);
348*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "foofs"));
349*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "-o"));
350*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "number2"));
351fd862595Spho 
352fd862595Spho 	memset(&config, 0, sizeof(config));
353fd862595Spho 	ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0);
354fd862595Spho 	ATF_CHECK_EQ(config.number, 2);
355fd862595Spho 	ATF_CHECK_EQ(config.string, NULL);
356fd862595Spho 	ATF_CHECK_EQ(config.nonopt, NULL);
357fd862595Spho 	ATF_CHECK_EQ(args.argc, 1);
358fd862595Spho 	ATF_CHECK_STREQ(args.argv[0], "foofs");
359fd862595Spho 
360fd862595Spho 	/* -x constant */
361fd862595Spho 	fuse_opt_free_args(&args);
362*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "foofs"));
363*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "--number=four"));
364fd862595Spho 
365fd862595Spho 	memset(&config, 0, sizeof(config));
366fd862595Spho 	ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0);
367fd862595Spho 	ATF_CHECK_EQ(config.number, 4);
368fd862595Spho 	ATF_CHECK_EQ(config.string, NULL);
369fd862595Spho 	ATF_CHECK_EQ(config.nonopt, NULL);
370fd862595Spho 	ATF_CHECK_EQ(args.argc, 1);
371fd862595Spho 	ATF_CHECK_STREQ(args.argv[0], "foofs");
372fd862595Spho 
373fd862595Spho 	/* end-of-options "--" marker */
374fd862595Spho 	fuse_opt_free_args(&args);
375*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "foofs"));
376*ef23f679Sriastradh     RL(fuse_opt_add_arg(&args, "--"));
377*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "-onumber=1"));
378*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "-ostring=foo"));
379fd862595Spho 
380fd862595Spho 	memset(&config, 0, sizeof(config));
381fd862595Spho 	ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0);
382fd862595Spho 	ATF_CHECK_EQ(config.number, 0);
383fd862595Spho 	ATF_CHECK_EQ(config.string, NULL);
384fd862595Spho 	ATF_CHECK_STREQ(config.nonopt, "-onumber=1");
385fd862595Spho 	ATF_CHECK_EQ(args.argc, 3);
386fd862595Spho 	ATF_CHECK_STREQ(args.argv[0], "foofs");
387fd862595Spho 	ATF_CHECK_STREQ(args.argv[1], "--");
388fd862595Spho 	ATF_CHECK_STREQ(args.argv[2], "-ostring=foo");
389fd862595Spho 
390fd862595Spho 	/* The "--" marker at the last of outargs should be removed */
391fd862595Spho 	fuse_opt_free_args(&args);
392*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "foofs"));
393*ef23f679Sriastradh     RL(fuse_opt_add_arg(&args, "--"));
394*ef23f679Sriastradh 	RL(fuse_opt_add_arg(&args, "-onumber=1"));
395fd862595Spho 
396fd862595Spho 	memset(&config, 0, sizeof(config));
397fd862595Spho 	ATF_CHECK(fuse_opt_parse(&args, &config, foofs_opts, foo_opt_proc) == 0);
398fd862595Spho 	ATF_CHECK_EQ(config.number, 0);
399fd862595Spho 	ATF_CHECK_EQ(config.string, NULL);
400fd862595Spho 	ATF_CHECK_STREQ(config.nonopt, "-onumber=1");
401fd862595Spho 	ATF_CHECK_EQ(args.argc, 1);
402fd862595Spho 	ATF_CHECK_STREQ(args.argv[0], "foofs");
403fd862595Spho }
404fd862595Spho 
ATF_TP_ADD_TCS(tp)4057768b995Spho ATF_TP_ADD_TCS(tp)
4067768b995Spho {
407b146e1b7Spho 	ATF_TP_ADD_TC(tp, t_fuse_opt_add_arg);
408b146e1b7Spho 	ATF_TP_ADD_TC(tp, t_fuse_opt_insert_arg);
409b146e1b7Spho 	ATF_TP_ADD_TC(tp, t_fuse_opt_add_opt);
410b146e1b7Spho 	ATF_TP_ADD_TC(tp, t_fuse_opt_add_opt_escaped);
411b146e1b7Spho 	ATF_TP_ADD_TC(tp, t_fuse_opt_match);
412fd862595Spho 	ATF_TP_ADD_TC(tp, t_fuse_opt_parse_null_args);
413fd862595Spho 	ATF_TP_ADD_TC(tp, t_fuse_opt_parse_null_opts);
414fd862595Spho 	ATF_TP_ADD_TC(tp, t_fuse_opt_parse_null_proc);
415fd862595Spho 	ATF_TP_ADD_TC(tp, t_fuse_opt_parse);
4167768b995Spho 
4177768b995Spho 	return atf_no_error();
4187768b995Spho }
419