]> icculus.org git repositories - taylor/freespace2.git/blob - src/osapi/osregistry-unix.cpp
finished cfilesystem.
[taylor/freespace2.git] / src / osapi / osregistry-unix.cpp
1 #include "pstypes.h"
2 #include "osregistry.h"
3 #undef malloc
4 #undef free
5 #undef strdup
6
7 #include <stdio.h>
8 #include <string.h>
9 #include <ctype.h>
10
11 char *Osreg_company_name = "Volition";
12 char *Osreg_class_name = "Freespace2Class";
13 #if defined(FS2_DEMO)
14 char *Osreg_app_name = "FreeSpace2Demo";
15 char *Osreg_title = "Freespace 2 Demo";
16 #define PROFILE_NAME "FreeSpace2Demo.ini"
17 #elif defined(OEM_BUILD)
18 char *Osreg_app_name = "FreeSpace2OEM";
19 char *Osreg_title = "Freespace 2 OEM";
20 #define PROFILE_NAME "FreeSpace2OEM.ini"
21 #else
22 char *Osreg_app_name = "FreeSpace2";
23 char *Osreg_title = "Freespace 2";
24 #define PROFILE_NAME "FreeSpace2.ini"
25 #endif
26
27 #define DEFAULT_SECTION "Default"
28
29 typedef struct KeyValue
30 {
31         char *key;
32         char *value;
33         
34         KeyValue *next;
35 } KeyValue;
36
37 typedef struct Section
38 {
39         char *name;
40         
41         KeyValue *pairs;
42         Section *next;
43 } Section;
44         
45 typedef struct Profile
46 {
47         Section *sections;
48 } Profile;
49
50 static char *read_line_from_file(FILE *fp)
51 {
52         char *buf, *buf_start;
53         int buflen, len, eol;
54         
55         buflen = 80;
56         buf = (char *)malloc(buflen);
57         buf_start = buf;
58         eol = 0;
59         
60         do {
61                 if (buf == NULL)
62                         return NULL;
63                 
64                 if (fgets(buf_start, 80, fp) == NULL)
65                         return NULL;
66                 
67                 len = strlen(buf_start);
68                 
69                 if (buf_start[len-1] == '\n') {
70                         buf_start[len-1] = 0;
71                         eol = 1;
72                 } else {
73                         buflen += 80;
74                         
75                         buf = (char *)realloc(buf, buflen);
76                         
77                         /* be sure to skip over the proper amount of nulls */
78                         buf_start = buf+(buflen-80)-(buflen/80)+1;
79                 }
80         } while (!eol);
81         
82         return buf;
83 }
84
85 static char *trim_string(char *str)
86 {
87         char *ptr;
88         
89         if (str == NULL)
90                 return NULL;
91         
92         /* kill any comment */
93         ptr = strchr(str, ';');
94         if (ptr)
95                 *ptr = 0;
96         ptr = strchr(str, '#');
97         if (ptr)
98                 *ptr = 0;
99         
100         ptr = str+strlen(str)-1;
101         while (*ptr && isspace(*ptr)) {
102                 ptr--;
103         }
104         
105         if (*ptr) {
106                 ptr++;
107                 *ptr = 0;
108         }
109         
110         ptr = str;
111         while (*ptr && isspace(*ptr)) {
112                 ptr++;
113         }
114         
115         return ptr;
116 }
117
118 static Profile *profile_read(char *file)
119 {
120         FILE *fp = fopen(file, "r");
121         if (fp == NULL)
122                 return NULL;
123         
124         Profile *profile = (Profile *)malloc(sizeof(Profile));
125         profile->sections = NULL;
126         
127         Section **sp_ptr = &(profile->sections);
128         Section *sp = NULL;
129
130         KeyValue **kvp_ptr = NULL;
131                 
132         char *str;
133         while ((str = read_line_from_file(fp)) != NULL) {
134                 char *ptr = trim_string(str);
135                 
136                 if (*ptr == '[') {
137                         ptr++;
138                         
139                         char *pend = strchr(ptr, ']');
140                         if (pend != NULL) {
141                                 // if (pend[1]) { /* trailing garbage! */ }
142                                 
143                                 *pend = 0;                              
144                                 
145                                 if (*ptr) {
146                                         sp = (Section *)malloc(sizeof(Section));
147                                         sp->next = NULL;
148                                 
149                                         sp->name = strdup(ptr);
150                                         sp->pairs = NULL;
151                                         
152                                         *sp_ptr = sp;
153                                         sp_ptr = &(sp->next);
154                                         
155                                         kvp_ptr = &(sp->pairs);
156                                 } // else { /* null name! */ }
157                         } // else { /* incomplete section name! */ }
158                 } else {
159                         if (*ptr) {
160                                 char *key = ptr;
161                                 char *value = NULL;
162                                 
163                                 ptr = strchr(ptr, '=');
164                                 if (ptr != NULL) {
165                                         *ptr = 0;
166                                         ptr++;
167                                         
168                                         value = ptr;
169                                 } // else { /* random garbage! */ }
170                                 
171                                 if (key && *key && value /* && *value */) {
172                                         if (sp != NULL) {
173                                                 KeyValue *kvp = (KeyValue *)malloc(sizeof(KeyValue));
174                                                 
175                                                 kvp->key = strdup(key);
176                                                 kvp->value = strdup(value);
177                                                 
178                                                 kvp->next = NULL;
179                                                 
180                                                 *kvp_ptr = kvp;
181                                                 kvp_ptr = &(kvp->next);
182                                         } // else { /* key/value with no section! */
183                                 } // else { /* malformed key/value entry! */ }
184                         } // else it's just a comment or empty string
185                 }
186                                 
187                 free(str);
188         }
189         
190         fclose(fp);
191
192         return profile;
193 }
194
195 static void profile_free(Profile *profile)
196 {
197         if (profile == NULL)
198                 return;
199                 
200         Section *sp = profile->sections;
201         while (sp != NULL) {
202                 Section *st = sp;
203                 KeyValue *kvp = sp->pairs;
204                 
205                 while (kvp != NULL) {
206                         KeyValue *kvt = kvp;
207                         
208                         free(kvp->key);
209                         free(kvp->value);
210                         
211                         kvp = kvp->next;
212                         free(kvt);
213                 }
214                 
215                 free(sp->name);
216                 
217                 sp = sp->next;
218                 free(st);
219         }
220         
221         free(profile);
222 }
223
224 static Profile *profile_update(Profile *profile, char *section, char *key, char *value)
225 {
226         if (profile == NULL) {
227                 profile = (Profile *)malloc(sizeof(Profile));
228                 
229                 profile->sections = NULL;
230         }
231         
232         KeyValue *kvp;
233         
234         Section **sp_ptr = &(profile->sections);
235         Section *sp = profile->sections;
236         while (sp != NULL) {
237                 if (strcmp(section, sp->name) == 0) {
238                         KeyValue **kvp_ptr = &(sp->pairs);
239                         kvp = sp->pairs;
240                         
241                         while (kvp != NULL) {
242                                 if (strcmp(key, kvp->key) == 0) {
243                                         free(kvp->value);
244                                         
245                                         kvp->value = strdup(value);
246                                         
247                                         /* all done */
248                                         return profile;
249                                 }
250                                 
251                                 kvp_ptr = &(kvp->next);
252                                 kvp = kvp->next;
253                         }
254                         
255                         /* key not found */
256                         kvp = (KeyValue *)malloc(sizeof(KeyValue));
257                         kvp->next = NULL;
258                         kvp->key = strdup(key);
259                         kvp->value = strdup(value);
260                         
261                         *kvp_ptr = kvp;
262                         
263                         /* all done */
264                         return profile;
265                 }
266                 
267                 sp_ptr = &(sp->next);
268                 sp = sp->next;
269         }
270         
271         /* section not found */
272         sp = (Section *)malloc(sizeof(Section));
273         sp->next = NULL;
274         sp->name = strdup(section);
275         
276         kvp = (KeyValue *)malloc(sizeof(KeyValue));
277         kvp->next = NULL;
278         kvp->key = strdup(key);
279         kvp->value = strdup(value);
280         
281         sp->pairs = kvp;
282         
283         *sp_ptr = sp;
284         
285         return profile;
286 }
287
288 static char *profile_get_value(Profile *profile, char *section, char *key)
289 {
290         if (profile == NULL)
291                 return NULL;
292         
293         Section *sp = profile->sections;
294         while (sp != NULL) {
295                 if (strcmp(section, sp->name) == 0) {
296                         KeyValue *kvp = sp->pairs;
297                 
298                         while (kvp != NULL) {
299                                 if (strcmp(key, kvp->key) == 0) {
300                                         return kvp->value;
301                                 }
302                                 kvp = kvp->next;
303                         }
304                 }
305                 
306                 sp = sp->next;
307         }
308         
309         /* not found */
310         return NULL;
311 }
312
313 static void profile_save(Profile *profile, char *file)
314 {
315         FILE *fp;
316         
317         if (profile == NULL)
318                 return;
319                 
320         fp = fopen(file, "w");
321         if (fp == NULL)
322                 return;
323         
324         Section *sp = profile->sections;
325         while (sp != NULL) {
326                 fprintf(fp, "[%s]\n", sp->name);
327                 
328                 KeyValue *kvp = sp->pairs;
329                 while (kvp != NULL) {
330                         fprintf(fp, "%s=%s\n", kvp->key, kvp->value);
331                         kvp = kvp->next;
332                 }
333                 
334                 fprintf(fp, "\n");
335                 
336                 sp = sp->next;
337         }
338         
339         fclose(fp);
340 }
341
342 static char tmp_string_data[1024];
343
344 char *os_config_read_string(char *section, char *name, char *default_value)
345 {
346         Profile *p = profile_read(PROFILE_NAME);
347         
348         if (section == NULL)
349                 section = DEFAULT_SECTION;
350                 
351         char *ptr = profile_get_value(p, section, name);
352         if (ptr != NULL) {
353                 strncpy(tmp_string_data, ptr, 1023);
354                 default_value = tmp_string_data;
355         }
356         
357         profile_free(p);
358         
359         return default_value;
360 }
361
362 unsigned int os_config_read_uint(char *section, char *name, unsigned int default_value)
363 {
364         Profile *p = profile_read(PROFILE_NAME);
365         
366         if (section == NULL)
367                 section = DEFAULT_SECTION;
368                 
369         char *ptr = profile_get_value(p, section, name);
370         if (ptr != NULL) {
371                 default_value = atoi(ptr);
372         }
373         
374         profile_free(p);
375         
376         return default_value;
377 }
378
379 void os_config_write_string(char *section, char *name, char *value)
380 {
381         Profile *p = profile_read(PROFILE_NAME);
382         
383         if (section == NULL)
384                 section = DEFAULT_SECTION;
385                 
386         p = profile_update(p, section, name, value);
387         profile_save(p, PROFILE_NAME);
388         profile_free(p);        
389 }
390
391 void os_config_write_uint(char *section, char *name, unsigned int value)
392 {
393         static char buf[21];
394         
395         snprintf(buf, 20, "%u", value);
396         
397         Profile *p = profile_read(PROFILE_NAME);
398         
399         if (section == NULL)
400                 section = DEFAULT_SECTION;
401         
402         p = profile_update(p, section, name, buf);
403         profile_save(p, PROFILE_NAME);
404         profile_free(p);
405 }