ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SIDPlayer/src/prefs.cpp
Revision: 1.3
Committed: 2001-01-16T16:53:26Z (23 years, 9 months ago) by cebix
Branch: MAIN
Changes since 1.2: +78 -8 lines
Log Message:
added options help screen for command line version

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 cebix 1.3
65     // Find descriptor for keyword
66 cebix 1.2 const prefs_desc *d = find_prefs_desc(keyword);
67 cebix 1.3 bool negated_bool = false;
68 cebix 1.2 if (d == NULL) {
69 cebix 1.3 // We also accept boolean arguments in the form '--nokeyword'
70     if (strncmp(keyword, "no", 2) == 0) {
71     negated_bool = true;
72     keyword += 2;
73     d = find_prefs_desc(keyword);
74     }
75     if (d == NULL) {
76     printf("WARNING: Unrecognized argument '%s'\n", *argv);
77     continue;
78     }
79 cebix 1.2 }
80 cebix 1.1
81 cebix 1.2 // Add/replace prefs item
82     switch (d->type) {
83     case TYPE_STRING:
84     if (argc < 2) {
85     printf("WARNING: Argument '%s' must be followed by value\n", *argv);
86     break;
87     }
88     argc--; argv++;
89     if (d->multiple)
90     PrefsAddString(keyword, *argv);
91     else
92     PrefsReplaceString(keyword, *argv);
93     break;
94    
95 cebix 1.3 case TYPE_BOOLEAN: {
96     bool new_value;
97     if (negated_bool)
98     new_value = false;
99     else if (argc > 1 && argv[1][0] != '-') {
100     if (!strcmp(argv[1], "true") || !strcmp(argv[1], "on") || !strcmp(argv[1], "yes")) {
101     new_value = true;
102     argc--; argv++;
103     } else if (!strcmp(argv[1], "false") || !strcmp(argv[1], "off") || !strcmp(argv[1], "no")) {
104     new_value = false;
105     argc--; argv++;
106     } else
107     new_value = true;
108 cebix 1.2 } else
109 cebix 1.3 new_value = true;
110     PrefsReplaceBool(keyword, new_value);
111 cebix 1.2 break;
112 cebix 1.3 }
113 cebix 1.2
114     case TYPE_INT32:
115     if (argc < 2) {
116     printf("WARNING: Argument '%s' must be followed by value\n", *argv);
117     break;
118     }
119     argc--; argv++;
120     PrefsReplaceInt32(keyword, atoi(*argv));
121     break;
122    
123     default:
124     break;
125     }
126     }
127 cebix 1.1 }
128    
129    
130     /*
131     * Deinitialize preferences
132     */
133    
134     void PrefsExit(void)
135     {
136     // Free prefs list
137     prefs_node *p = the_prefs, *next;
138     while (p) {
139     next = p->next;
140     free((void *)p->name);
141     free(p->data);
142     delete p;
143     p = next;
144     }
145     }
146    
147    
148     /*
149 cebix 1.3 * Print preferences options help
150     */
151    
152     static void print_options(const prefs_desc *list)
153     {
154     while (list->type != TYPE_END) {
155     if (list->help) {
156     const char *typestr, *defstr;
157     char numstr[32];
158     switch (list->type) {
159     case TYPE_STRING:
160     typestr = "STRING";
161     defstr = PrefsFindString(list->name);
162     if (defstr == NULL)
163     defstr = "none";
164     break;
165     case TYPE_BOOLEAN:
166     typestr = "BOOL";
167     if (PrefsFindBool(list->name))
168     defstr = "true";
169     else
170     defstr = "false";
171     break;
172     case TYPE_INT32:
173     typestr = "NUMBER";
174     sprintf(numstr, "%d", PrefsFindInt32(list->name));
175     defstr = numstr;
176     break;
177     default:
178     typestr = "<unknown>";
179     defstr = "none";
180     break;
181     }
182     printf(" --%s %s\n %s [default=%s]\n", list->name, typestr, list->help, defstr);
183     }
184     list++;
185     }
186     }
187    
188     void PrefsPrintUsage(void)
189     {
190     printf("\nGeneral options:\n");
191     print_options(common_prefs_items);
192     printf("\nBoolean options can be specified as '--OPTION true|on|yes' and\n'--OPTION false|off|no', or as '--OPTION' and '--noOPTION'.\n");
193     }
194    
195    
196     /*
197 cebix 1.1 * Find preferences descriptor by keyword
198     */
199    
200     static prefs_desc *find_prefs_desc(const char *name, prefs_desc *list)
201     {
202 cebix 1.3 while (list->type != TYPE_END) {
203 cebix 1.1 if (strcmp(list->name, name) == 0)
204     return list;
205     list++;
206     }
207     return NULL;
208     }
209    
210 cebix 1.2 static prefs_desc *find_prefs_desc(const char *name)
211     {
212     return find_prefs_desc(name, common_prefs_items);
213     }
214    
215 cebix 1.1
216     /*
217     * Set prefs items
218     */
219    
220     static void add_data(const char *name, prefs_type type, void *data, int size)
221     {
222     void *d = malloc(size);
223     if (d == NULL)
224     return;
225     memcpy(d, data, size);
226     prefs_node *p = new prefs_node;
227     p->next = 0;
228     p->name = strdup(name);
229     p->type = type;
230     p->data = d;
231 cebix 1.2 p->desc = find_prefs_desc(p->name);
232 cebix 1.1 if (the_prefs) {
233     prefs_node *prev = the_prefs;
234     while (prev->next)
235     prev = prev->next;
236     prev->next = p;
237     } else
238     the_prefs = p;
239     }
240    
241     void PrefsAddString(const char *name, const char *s)
242     {
243     add_data(name, TYPE_STRING, (void *)s, strlen(s) + 1);
244     }
245    
246     void PrefsAddBool(const char *name, bool b)
247     {
248     add_data(name, TYPE_BOOLEAN, &b, sizeof(bool));
249     }
250    
251     void PrefsAddInt32(const char *name, int32 val)
252     {
253     add_data(name, TYPE_INT32, &val, sizeof(int32));
254     }
255    
256    
257     /*
258     * Replace prefs items
259     */
260    
261     static prefs_node *find_node(const char *name, prefs_type type, int index = 0)
262     {
263     prefs_node *p = the_prefs;
264     int i = 0;
265     while (p) {
266     if ((type == TYPE_ANY || p->type == type) && !strcmp(p->name, name)) {
267     if (i == index)
268     return p;
269     else
270     i++;
271     }
272     p = p->next;
273     }
274     return NULL;
275     }
276    
277     void PrefsReplaceString(const char *name, const char *s, int index)
278     {
279     prefs_node *p = find_node(name, TYPE_STRING, index);
280     if (p) {
281     if (p->desc && p->desc->func)
282     ((prefs_func_string)(p->desc->func))(name, (const char *)p->data, s);
283     free(p->data);
284     p->data = strdup(s);
285     } else
286     add_data(name, TYPE_STRING, (void *)s, strlen(s) + 1);
287     }
288    
289     void PrefsReplaceBool(const char *name, bool b)
290     {
291     prefs_node *p = find_node(name, TYPE_BOOLEAN);
292     if (p) {
293     if (p->desc && p->desc->func)
294     ((prefs_func_bool)(p->desc->func))(name, *(bool *)(p->data), b);
295     *(bool *)(p->data) = b;
296     } else
297     add_data(name, TYPE_BOOLEAN, &b, sizeof(bool));
298     }
299    
300     void PrefsReplaceInt32(const char *name, int32 val)
301     {
302     prefs_node *p = find_node(name, TYPE_INT32);
303     if (p) {
304     if (p->desc && p->desc->func)
305     ((prefs_func_int32)(p->desc->func))(name, *(int32 *)(p->data), val);
306     *(int32 *)(p->data) = val;
307     } else
308     add_data(name, TYPE_INT32, &val, sizeof(int32));
309     }
310    
311    
312     /*
313     * Get prefs items
314     */
315    
316     const char *PrefsFindString(const char *name, int index)
317     {
318     prefs_node *p = find_node(name, TYPE_STRING, index);
319     if (p)
320     return (char *)(p->data);
321     else
322     return NULL;
323     }
324    
325     bool PrefsFindBool(const char *name)
326     {
327     prefs_node *p = find_node(name, TYPE_BOOLEAN, 0);
328     if (p)
329     return *(bool *)(p->data);
330     else
331     return false;
332     }
333    
334     int32 PrefsFindInt32(const char *name)
335     {
336     prefs_node *p = find_node(name, TYPE_INT32, 0);
337     if (p)
338     return *(int32 *)(p->data);
339     else
340     return 0;
341     }
342    
343    
344     /*
345     * Remove prefs items
346     */
347    
348     void PrefsRemoveItem(const char *name, int index)
349     {
350     prefs_node *p = find_node(name, TYPE_ANY, index);
351     if (p) {
352     free((void *)p->name);
353     free(p->data);
354     prefs_node *q = the_prefs;
355     if (q == p) {
356     the_prefs = NULL;
357     delete p;
358     return;
359     }
360     while (q) {
361     if (q->next == p) {
362     q->next = p->next;
363     delete p;
364     return;
365     }
366     q = q->next;
367     }
368     }
369     }
370    
371    
372     /*
373     * Set prefs change callback function
374     */
375    
376     static void set_callback(const char *name, prefs_func f)
377     {
378 cebix 1.2 prefs_desc *d = find_prefs_desc(name);
379 cebix 1.1 if (d == NULL)
380     return;
381     d->func = f;
382     }
383    
384     void PrefsSetCallback(const char *name, prefs_func_string f)
385     {
386     set_callback(name, (prefs_func)f);
387     }
388    
389     void PrefsSetCallback(const char *name, prefs_func_bool f)
390     {
391     set_callback(name, (prefs_func)f);
392     }
393    
394     void PrefsSetCallback(const char *name, prefs_func_int32 f)
395     {
396     set_callback(name, (prefs_func)f);
397     }