xref: /haiku/src/tests/system/libroot/os/DriverSettingsTest.cpp (revision 1d9d47fc72028bb71b5f232a877231e59cfe2438)
1 /*
2  * Copyright 2003-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include <driver_settings.h>
8 #include <Directory.h>
9 #include <Entry.h>
10 #include <Path.h>
11 
12 #include <stdio.h>
13 #include <string.h>
14 
15 
16 bool gVerbose = false;
17 
18 // Just add your test settings here, they will be picked
19 // up automatically
20 
21 const char *kSettings[] = {
22 	"keyA b c d {\n"
23 	"	keyB {\n"
24 	"		keyC d e f {\n"
25 	"			keyD e\n"
26 	"			keyE f\n"
27 	"		}\n"
28 	"	}}\n",
29 
30 	"keyA {\ndisabled\n}\n",
31 
32 	"keyA = b { keyB=d =e { keyC \"f g\"; keyD h } }"
33 };
34 
35 
36 // needed by the driver_settings implementation, but not part of
37 // the original R5 libroot.so
38 
39 size_t
40 strnlen(char const *string, size_t count)
41 {
42 	const char *pos = string;
43 
44 	while (count-- && pos[0] != '\0')
45 		pos++;
46 
47 	return pos - string;
48 }
49 
50 
51 /** Concatenates the source string to the destination, writes
52  *	as much as "maxLength" bytes to the dest string.
53  *	Always null terminates the string as long as maxLength is
54  *	larger than the dest string.
55  *	Returns the length of the string that it tried to create
56  *	to be able to easily detect string truncation.
57  */
58 
59 size_t
60 strlcat(char *dest, const char *source, size_t maxLength)
61 {
62 	size_t destLength = strnlen(dest, maxLength);
63 
64 	// This returns the wrong size, but it's all we can do
65 	if (maxLength == destLength)
66 		return destLength + strlen(source);
67 
68 	dest += destLength;
69 	maxLength -= destLength;
70 
71 	size_t i = 0;
72 	for (; i < maxLength - 1 && source[i]; i++) {
73 		dest[i] = source[i];
74 	}
75 
76 	dest[i] = '\0';
77 
78 	return destLength + i + strlen(source + i);
79 }
80 
81 
82 //	#pragma mark -
83 
84 
85 void
86 put_level_space(int32 level)
87 {
88 	while (level-- > 0)
89 		putchar('\t');
90 }
91 
92 
93 void
94 dump_parameter(const driver_parameter &parameter, int32 level)
95 {
96 	put_level_space(level);
97 	printf("\"%s\" =", parameter.name);
98 
99 	for (int32 i = 0; i < parameter.value_count; i++)
100 		printf(" \"%s\"", parameter.values[i]);
101 	putchar('\n');
102 
103 	for (int32 i = 0; i < parameter.parameter_count; i++)
104 		dump_parameter(parameter.parameters[i], level + 1);
105 }
106 
107 
108 void
109 dump_settings(const driver_settings &settings)
110 {
111 	for (int32 i = 0; i < settings.parameter_count; i++)
112 		dump_parameter(settings.parameters[i], 0);
113 }
114 
115 
116 void
117 print_settings(void *handle)
118 {
119 	char buffer[2048];
120 	size_t bufferSize = sizeof(buffer);
121 
122 	if (get_driver_settings_string(handle, buffer, &bufferSize, false) < B_OK) {
123 		fprintf(stderr, "Could not get settings string (standard)\n");
124 		exit(-1);
125 	}
126 	puts("  ----- standard");
127 	puts(buffer);
128 	puts("  ----- standard reparsed");
129 
130 	void *reparsedHandle = parse_driver_settings_string(buffer);
131 	if (reparsedHandle == NULL) {
132 		fprintf(stderr, "Could not reparse settings\n");
133 		exit(-1);
134 	}
135 	const driver_settings *settings = get_driver_settings(reparsedHandle);
136 	dump_settings(*settings);
137 
138 	delete_driver_settings(reparsedHandle);
139 
140 	bufferSize = sizeof(buffer);
141 	if (get_driver_settings_string(handle, buffer, &bufferSize, true) < B_OK) {
142 		fprintf(stderr, "Could not get settings string (flat)\n");
143 		exit(-1);
144 	}
145 	puts("  ----- flat");
146 	puts(buffer);
147 	puts("  ----- flat reparsed");
148 
149 	reparsedHandle = parse_driver_settings_string(buffer);
150 	if (reparsedHandle == NULL) {
151 		fprintf(stderr, "Could not reparse settings\n");
152 		exit(-1);
153 	}
154 	settings = get_driver_settings(reparsedHandle);
155 	dump_settings(*settings);
156 
157 	delete_driver_settings(reparsedHandle);
158 }
159 
160 
161 void
162 check_settings_string(uint32 num)
163 {
164 	const char *string = kSettings[num];
165 
166 	printf("\n--------- settings %ld -----------\n", num);
167 
168 	void *handle = parse_driver_settings_string(string);
169 	if (handle == NULL) {
170 		fprintf(stderr, "Could not parse settings 1\n");
171 		exit(-1);
172 	}
173 	const driver_settings *settings = get_driver_settings(handle);
174 
175 	if (gVerbose) {
176 		puts("  ----- original");
177 		puts(string);
178 		puts("  ----- parsed");
179 		dump_settings(*settings);
180 	}
181 
182 	print_settings(handle);
183 	delete_driver_settings(handle);
184 }
185 
186 
187 void
188 load_settings(const char *name)
189 {
190 	void *handle = load_driver_settings(name);
191 	if (handle == NULL) {
192 		fprintf(stderr, "Could not load settings \"%s\"\n", name);
193 		return;
194 	}
195 
196 	const driver_settings *settings = get_driver_settings(handle);
197 	if (settings == NULL) {
198 		fprintf(stderr, "Could not get settings from loaded file \"%s\"\n", name);
199 		goto end;
200 	}
201 
202 	printf("settings \"%s\" loaded successfully\n", name);
203 	if (gVerbose)
204 		dump_settings(*settings);
205 
206 end:
207 	if (unload_driver_settings(handle) < B_OK)
208 		fprintf(stderr, "Could not unload driver settings \"%s\"\n", name);
209 }
210 
211 
212 int
213 main(int argc, char **argv)
214 {
215 	BDirectory directory("/boot/home/config/settings/kernel/drivers");
216 	if (directory.InitCheck() != B_OK) {
217 		fprintf(stderr, "Could not open directory: %s\n", strerror(directory.InitCheck()));
218 		return 0;
219 	}
220 
221 	// yes, I know I am lazy...
222 	if (argc > 1 && !strcmp(argv[1], "-v"))
223 		gVerbose = true;
224 
225 	entry_ref ref;
226 	while (directory.GetNextRef(&ref) == B_OK) {
227 		load_settings(ref.name);
228 	}
229 
230 	// load additional files specified on the command line
231 
232 	for (int32 i = 1; i < argc; i++) {
233 		const char *name = argv[i];
234 		if (name[0] == '-')
235 			continue;
236 
237 		// make path absolute, so that load_driver_settings()
238 		// doesn't search in the standard directory
239 		BPath path(name);
240 		load_settings(path.Path());
241 	}
242 
243 	// check fixed settings strings
244 
245 	for (uint32 i = 0; i < sizeof(kSettings) / sizeof(char *); i++)
246 		check_settings_string(i);
247 
248 	return 0;
249 }
250 
251