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, 10 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

# User Rev Content
1 cebix 1.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 cebix 1.2 // Prefs items are stored in a linked list of these nodes
32 cebix 1.1 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 cebix 1.2 static prefs_node *the_prefs = NULL;
42    
43     // Prototypes
44     static prefs_desc *find_prefs_desc(const char *name);
45 cebix 1.1
46    
47     /*
48     * Initialize preferences
49     */
50    
51     void PrefsInit(int argc, char **argv)
52     {
53 cebix 1.2 // 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 cebix 1.1
70 cebix 1.2 // 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 cebix 1.1 }
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 cebix 1.2 static prefs_desc *find_prefs_desc(const char *name)
141     {
142     return find_prefs_desc(name, common_prefs_items);
143     }
144    
145 cebix 1.1
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 cebix 1.2 p->desc = find_prefs_desc(p->name);
162 cebix 1.1 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 cebix 1.2 prefs_desc *d = find_prefs_desc(name);
309 cebix 1.1 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     }