1 /*
2  *	option parser test program
3  *	Copyright Jan Engelhardt
4  *
5  *	This program is free software; you can redistribute it and/or
6  *	modify it under the terms of the WTF Public License version 2 or
7  *	(at your option) any later version.
8  */
9 #include <errno.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <libHX/defs.h>
14 #include <libHX/init.h>
15 #include <libHX/map.h>
16 #include <libHX/option.h>
17 
18 static int opt_v = 0, opt_mask = 0;
19 static char *opt_kstr = NULL;
20 static long opt_klong = 0;
21 static double opt_kdbl = 0;
22 static int opt_kflag = 0, opt_kint = 0;
23 static int opt_dst = 0;
24 static hxmc_t *opt_mcstr = NULL;
25 
opt_cbf(const struct HXoptcb * cbi)26 static void opt_cbf(const struct HXoptcb *cbi)
27 {
28 	printf("cbf was called... with \"%s\"/'%c'\n",
29 	       cbi->current->ln, cbi->current->sh);
30 }
31 
32 static const char *opt_eitheror[] = {"neither", "either", "or"};
33 static struct HXoption table[] = {
34 	{.ln = "dbl", .type = HXTYPE_DOUBLE, .cb = opt_cbf,
35 	 .ptr = &opt_kdbl, .help = "Callback function for doubles"},
36 	{.ln = "flag", .sh = 'F', .type = HXTYPE_NONE, .cb = opt_cbf,
37 	 .ptr = &opt_kflag, .help = "Callback function for flags"},
38 	{.ln = "long", .sh = 'L', .type = HXTYPE_LONG, .cb = opt_cbf,
39 	 .ptr = &opt_klong, .help = "Callback function for integers"},
40 	{.sh = 'B', .type = HXTYPE_BOOL, .ptr = &opt_v,
41 	 .cb = opt_cbf, .help = "Bool test", .htyp = "value"},
42 	{.sh = 'P', .type = HXTYPE_MCSTR, .ptr = &opt_mcstr,
43 	 .help = "Any string"},
44 	{.ln = "str", .sh = 'S', .type = HXTYPE_STRING, .cb = opt_cbf,
45 	 .ptr = &opt_kstr, .help = "Callback function for strings"},
46 	{.ln = "either", .type = HXTYPE_VAL, .cb = opt_cbf, .ptr = &opt_dst,
47 	 .val = 1, .help = "Mutually exclusive selection: either | or"},
48 	{.ln = "or", .type = HXTYPE_VAL, .ptr = &opt_dst, .val = 2,
49 	 .cb = opt_cbf, .help = "Mutually exclusive selection: either | or"},
50 	{.ln = "quiet", .sh = 'q', .type = HXOPT_DEC, .ptr = &opt_v,
51 	 .cb = opt_cbf, .help = "Decrease verbosity"},
52 	{.ln = "quack", .type = HXOPT_INC, .ptr = &opt_v,
53 	 .cb = opt_cbf, .help = "Increase verbosity"},
54 	{.ln = "verbose", .sh = 'v', .type = HXOPT_INC, .ptr = &opt_v,
55 	 .cb = opt_cbf, .help = "Increase verbosity"},
56 	{.sh = 'A', .type = HXTYPE_INT | HXOPT_AND, .ptr = &opt_mask,
57 	 .cb = opt_cbf, .help = "AND mask test", .htyp = "value"},
58 	{.sh = 'O', .type = HXTYPE_INT | HXOPT_OR, .ptr = &opt_mask,
59 	 .cb = opt_cbf, .help = "OR mask test", .htyp = "value"},
60 	{.sh = 'X', .type = HXTYPE_INT | HXOPT_XOR, .ptr = &opt_mask,
61 	 .cb = opt_cbf, .help = "XOR mask test", .htyp = "value"},
62 	{.sh = 'G', .type = HXTYPE_NONE, .help = "Just a flag", .cb = opt_cbf},
63 	{.sh = 'H', .type = HXTYPE_NONE, .help = "Just a flag", .cb = opt_cbf},
64 	{.sh = 'I', .type = HXTYPE_NONE, .help = "Just a flag", .cb = opt_cbf},
65 	HXOPT_AUTOHELP,
66 	{.sh = 'J', .type = HXTYPE_NONE, .help = "Just a flag", .cb = opt_cbf},
67 	HXOPT_TABLEEND,
68 };
69 
dump_argv(const char ** v)70 static void dump_argv(const char **v)
71 {
72 	while (*v != NULL)
73 		printf("[%s] ", *v++);
74 	printf("\n");
75 }
76 
t_pthru(void)77 static void t_pthru(void)
78 {
79 	const char *argv[] = {
80 		"ARGV0", "-Zomg", "-GZfoo", "bar",
81 		"--unknown-f=13.37", "--unknown-a",
82 		"foo", "bar", NULL
83 	};
84 	const char **argp = argv;
85 	int argc = ARRAY_SIZE(argv) - 1;
86 
87 	printf("PTHRU test:\n");
88 	HX_getopt(table, &argc, &argp, HXOPT_USAGEONERR | HXOPT_PTHRU);
89 	dump_argv(argp);
90 	printf("\n");
91 }
92 
t_empty_argv(void)93 static void t_empty_argv(void)
94 {
95 	const char *zero_argv[] = {NULL}, **zero_argp = zero_argv;
96 	int zero_argc = 0;
97 
98 	printf("Testing argv={NULL}\n");
99 	HX_getopt(table, &zero_argc, &zero_argp, HXOPT_USAGEONERR);
100 }
101 
main(int argc,const char ** argv)102 int main(int argc, const char **argv)
103 {
104 	if (HX_init() <= 0)
105 		abort();
106 	printf("Return value of HX_getopt: %d\n",
107 	       HX_getopt(table, &argc, &argv, HXOPT_USAGEONERR));
108 	t_empty_argv();
109 
110 	printf("Either-or is: %s\n", opt_eitheror[opt_dst]);
111 	printf("values: D=%lf I=%d L=%ld S=%s\n",
112 	       opt_kdbl, opt_kint, opt_klong, opt_kstr);
113 	printf("Verbosity level: %d\n", opt_v);
114 	printf("Mask: 0x%08X\n", opt_mask);
115 	printf("mcstr: >%s<\n", opt_mcstr);
116 
117 	t_pthru();
118 
119 	HX_exit();
120 	return EXIT_SUCCESS;
121 }
122