ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SIDPlayer/src/prefs.cpp
Revision: 1.2
Committed: 2001-01-04T19:54:13Z (23 years, 3 months ago) by cebix
Branch: MAIN
Changes since 1.1: +63 -55 lines
Log Message:
- split prefs.cpp into prefs.cpp and prefs_items.cpp
- it's now possible to specify prefs items on the command line

File Contents

# Content
1 /*
2 * prefs.cpp - Preferences handling
3 *
4 * SIDPlayer (C) Copyright 1996-2000 Christian Bauer
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include "sys.h"
22
23 #include <string.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <ctype.h>
27
28 #include "prefs.h"
29
30
31 // Prefs items are stored in a linked list of these nodes
32 struct prefs_node {
33 prefs_node *next;
34 const char *name;
35 prefs_type type;
36 void *data;
37 prefs_desc *desc;
38 };
39
40 // List of prefs nodes
41 static prefs_node *the_prefs = NULL;
42
43 // Prototypes
44 static prefs_desc *find_prefs_desc(const char *name);
45
46
47 /*
48 * Initialize preferences
49 */
50
51 void PrefsInit(int argc, char **argv)
52 {
53 // Set defaults
54 AddPrefsDefaults();
55
56 // Override prefs with command line arguments
57 argc--; argv++;
58 for (; argc>0; argc--, argv++) {
59
60 // Arguments are of the form '--keyword'
61 if (strlen(*argv) < 3 || argv[0][0] != '-' || argv[0][1] != '-')
62 continue;
63 const char *keyword = *argv + 2;
64 const prefs_desc *d = find_prefs_desc(keyword);
65 if (d == NULL) {
66 printf("WARNING: Unrecognized argument '%s'\n", *argv);
67 continue;
68 }
69
70 // Add/replace prefs item
71 switch (d->type) {
72 case TYPE_STRING:
73 if (argc < 2) {
74 printf("WARNING: Argument '%s' must be followed by value\n", *argv);
75 break;
76 }
77 argc--; argv++;
78 if (d->multiple)
79 PrefsAddString(keyword, *argv);
80 else
81 PrefsReplaceString(keyword, *argv);
82 break;
83
84 case TYPE_BOOLEAN:
85 if (argc > 1 && argv[1][0] != '-') {
86 argc--; argv++;
87 PrefsReplaceBool(keyword, !strcmp(*argv, "true") || !strcmp(*argv, "on"));
88 } else
89 PrefsReplaceBool(keyword, true);
90 break;
91
92 case TYPE_INT32:
93 if (argc < 2) {
94 printf("WARNING: Argument '%s' must be followed by value\n", *argv);
95 break;
96 }
97 argc--; argv++;
98 PrefsReplaceInt32(keyword, atoi(*argv));
99 break;
100
101 default:
102 break;
103 }
104 }
105 }
106
107
108 /*
109 * Deinitialize preferences
110 */
111
112 void PrefsExit(void)
113 {
114 // Free prefs list
115 prefs_node *p = the_prefs, *next;
116 while (p) {
117 next = p->next;
118 free((void *)p->name);
119 free(p->data);
120 delete p;
121 p = next;
122 }
123 }
124
125
126 /*
127 * Find preferences descriptor by keyword
128 */
129
130 static prefs_desc *find_prefs_desc(const char *name, prefs_desc *list)
131 {
132 while (list->type != TYPE_ANY) {
133 if (strcmp(list->name, name) == 0)
134 return list;
135 list++;
136 }
137 return NULL;
138 }
139
140 static prefs_desc *find_prefs_desc(const char *name)
141 {
142 return find_prefs_desc(name, common_prefs_items);
143 }
144
145
146 /*
147 * Set prefs items
148 */
149
150 static void add_data(const char *name, prefs_type type, void *data, int size)
151 {
152 void *d = malloc(size);
153 if (d == NULL)
154 return;
155 memcpy(d, data, size);
156 prefs_node *p = new prefs_node;
157 p->next = 0;
158 p->name = strdup(name);
159 p->type = type;
160 p->data = d;
161 p->desc = find_prefs_desc(p->name);
162 if (the_prefs) {
163 prefs_node *prev = the_prefs;
164 while (prev->next)
165 prev = prev->next;
166 prev->next = p;
167 } else
168 the_prefs = p;
169 }
170
171 void PrefsAddString(const char *name, const char *s)
172 {
173 add_data(name, TYPE_STRING, (void *)s, strlen(s) + 1);
174 }
175
176 void PrefsAddBool(const char *name, bool b)
177 {
178 add_data(name, TYPE_BOOLEAN, &b, sizeof(bool));
179 }
180
181 void PrefsAddInt32(const char *name, int32 val)
182 {
183 add_data(name, TYPE_INT32, &val, sizeof(int32));
184 }
185
186
187 /*
188 * Replace prefs items
189 */
190
191 static prefs_node *find_node(const char *name, prefs_type type, int index = 0)
192 {
193 prefs_node *p = the_prefs;
194 int i = 0;
195 while (p) {
196 if ((type == TYPE_ANY || p->type == type) && !strcmp(p->name, name)) {
197 if (i == index)
198 return p;
199 else
200 i++;
201 }
202 p = p->next;
203 }
204 return NULL;
205 }
206
207 void PrefsReplaceString(const char *name, const char *s, int index)
208 {
209 prefs_node *p = find_node(name, TYPE_STRING, index);
210 if (p) {
211 if (p->desc && p->desc->func)
212 ((prefs_func_string)(p->desc->func))(name, (const char *)p->data, s);
213 free(p->data);
214 p->data = strdup(s);
215 } else
216 add_data(name, TYPE_STRING, (void *)s, strlen(s) + 1);
217 }
218
219 void PrefsReplaceBool(const char *name, bool b)
220 {
221 prefs_node *p = find_node(name, TYPE_BOOLEAN);
222 if (p) {
223 if (p->desc && p->desc->func)
224 ((prefs_func_bool)(p->desc->func))(name, *(bool *)(p->data), b);
225 *(bool *)(p->data) = b;
226 } else
227 add_data(name, TYPE_BOOLEAN, &b, sizeof(bool));
228 }
229
230 void PrefsReplaceInt32(const char *name, int32 val)
231 {
232 prefs_node *p = find_node(name, TYPE_INT32);
233 if (p) {
234 if (p->desc && p->desc->func)
235 ((prefs_func_int32)(p->desc->func))(name, *(int32 *)(p->data), val);
236 *(int32 *)(p->data) = val;
237 } else
238 add_data(name, TYPE_INT32, &val, sizeof(int32));
239 }
240
241
242 /*
243 * Get prefs items
244 */
245
246 const char *PrefsFindString(const char *name, int index)
247 {
248 prefs_node *p = find_node(name, TYPE_STRING, index);
249 if (p)
250 return (char *)(p->data);
251 else
252 return NULL;
253 }
254
255 bool PrefsFindBool(const char *name)
256 {
257 prefs_node *p = find_node(name, TYPE_BOOLEAN, 0);
258 if (p)
259 return *(bool *)(p->data);
260 else
261 return false;
262 }
263
264 int32 PrefsFindInt32(const char *name)
265 {
266 prefs_node *p = find_node(name, TYPE_INT32, 0);
267 if (p)
268 return *(int32 *)(p->data);
269 else
270 return 0;
271 }
272
273
274 /*
275 * Remove prefs items
276 */
277
278 void PrefsRemoveItem(const char *name, int index)
279 {
280 prefs_node *p = find_node(name, TYPE_ANY, index);
281 if (p) {
282 free((void *)p->name);
283 free(p->data);
284 prefs_node *q = the_prefs;
285 if (q == p) {
286 the_prefs = NULL;
287 delete p;
288 return;
289 }
290 while (q) {
291 if (q->next == p) {
292 q->next = p->next;
293 delete p;
294 return;
295 }
296 q = q->next;
297 }
298 }
299 }
300
301
302 /*
303 * Set prefs change callback function
304 */
305
306 static void set_callback(const char *name, prefs_func f)
307 {
308 prefs_desc *d = find_prefs_desc(name);
309 if (d == NULL)
310 return;
311 d->func = f;
312 }
313
314 void PrefsSetCallback(const char *name, prefs_func_string f)
315 {
316 set_callback(name, (prefs_func)f);
317 }
318
319 void PrefsSetCallback(const char *name, prefs_func_bool f)
320 {
321 set_callback(name, (prefs_func)f);
322 }
323
324 void PrefsSetCallback(const char *name, prefs_func_int32 f)
325 {
326 set_callback(name, (prefs_func)f);
327 }