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
17bool gVerbose = false;
18
19// Just add your test settings here, they will be picked
20// up automatically
21
22const 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
40size_t
41strnlen(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
60size_t
61strlcat(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
86void
87put_level_space(int32 level)
88{
89	while (level-- > 0)
90		putchar('\t');
91}
92
93
94void
95dump_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
109void
110dump_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
117void
118print_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	delete_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	delete_driver_settings(reparsedHandle);
159}
160
161
162void
163check_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	delete_driver_settings(handle);
185}
186
187
188void
189load_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
207end:
208	if (unload_driver_settings(handle) < B_OK)
209		fprintf(stderr, "Could not unload driver settings \"%s\"\n", name);
210}
211
212
213int
214main(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