3 * Basically the same as osregistry.cpp but without having to be tied into
6 * External function calls should remain identical to what's in core lib so that
7 * the launcher can just include osregistry.h like elsewhere
12 #include "osregistry.h"
21 const char *Osreg_company_name = "Volition";
23 const char *Osreg_class_name = "FreeSpaceClass";
25 const char *Osreg_class_name = "FreeSpace2Class";
28 const char *Osreg_app_name = "FreeSpaceDemo";
29 const char *Osreg_title = "FreeSpace Demo";
30 #define PROFILE_NAME "FreeSpaceDemo.ini"
31 #elif defined(FS2_DEMO)
32 const char *Osreg_app_name = "FreeSpace2Demo";
33 const char *Osreg_title = "FreeSpace 2 Demo";
34 #define PROFILE_NAME "FreeSpace2Demo.ini"
35 #elif defined(OEM_BUILD)
36 const char *Osreg_app_name = "FreeSpace2OEM";
37 const char *Osreg_title = "FreeSpace 2 OEM";
38 #define PROFILE_NAME "FreeSpace2OEM.ini"
39 #elif defined(MAKE_FS1)
40 const char *Osreg_app_name = "FreeSpace";
41 const char *Osreg_title = "FreeSpace";
42 #define PROFILE_NAME "FreeSpace.ini"
44 const char *Osreg_app_name = "FreeSpace2";
45 const char *Osreg_title = "FreeSpace 2";
46 #define PROFILE_NAME "FreeSpace2.ini"
49 #define DEFAULT_SECTION "Default"
51 static int Profile_initted = 0;
52 static char PROFILE_PATH[MAX_PATH_LEN] = { 0 };
55 typedef struct KeyValue
60 struct KeyValue *next;
63 typedef struct Section
67 struct KeyValue *pairs;
71 typedef struct Profile
73 struct Section *sections;
76 static int profile_init()
78 if (Profile_initted) {
82 char *u_path = SDL_GetPrefPath(Osreg_company_name, Osreg_app_name);
84 // make sure we have something
90 if ( (strlen(u_path) + strlen(PROFILE_NAME) + 1) >= MAX_PATH_LEN ) {
95 // set profile location
96 SDL_snprintf(PROFILE_PATH, SDL_arraysize(PROFILE_PATH), "%s%s%s", u_path, DIR_SEPARATOR_STR, PROFILE_NAME);
106 static char *read_line_from_file(FILE *fp)
108 char *buf, *buf_start;
109 int buflen, len, eol;
112 buf = (char *)SDL_malloc(buflen);
121 if (fgets(buf_start, 80, fp) == NULL) {
122 if (buf_start == buf) {
131 len = SDL_strlen(buf_start);
133 if (buf_start[len-1] == '\n') {
134 buf_start[len-1] = 0;
139 buf = (char *)SDL_realloc(buf, buflen);
141 /* be sure to skip over the proper amount of nulls */
142 buf_start = buf+(buflen-80)-(buflen/80)+1;
149 static char *trim_string(char *str)
157 /* kill any comment */
158 ptr = SDL_strchr(str, ';');
161 ptr = SDL_strchr(str, '#');
166 len = SDL_strlen(str);
171 while ((ptr > str) && SDL_isspace(*ptr)) {
181 while (*ptr && SDL_isspace(*ptr)) {
188 static Profile *profile_read()
190 if ( profile_init() ) {
194 FILE *fp = fopen(PROFILE_PATH, "rt");
198 Profile *profile = (Profile *)SDL_malloc(sizeof(Profile));
199 profile->sections = NULL;
201 Section **sp_ptr = &(profile->sections);
204 KeyValue **kvp_ptr = NULL;
207 while ((str = read_line_from_file(fp)) != NULL) {
208 char *ptr = trim_string(str);
213 char *pend = SDL_strchr(ptr, ']');
215 // if (pend[1]) { /* trailing garbage! */ }
220 sp = (Section *)SDL_malloc(sizeof(Section));
223 sp->name = SDL_strdup(ptr);
227 sp_ptr = &(sp->next);
229 kvp_ptr = &(sp->pairs);
230 } // else { /* null name! */ }
231 } // else { /* incomplete section name! */ }
237 ptr = SDL_strchr(ptr, '=');
243 } // else { /* random garbage! */ }
245 if (key && *key && value /* && *value */) {
247 KeyValue *kvp = (KeyValue *)SDL_malloc(sizeof(KeyValue));
249 kvp->key = SDL_strdup(key);
250 kvp->value = SDL_strdup(value);
255 kvp_ptr = &(kvp->next);
256 } // else { /* key/value with no section! */
257 } // else { /* malformed key/value entry! */ }
258 } // else it's just a comment or empty string
269 static void profile_free(Profile *profile)
274 Section *sp = profile->sections;
277 KeyValue *kvp = sp->pairs;
279 while (kvp != NULL) {
283 SDL_free(kvp->value);
298 static Profile *profile_update(Profile *profile, const char *section, const char *key, const char *value)
300 if (profile == NULL) {
301 profile = (Profile *)SDL_malloc(sizeof(Profile));
303 profile->sections = NULL;
308 Section **sp_ptr = &(profile->sections);
309 Section *sp = profile->sections;
311 if (SDL_strcmp(section, sp->name) == 0) {
312 KeyValue **kvp_ptr = &(sp->pairs);
315 while (kvp != NULL) {
316 if (SDL_strcmp(key, kvp->key) == 0) {
317 SDL_free(kvp->value);
320 *kvp_ptr = kvp->next;
325 kvp->value = SDL_strdup(value);
332 kvp_ptr = &(kvp->next);
338 kvp = (KeyValue *)SDL_malloc(sizeof(KeyValue));
340 kvp->key = SDL_strdup(key);
341 kvp->value = SDL_strdup(value);
350 sp_ptr = &(sp->next);
354 /* section not found */
355 sp = (Section *)SDL_malloc(sizeof(Section));
357 sp->name = SDL_strdup(section);
359 kvp = (KeyValue *)SDL_malloc(sizeof(KeyValue));
361 kvp->key = SDL_strdup(key);
362 kvp->value = SDL_strdup(value);
371 static const char *profile_get_value(Profile *profile, const char *section, const char *key)
376 Section *sp = profile->sections;
378 if (SDL_strcmp(section, sp->name) == 0) {
379 KeyValue *kvp = sp->pairs;
381 while (kvp != NULL) {
382 if (SDL_strcmp(key, kvp->key) == 0) {
396 static char tmp_string_data[1024];
398 static void profile_save(Profile *profile)
405 if ( profile_init() ) {
409 fp = fopen(PROFILE_PATH, "wt");
413 Section *sp = profile->sections;
415 SDL_snprintf(tmp_string_data, SDL_arraysize(tmp_string_data), "[%s]\n", sp->name);
416 fputs(tmp_string_data, fp);
418 KeyValue *kvp = sp->pairs;
419 while (kvp != NULL) {
420 SDL_snprintf(tmp_string_data, SDL_arraysize(tmp_string_data), "%s=%s\n", kvp->key, kvp->value);
421 fputs(tmp_string_data, fp);
433 const char *os_config_read_string(const char *section, const char *name, const char *default_value)
435 Profile *p = profile_read();
438 section = DEFAULT_SECTION;
440 const char *ptr = profile_get_value(p, section, name);
441 if ( (ptr != NULL) && SDL_strlen(ptr) ) {
442 SDL_strlcpy(tmp_string_data, ptr, SDL_arraysize(tmp_string_data));
443 default_value = tmp_string_data;
448 return default_value;
451 unsigned int os_config_read_uint(const char *section, const char *name, unsigned int default_value)
453 Profile *p = profile_read();
456 section = DEFAULT_SECTION;
458 const char *ptr = profile_get_value(p, section, name);
459 if ( (ptr != NULL) && SDL_strlen(ptr) ) {
460 default_value = SDL_atoi(ptr);
465 return default_value;
468 void os_config_write_string(const char *section, const char *name, const char *value)
470 Profile *p = profile_read();
473 section = DEFAULT_SECTION;
475 p = profile_update(p, section, name, value);
480 void os_config_write_uint(const char *section, const char *name, unsigned int value)
484 SDL_snprintf(buf, SDL_arraysize(buf), "%u", value);
486 Profile *p = profile_read();
489 section = DEFAULT_SECTION;
491 p = profile_update(p, section, name, buf);