2 #include "osregistry.h"
13 const char *Osreg_company_name = "Volition";
15 const char *Osreg_class_name = "FreespaceClass";
17 const char *Osreg_class_name = "Freespace2Class";
20 const char *Osreg_app_name = "FreeSpaceDemo";
21 const char *Osreg_title = "Freespace Demo";
23 const char *Osreg_user_dir = ".freespace_demo";
25 const char *Osreg_user_dir = "Library/Application Support/FreeSpace Demo";
27 #define PROFILE_NAME "FreeSpaceDemo.ini"
28 #elif defined(FS2_DEMO)
29 const char *Osreg_app_name = "FreeSpace2Demo";
30 const char *Osreg_title = "Freespace 2 Demo";
32 const char *Osreg_user_dir = ".freespace2_demo";
34 const char *Osreg_user_dir = "Library/Application Support/Freespace 2 Demo";
36 #define PROFILE_NAME "FreeSpace2Demo.ini"
37 #elif defined(OEM_BUILD)
38 const char *Osreg_app_name = "FreeSpace2OEM";
39 const char *Osreg_title = "Freespace 2 OEM";
40 #define PROFILE_NAME "FreeSpace2OEM.ini"
41 #elif defined(MAKE_FS1)
42 const char *Osreg_app_name = "FreeSpace";
43 const char *Osreg_title = "FreeSpace";
45 const char *Osreg_user_dir = ".freespace";
47 const char *Osreg_user_dir = "Library/Application Support/FreeSpace";
49 #define PROFILE_NAME "FreeSpace.ini"
51 const char *Osreg_app_name = "FreeSpace2";
52 const char *Osreg_title = "Freespace 2";
54 const char *Osreg_user_dir = ".freespace2";
56 const char *Osreg_user_dir = "Library/Application Support/Freespace 2";
58 #define PROFILE_NAME "FreeSpace2.ini"
61 #define DEFAULT_SECTION "Default"
64 typedef struct KeyValue
69 struct KeyValue *next;
72 typedef struct Section
76 struct KeyValue *pairs;
80 typedef struct Profile
82 struct Section *sections;
85 static char *read_line_from_file(CFILE *fp)
87 char *buf, *buf_start;
91 buf = (char *)malloc(buflen);
100 if (cfgets(buf_start, 80, fp) == NULL) {
101 if (buf_start == buf) {
110 len = strlen(buf_start);
112 if (buf_start[len-1] == '\n') {
113 buf_start[len-1] = 0;
118 buf = (char *)realloc(buf, buflen);
120 /* be sure to skip over the proper amount of nulls */
121 buf_start = buf+(buflen-80)-(buflen/80)+1;
128 static char *trim_string(char *str)
136 /* kill any comment */
137 ptr = strchr(str, ';');
140 ptr = strchr(str, '#');
150 while ((ptr > str) && isspace(*ptr)) {
160 while (*ptr && isspace(*ptr)) {
167 static Profile *profile_read(const char *file)
169 CFILE *fp = cfopen(file, "rt", CFILE_NORMAL, CF_TYPE_ROOT);
173 Profile *profile = (Profile *)malloc(sizeof(Profile));
174 profile->sections = NULL;
176 Section **sp_ptr = &(profile->sections);
179 KeyValue **kvp_ptr = NULL;
182 while ((str = read_line_from_file(fp)) != NULL) {
183 char *ptr = trim_string(str);
188 char *pend = strchr(ptr, ']');
190 // if (pend[1]) { /* trailing garbage! */ }
195 sp = (Section *)malloc(sizeof(Section));
198 sp->name = strdup(ptr);
202 sp_ptr = &(sp->next);
204 kvp_ptr = &(sp->pairs);
205 } // else { /* null name! */ }
206 } // else { /* incomplete section name! */ }
212 ptr = strchr(ptr, '=');
218 } // else { /* random garbage! */ }
220 if (key && *key && value /* && *value */) {
222 KeyValue *kvp = (KeyValue *)malloc(sizeof(KeyValue));
224 kvp->key = strdup(key);
225 kvp->value = strdup(value);
230 kvp_ptr = &(kvp->next);
231 } // else { /* key/value with no section! */
232 } // else { /* malformed key/value entry! */ }
233 } // else it's just a comment or empty string
244 static void profile_free(Profile *profile)
249 Section *sp = profile->sections;
252 KeyValue *kvp = sp->pairs;
254 while (kvp != NULL) {
273 static Profile *profile_update(Profile *profile, const char *section, const char *key, const char *value)
275 if (profile == NULL) {
276 profile = (Profile *)malloc(sizeof(Profile));
278 profile->sections = NULL;
283 Section **sp_ptr = &(profile->sections);
284 Section *sp = profile->sections;
286 if (strcmp(section, sp->name) == 0) {
287 KeyValue **kvp_ptr = &(sp->pairs);
290 while (kvp != NULL) {
291 if (strcmp(key, kvp->key) == 0) {
295 *kvp_ptr = kvp->next;
300 kvp->value = strdup(value);
307 kvp_ptr = &(kvp->next);
313 kvp = (KeyValue *)malloc(sizeof(KeyValue));
315 kvp->key = strdup(key);
316 kvp->value = strdup(value);
325 sp_ptr = &(sp->next);
329 /* section not found */
330 sp = (Section *)malloc(sizeof(Section));
332 sp->name = strdup(section);
334 kvp = (KeyValue *)malloc(sizeof(KeyValue));
336 kvp->key = strdup(key);
337 kvp->value = strdup(value);
346 static const char *profile_get_value(Profile *profile, const char *section, const char *key)
351 Section *sp = profile->sections;
353 if (strcmp(section, sp->name) == 0) {
354 KeyValue *kvp = sp->pairs;
356 while (kvp != NULL) {
357 if (strcmp(key, kvp->key) == 0) {
371 static void profile_save(Profile *profile, const char *file)
375 char tmp[MAX_PATH] = "";
376 char tmp2[MAX_PATH] = "";
381 fp = cfopen(file, "wt", CFILE_NORMAL, CF_TYPE_ROOT);
385 Section *sp = profile->sections;
387 sprintf(tmp, NOX("[%s]\n"), sp->name);
390 KeyValue *kvp = sp->pairs;
391 while (kvp != NULL) {
392 sprintf(tmp2, NOX("%s=%s\n"), kvp->key, kvp->value);
397 cfwrite_char('\n', fp);
405 static char tmp_string_data[1024];
407 const char *os_config_read_string(const char *section, const char *name, const char *default_value)
409 Profile *p = profile_read(PROFILE_NAME);
412 section = DEFAULT_SECTION;
414 const char *ptr = profile_get_value(p, section, name);
416 strncpy(tmp_string_data, ptr, 1023);
417 default_value = tmp_string_data;
422 return default_value;
425 unsigned int os_config_read_uint(const char *section, const char *name, unsigned int default_value)
427 Profile *p = profile_read(PROFILE_NAME);
430 section = DEFAULT_SECTION;
432 const char *ptr = profile_get_value(p, section, name);
434 default_value = atoi(ptr);
439 return default_value;
442 void os_config_write_string(const char *section, const char *name, const char *value)
444 Profile *p = profile_read(PROFILE_NAME);
447 section = DEFAULT_SECTION;
449 p = profile_update(p, section, name, value);
450 profile_save(p, PROFILE_NAME);
454 void os_config_write_uint(const char *section, const char *name, unsigned int value)
458 snprintf(buf, 20, "%u", value);
460 Profile *p = profile_read(PROFILE_NAME);
463 section = DEFAULT_SECTION;
465 p = profile_update(p, section, name, buf);
466 profile_save(p, PROFILE_NAME);