PCem

view src/config.c @ 113:f749363ad763

Added per-device configuration. Reworked configuration parser a bit. Added configuration for S3 ViRGE and 8-bit Sound Blasters. IRQ 2 routed to IRQ 9 on AT machines.
author TomW
date Mon Jun 30 21:31:28 2014 +0100
parents fb4a67daaa1b
children 55564c65aa15
line source
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include "config.h"
6 static char config_file[256];
8 typedef struct list_t
9 {
10 struct list_t *next;
11 } list_t;
13 static list_t config_head;
15 typedef struct section_t
16 {
17 struct list_t list;
19 char name[256];
21 struct list_t entry_head;
22 } section_t;
24 typedef struct entry_t
25 {
26 struct list_t list;
28 char name[256];
29 char data[256];
30 } entry_t;
32 #define list_add(new, head) \
33 { \
34 struct list_t *next = head; \
35 \
36 while (next->next) \
37 next = next->next; \
38 \
39 (next)->next = new; \
40 (new)->next = NULL; \
41 }
43 void config_dump()
44 {
45 section_t *current_section;
47 pclog("Config data :\n");
49 current_section = (section_t *)config_head.next;
51 while (current_section)
52 {
53 entry_t *current_entry;
55 pclog("[%s]\n", current_section->name);
57 current_entry = (entry_t *)current_section->entry_head.next;
59 while (current_entry)
60 {
61 pclog("%s = %s\n", current_entry->name, current_entry->data);
63 current_entry = (entry_t *)current_entry->list.next;
64 }
66 current_section = (section_t *)current_section->list.next;
67 }
68 }
70 void config_free()
71 {
72 section_t *current_section;
73 current_section = (section_t *)config_head.next;
75 while (current_section)
76 {
77 section_t *next_section = (section_t *)current_section->list.next;
78 entry_t *current_entry;
80 current_entry = (entry_t *)current_section->entry_head.next;
82 while (current_entry)
83 {
84 entry_t *next_entry = (entry_t *)current_entry->list.next;
86 free(current_entry);
87 current_entry = next_entry;
88 }
90 free(current_section);
91 current_section = next_section;
92 }
93 }
95 void config_load()
96 {
97 FILE *f = fopen(config_file, "rt");
98 section_t *current_section;
100 memset(&config_head, 0, sizeof(list_t));
102 current_section = malloc(sizeof(section_t));
103 memset(current_section, 0, sizeof(section_t));
104 list_add(&current_section->list, &config_head);
106 if (!f)
107 return;
109 while (1)
110 {
111 int c;
112 char buffer[256];
114 fgets(buffer, 255, f);
115 if (feof(f)) break;
117 c = 0;
119 while (buffer[c] == ' ' && buffer[c])
120 c++;
122 if (!buffer[c]) continue;
124 if (buffer[c] == '#') /*Comment*/
125 continue;
127 if (buffer[c] == '[') /*Section*/
128 {
129 section_t *new_section;
130 char name[256];
131 int d = 0;
133 c++;
134 while (buffer[c] != ']' && buffer[c])
135 name[d++] = buffer[c++];
137 if (buffer[c] != ']')
138 continue;
139 name[d] = 0;
141 new_section = malloc(sizeof(section_t));
142 memset(new_section, 0, sizeof(section_t));
143 strncpy(new_section->name, name, 256);
144 list_add(&new_section->list, &config_head);
146 current_section = new_section;
148 // pclog("New section : %s %p\n", name, (void *)current_section);
149 }
150 else
151 {
152 entry_t *new_entry;
153 char name[256];
154 int d = 0, data_pos;
156 while (buffer[c] != '=' && buffer[c] != ' ' && buffer[c])
157 name[d++] = buffer[c++];
159 if (!buffer[c]) continue;
160 name[d] = 0;
162 while ((buffer[c] == '=' || buffer[c] == ' ') && buffer[c])
163 c++;
165 if (!buffer[c]) continue;
167 data_pos = c;
168 while (buffer[c])
169 {
170 if (buffer[c] == '\n')
171 buffer[c] = 0;
172 c++;
173 }
175 new_entry = malloc(sizeof(entry_t));
176 memset(new_entry, 0, sizeof(entry_t));
177 strncpy(new_entry->name, name, 256);
178 strncpy(new_entry->data, &buffer[data_pos], 256);
179 list_add(&new_entry->list, &current_section->entry_head);
181 // pclog("New data under section [%s] : %s = %s\n", current_section->name, new_entry->name, new_entry->data);
182 }
183 }
185 fclose(f);
187 config_dump();
188 }
192 void set_config_file(char *s)
193 {
194 strcpy(config_file, s);
195 }
197 void config_new()
198 {
199 FILE *f = fopen(config_file, "wt");
200 fclose(f);
201 }
203 static section_t *find_section(char *name)
204 {
205 section_t *current_section;
206 char blank[] = "";
208 current_section = (section_t *)config_head.next;
209 if (!name)
210 name = blank;
212 while (current_section)
213 {
214 if (!strncmp(current_section->name, name, 256))
215 return current_section;
217 current_section = (section_t *)current_section->list.next;
218 }
219 return NULL;
220 }
222 static entry_t *find_entry(section_t *section, char *name)
223 {
224 entry_t *current_entry;
226 current_entry = (entry_t *)section->entry_head.next;
228 while (current_entry)
229 {
230 if (!strncmp(current_entry->name, name, 256))
231 return current_entry;
233 current_entry = (entry_t *)current_entry->list.next;
234 }
235 return NULL;
236 }
238 static section_t *create_section(char *name)
239 {
240 section_t *new_section = malloc(sizeof(section_t));
242 memset(new_section, 0, sizeof(section_t));
243 strncpy(new_section->name, name, 256);
244 list_add(&new_section->list, &config_head);
246 return new_section;
247 }
249 static entry_t *create_entry(section_t *section, char *name)
250 {
251 entry_t *new_entry = malloc(sizeof(entry_t));
252 memset(new_entry, 0, sizeof(entry_t));
253 strncpy(new_entry->name, name, 256);
254 list_add(&new_entry->list, &section->entry_head);
256 return new_entry;
257 }
259 int get_config_int(char *head, char *name, int def)
260 {
261 section_t *section;
262 entry_t *entry;
263 int value;
265 section = find_section(head);
267 if (!section)
268 return def;
270 entry = find_entry(section, name);
272 if (!entry)
273 return def;
275 sscanf(entry->data, "%i", &value);
277 return value;
278 }
280 char *get_config_string(char *head, char *name, char *def)
281 {
282 section_t *section;
283 entry_t *entry;
284 int value;
286 section = find_section(head);
288 if (!section)
289 return def;
291 entry = find_entry(section, name);
293 if (!entry)
294 return def;
296 return entry->data;
297 }
299 void set_config_int(char *head, char *name, int val)
300 {
301 section_t *section;
302 entry_t *entry;
304 section = find_section(head);
306 if (!section)
307 section = create_section(head);
309 entry = find_entry(section, name);
311 if (!entry)
312 entry = create_entry(section, name);
314 sprintf(entry->data, "%i", val);
315 }
317 void set_config_string(char *head, char *name, char *val)
318 {
319 section_t *section;
320 entry_t *entry;
322 section = find_section(head);
324 if (!section)
325 section = create_section(head);
327 entry = find_entry(section, name);
329 if (!entry)
330 entry = create_entry(section, name);
332 strncpy(entry->data, val, 256);
333 }
336 char *get_filename(char *s)
337 {
338 int c = strlen(s) - 1;
339 while (c > 0)
340 {
341 if (s[c] == '/' || s[c] == '\\')
342 return &s[c+1];
343 c--;
344 }
345 return s;
346 }
348 void append_filename(char *dest, char *s1, char *s2, int size)
349 {
350 sprintf(dest, "%s%s", s1, s2);
351 }
353 void put_backslash(char *s)
354 {
355 int c = strlen(s) - 1;
356 if (s[c] != '/' && s[c] != '\\')
357 s[c] = '/';
358 }
360 void config_save()
361 {
362 FILE *f = fopen(config_file, "wt");
363 section_t *current_section;
365 current_section = (section_t *)config_head.next;
367 while (current_section)
368 {
369 entry_t *current_entry;
371 if (current_section->name[0])
372 fprintf(f, "\n[%s]\n", current_section->name);
374 current_entry = (entry_t *)current_section->entry_head.next;
376 while (current_entry)
377 {
378 fprintf(f, "%s = %s\n", current_entry->name, current_entry->data);
380 current_entry = (entry_t *)current_entry->list.next;
381 }
383 current_section = (section_t *)current_section->list.next;
384 }
386 fclose(f);
387 }