1 /*****************************************************************************
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15 *
16 *****************************************************************************/
17 
18 #include "common.h"
19 #include "utils_base.h"
20 #include "extra_opts.h"
21 
22 #include "tap.h"
23 
24 /* This my_free would be the most efficient way of freeing an extra-opts array,
25  * provided as an example */
26 #if 0
27 void my_free(int *argc, char **newargv, char **argv) {
28 	int i;
29 	/* Return if both arrays are the same */
30 	if (newargv == argv) return;
31 
32 	for (i=1; i<*argc; i++) {
33 		/* Free array items until we reach the start of the original argv */
34 		if (newargv[i] == argv[1]) break;
35 		free(newargv[i]);
36 	}
37 	/* Free the array itself */
38 	free(newargv);
39 }
40 #else
my_free(int * argc,char ** newargv,char ** argv)41 void my_free(int *argc, char **newargv, char **argv) {
42 	/* Free stuff (and print while we're at it) */
43 	int i, freeflag=1;
44 	printf ("    Arg(%i): ", *argc+1);
45 	printf ("'%s' ", newargv[0]);
46 	for (i=1; i<*argc; i++) {
47 		printf ("'%s' ", newargv[i]);
48 		/* Stop freeing when we get to the start of the original array */
49 		if (freeflag) {
50 			if (newargv[i] == argv[1])
51 				freeflag=0;
52 			else
53 				free(newargv[i]);
54 		}
55 	}
56 	printf ("\n");
57 	/* Free only if it's a different array */
58 	if (newargv != argv) free(newargv);
59 	*argc=0;
60 }
61 #endif
62 
array_diff(int i1,char ** a1,int i2,char ** a2)63 int array_diff(int i1, char **a1, int i2, char **a2) {
64 	int i;
65 
66 	if (i1 != i2) {
67 		printf("    Argument count doesn't match!\n");
68 		return 0;
69 	}
70 	for (i=0; i<=i1; i++) {
71 		if (a1[i]==NULL && a2[i]==NULL) continue;
72 		if (a1[i]==NULL || a2[i]==NULL) {
73 			printf("    Argument # %i null in one array!\n", i);
74 			return 0;
75 		}
76 		if (strcmp(a1[i], a2[i])) {
77 			printf("    Argument # %i doesn't match!\n", i);
78 			return 0;
79 		}
80 	}
81 	return 1;
82 }
83 
84 int
main(int argc,char ** argv)85 main (int argc, char **argv)
86 {
87 	char **argv_new=NULL;
88 	int i, argc_test;
89 
90 	plan_tests(5);
91 
92 	{
93 		char *argv_test[] = {"prog_name", (char *) NULL};
94 		argc_test=1;
95 		char *argv_known[] = {"prog_name", (char *) NULL};
96 		argv_new=np_extra_opts(&argc_test, argv_test, "check_disk");
97 		ok(array_diff(argc_test, argv_new, 1, argv_known), "No opts, returns correct argv/argc");
98 		my_free(&argc_test, argv_new, argv_test);
99 	}
100 
101 	{
102 		char *argv_test[] = {"prog_name", "arg1", "--arg2=val1", "--arg3", "val2", (char *) NULL};
103 		argc_test=5;
104 		char *argv_known[] = {"prog_name", "arg1", "--arg2=val1", "--arg3", "val2", (char *) NULL};
105 		argv_new=np_extra_opts(&argc_test, argv_test, "check_disk");
106 		ok(array_diff(argc_test, argv_new, 5, argv_known), "No extra opts, verbatim copy of argv");
107 		my_free(&argc_test, argv_new, argv_test);
108 	}
109 
110 	{
111 		char *argv_test[] = {"prog_name", "--extra-opts=@./config-opts.ini", (char *) NULL};
112 		argc_test=2;
113 		char *argv_known[] = {"prog_name", "--foo=Bar", "--this=Your Mother!", "--blank", (char *) NULL};
114 		argv_new=np_extra_opts(&argc_test, argv_test, "check_disk");
115 		ok(array_diff(argc_test, argv_new, 4, argv_known), "Only extra opts using default section");
116 		my_free(&argc_test, argv_new, argv_test);
117 	}
118 
119 	{
120 		char *argv_test[] = {"prog_name", "--extra-opts=sect1@./config-opts.ini", "--extra-opts", "sect2@./config-opts.ini", (char *) NULL};
121 		argc_test=4;
122 		char *argv_known[] = {"prog_name", "--one=two", "--something else=oops", "--this=that", (char *) NULL};
123 		argv_new=np_extra_opts(&argc_test, argv_test, "check_disk");
124 		ok(array_diff(argc_test, argv_new, 4, argv_known), "Only extra opts specified twice");
125 		my_free(&argc_test, argv_new, argv_test);
126 	}
127 
128 	{
129 		char *argv_test[] = {"prog_name", "--arg1=val1", "--extra-opts=@./config-opts.ini", "--extra-opts", "sect1@./config-opts.ini", "--arg2", (char *) NULL};
130 		argc_test=6;
131 		char *argv_known[] = {"prog_name", "--foo=Bar", "--this=Your Mother!", "--blank", "--one=two", "--arg1=val1", "--arg2", (char *) NULL};
132 		argv_new=np_extra_opts(&argc_test, argv_test, "check_disk");
133 		ok(array_diff(argc_test, argv_new, 7, argv_known), "twice extra opts using two sections");
134 		my_free(&argc_test, argv_new, argv_test);
135 	}
136 
137 	return exit_status();
138 }
139 
140