ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/prefs.cpp
Revision: 1.8
Committed: 2000-07-25T15:19:40Z (24 years, 4 months ago) by cebix
Branch: MAIN
Changes since 1.7: +2 -49 lines
Log Message:
- more cleanups
- splitted prefs.cpp into prefs.cpp and prefs_items.cpp to make prefs.cpp
  reusable for other projects

File Contents

# User Rev Content
1 cebix 1.1 /*
2     * prefs.cpp - Preferences handling
3     *
4 cebix 1.4 * Basilisk II (C) 1997-2000 Christian Bauer
5 cebix 1.1 *
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 <string.h>
22     #include <stdlib.h>
23     #include <stdio.h>
24     #include <ctype.h>
25    
26     #include "sysdeps.h"
27     #include "sys.h"
28     #include "prefs.h"
29    
30    
31 cebix 1.8 // 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     };
38    
39     // List of prefs nodes
40     static prefs_node *the_prefs;
41    
42    
43     /*
44     * Initialize preferences
45     */
46    
47     void PrefsInit(void)
48     {
49     // Start with empty list
50     the_prefs = NULL;
51    
52     // Set defaults
53 cebix 1.8 AddPrefsDefaults();
54 cebix 1.1 AddPlatformPrefsDefaults();
55    
56     // Load preferences from settings file
57     LoadPrefs();
58     }
59    
60    
61     /*
62     * Deinitialize preferences
63     */
64    
65     void PrefsExit(void)
66     {
67     // Free prefs list
68     prefs_node *p = the_prefs, *next;
69     while (p) {
70     next = p->next;
71     free((void *)p->name);
72     free(p->data);
73     delete p;
74     p = next;
75     }
76     }
77    
78    
79     /*
80     * Find preferences descriptor by keyword
81     */
82    
83     static const prefs_desc *find_prefs_desc(const char *name, const prefs_desc *list)
84     {
85     while (list->type != TYPE_ANY) {
86     if (strcmp(list->name, name) == 0)
87     return list;
88     list++;
89     }
90     return NULL;
91     }
92    
93    
94     /*
95     * Set prefs items
96     */
97    
98     static void add_data(const char *name, prefs_type type, void *data, int size)
99     {
100     void *d = malloc(size);
101     if (d == NULL)
102     return;
103     memcpy(d, data, size);
104     prefs_node *p = new prefs_node;
105     p->next = 0;
106     p->name = strdup(name);
107     p->type = type;
108     p->data = d;
109     if (the_prefs) {
110     prefs_node *prev = the_prefs;
111     while (prev->next)
112     prev = prev->next;
113     prev->next = p;
114     } else
115     the_prefs = p;
116     }
117    
118     void PrefsAddString(const char *name, const char *s)
119     {
120     add_data(name, TYPE_STRING, (void *)s, strlen(s) + 1);
121     }
122    
123     void PrefsAddBool(const char *name, bool b)
124     {
125     add_data(name, TYPE_BOOLEAN, &b, sizeof(bool));
126     }
127    
128     void PrefsAddInt16(const char *name, int16 val)
129     {
130     add_data(name, TYPE_INT16, &val, sizeof(int16));
131     }
132    
133     void PrefsAddInt32(const char *name, int32 val)
134     {
135     add_data(name, TYPE_INT32, &val, sizeof(int32));
136     }
137    
138    
139     /*
140     * Replace prefs items
141     */
142    
143     static prefs_node *find_node(const char *name, prefs_type type, int index = 0)
144     {
145     prefs_node *p = the_prefs;
146     int i = 0;
147     while (p) {
148     if ((type == TYPE_ANY || p->type == type) && !strcmp(p->name, name)) {
149     if (i == index)
150     return p;
151     else
152     i++;
153     }
154     p = p->next;
155     }
156     return NULL;
157     }
158    
159     void PrefsReplaceString(const char *name, const char *s, int index)
160     {
161     prefs_node *p = find_node(name, TYPE_STRING, index);
162     if (p) {
163     free(p->data);
164     p->data = strdup(s);
165     } else
166     add_data(name, TYPE_STRING, (void *)s, strlen(s) + 1);
167     }
168    
169     void PrefsReplaceBool(const char *name, bool b)
170     {
171     prefs_node *p = find_node(name, TYPE_BOOLEAN);
172     if (p)
173     *(bool *)(p->data) = b;
174     else
175     add_data(name, TYPE_BOOLEAN, &b, sizeof(bool));
176     }
177    
178     void PrefsReplaceInt16(const char *name, int16 val)
179     {
180     prefs_node *p = find_node(name, TYPE_INT16);
181     if (p)
182     *(int16 *)(p->data) = val;
183     else
184     add_data(name, TYPE_INT16, &val, sizeof(int16));
185     }
186    
187     void PrefsReplaceInt32(const char *name, int32 val)
188     {
189     prefs_node *p = find_node(name, TYPE_INT32);
190     if (p)
191     *(int32 *)(p->data) = val;
192     else
193     add_data(name, TYPE_INT32, &val, sizeof(int32));
194     }
195    
196    
197     /*
198     * Get prefs items
199     */
200    
201     const char *PrefsFindString(const char *name, int index)
202     {
203     prefs_node *p = find_node(name, TYPE_STRING, index);
204     if (p)
205     return (char *)(p->data);
206     else
207     return NULL;
208     }
209    
210     bool PrefsFindBool(const char *name)
211     {
212     prefs_node *p = find_node(name, TYPE_BOOLEAN, 0);
213     if (p)
214     return *(bool *)(p->data);
215     else
216     return false;
217     }
218    
219     int16 PrefsFindInt16(const char *name)
220     {
221     prefs_node *p = find_node(name, TYPE_INT16, 0);
222     if (p)
223     return *(int16 *)(p->data);
224     else
225     return 0;
226     }
227    
228     int32 PrefsFindInt32(const char *name)
229     {
230     prefs_node *p = find_node(name, TYPE_INT32, 0);
231     if (p)
232     return *(int32 *)(p->data);
233     else
234     return 0;
235     }
236    
237    
238     /*
239     * Remove prefs items
240     */
241    
242     void PrefsRemoveItem(const char *name, int index)
243     {
244     prefs_node *p = find_node(name, TYPE_ANY, index);
245     if (p) {
246     free((void *)p->name);
247     free(p->data);
248     prefs_node *q = the_prefs;
249     if (q == p) {
250     the_prefs = NULL;
251     delete p;
252     return;
253     }
254     while (q) {
255     if (q->next == p) {
256     q->next = p->next;
257     delete p;
258     return;
259     }
260     q = q->next;
261     }
262     }
263     }
264    
265    
266     /*
267     * Load prefs from stream (utility function for LoadPrefs() implementation)
268     */
269    
270     void LoadPrefsFromStream(FILE *f)
271     {
272     char line[256];
273     while(fgets(line, 255, f)) {
274     // Read line
275     int len = strlen(line);
276     if (len == 0)
277     continue;
278     line[len-1] = 0;
279    
280     // Comments begin with "#" or ";"
281     if (line[0] == '#' || line[0] == ';')
282     continue;
283    
284     // Terminate string after keyword
285     char *p = line;
286     while (!isspace(*p)) p++;
287     *p++ = 0;
288    
289     // Skip whitespace until value
290     while (isspace(*p)) p++;
291     char *keyword = line;
292     char *value = p;
293     int32 i = atol(value);
294    
295     // Look for keyword first in common item list, then in platform specific list
296     const prefs_desc *desc = find_prefs_desc(keyword, common_prefs_items);
297     if (desc == NULL)
298     desc = find_prefs_desc(keyword, platform_prefs_items);
299     if (desc == NULL) {
300     printf("WARNING: Unknown preferences keyword '%s'\n", keyword);
301     continue;
302     }
303    
304     // Add item to prefs
305     switch (desc->type) {
306     case TYPE_STRING:
307     if (desc->multiple)
308     PrefsAddString(keyword, value);
309     else
310     PrefsReplaceString(keyword, value);
311     break;
312     case TYPE_BOOLEAN:
313     PrefsReplaceBool(keyword, !strcmp(value, "true"));
314     break;
315     case TYPE_INT16:
316     PrefsReplaceInt16(keyword, i);
317     break;
318     case TYPE_INT32:
319     PrefsReplaceInt32(keyword, i);
320     break;
321     default:
322     break;
323     }
324     }
325     }
326    
327    
328     /*
329     * Save settings to stream (utility function for SavePrefs() implementation)
330     */
331    
332     static void write_prefs(FILE *f, const prefs_desc *list)
333     {
334     while (list->type != TYPE_ANY) {
335     switch (list->type) {
336     case TYPE_STRING: {
337     int index = 0;
338     const char *str;
339     while ((str = PrefsFindString(list->name, index++)) != NULL)
340     fprintf(f, "%s %s\n", list->name, str);
341     break;
342     }
343     case TYPE_BOOLEAN:
344     fprintf(f, "%s %s\n", list->name, PrefsFindBool(list->name) ? "true" : "false");
345     break;
346     case TYPE_INT16:
347     fprintf(f, "%s %d\n", list->name, PrefsFindInt16(list->name));
348     break;
349     case TYPE_INT32:
350 cebix 1.7 fprintf(f, "%s %d\n", list->name, PrefsFindInt32(list->name));
351 cebix 1.1 break;
352     default:
353     break;
354     }
355     list++;
356     }
357     }
358    
359     void SavePrefsToStream(FILE *f)
360     {
361     write_prefs(f, common_prefs_items);
362     write_prefs(f, platform_prefs_items);
363     }