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