#include <stdio.h> #include <stdlib.h> #include <string.h> #include "forge.h" typedef enum{ IMAGINE_ST_UNDEFINED, IMAGINE_ST_BOOLEAN, IMAGINE_ST_INTEGER, IMAGINE_ST_DOUBLE, IMAGINE_ST_TEXT, IMAGINE_ST_COUNT }ImagineSettingType; typedef struct{ char name[32]; ImagineSettingType type; const char *comment; union{ boolean toggle; char *text; double real; int integer; }data; }ImagineSetting; struct{ ImagineSetting *array; uint count; uint version; }ImagineGlobalSettings; #ifdef __APPLE_CC__ #include <unistd.h> #include <CoreFoundation/CoreFoundation.h> void imagine_set_working_directory() /* FUCK APPLE!!!! */ { uint i, j; CFURLRef url; char path[PATH_MAX], *dot_app = ".app"; url = CFBundleCopyExecutableURL(CFBundleGetMainBundle()); if(CFURLGetFileSystemRepresentation(url, true, (UInt8*)path, sizeof(path))) { for(i = 0; path[i] != 0; i++) { for(j = 0; path[i + j] == dot_app[j] && dot_app[j] != 0; j++); if(dot_app[j] == 0) { for(;i > 0 && path[i] != '/'; i--); path[++i] = 0; printf("Set operating directory = %s\n", path); chdir(path); break; } } } CFRelease(url); } #endif static void init_setting(void) { static boolean init = FALSE; if(init) return; init = TRUE; #ifdef __APPLE_CC__ imagine_set_working_directory(); #endif ImagineGlobalSettings.array = malloc((sizeof *ImagineGlobalSettings.array) * 128); ImagineGlobalSettings.count = 0; ImagineGlobalSettings.version = 345; } static ImagineSetting * imagine_add_setting(const char *name, const char *comment) { ImagineSetting *s = NULL; uint i, j; init_setting(); for(i = 0; i < ImagineGlobalSettings.count; i++) { for(j = 0; ImagineGlobalSettings.array[i].name[j] == name[j] && name[j] != 0; j++); if(ImagineGlobalSettings.array[i].name[j] == name[j]) { s = &ImagineGlobalSettings.array[i]; if(s->type == IMAGINE_ST_UNDEFINED || s->type == IMAGINE_ST_TEXT) free(s->data.text); break; } } if(s == NULL) { if(ImagineGlobalSettings.count % 64 == 0) ImagineGlobalSettings.array = realloc(ImagineGlobalSettings.array, (sizeof *ImagineGlobalSettings.array) * (ImagineGlobalSettings.count + 64)); s = &ImagineGlobalSettings.array[ImagineGlobalSettings.count++]; for(i = 0; i < 31 && name[i] != 0; i++) s->name[i] = name[i]; s->name[i] = 0; } s->comment = comment; s->type = IMAGINE_ST_UNDEFINED; s->data.integer = 1; return s; } static ImagineSetting * imagine_setting_get(const char *name) { uint i; init_setting(); for(i = 0; i < ImagineGlobalSettings.count; i++) if(strcmp(ImagineGlobalSettings.array[i].name, name) == 0) return &ImagineGlobalSettings.array[i]; return NULL; } boolean imagine_setting_boolean_get(const char *setting, boolean default_value, const char *comment) { ImagineSetting *s; char *text; uint i; init_setting(); s = imagine_setting_get(setting); if(s == NULL) { s = imagine_add_setting(setting, comment); s->data.toggle = default_value; s->type = IMAGINE_ST_BOOLEAN; }else if(s->type != IMAGINE_ST_BOOLEAN) { text = s->data.text; s->data.toggle = default_value; for(i = 0; text[i] != 0 && text[i] <= 32; i++); if(text[i] != 0) { if(text[i] == 'T' || text[i] == 't') s->data.toggle = TRUE; if(text[i] == 'F' || text[i] == 'f' || (text[i] > '0' && text[i] <= '9')) s->data.toggle = FALSE; } free(text); s->type = IMAGINE_ST_BOOLEAN; } if(comment != NULL) s->comment = comment; return s->data.toggle; } void imagine_setting_boolean_set(const char *setting, boolean value, const char *comment) { ImagineSetting *s; init_setting(); s = imagine_setting_get(setting); if(s == NULL) s = imagine_add_setting(setting, comment); s->data.toggle = value; if(comment != NULL) s->comment = comment; s->type = IMAGINE_ST_BOOLEAN; } int imagine_setting_integer_get(const char *setting, int default_value, const char *comment) { ImagineSetting *s; char *text; init_setting(); s = imagine_setting_get(setting); if(s == NULL) { s = imagine_add_setting(setting, comment); s->data.integer = default_value; s->type = IMAGINE_ST_INTEGER; }else if(s->type != IMAGINE_ST_INTEGER) { text = s->data.text; s->data.integer = default_value; if(sscanf(text, "%u", &s->data.integer) == 1) free(text); s->type = IMAGINE_ST_INTEGER; } if(comment != NULL) s->comment = comment; return s->data.integer; } void imagine_setting_integer_set(const char *setting, int value, const char *comment) { ImagineSetting *s; char *text; init_setting(); s = imagine_setting_get(setting); if(s == NULL) s = imagine_add_setting(setting, comment); s->data.integer = value; s->type = IMAGINE_ST_INTEGER; if(comment != NULL) s->comment = comment; } double imagine_setting_double_get(const char *setting, double default_value, const char *comment) { ImagineSetting *s; char *text; init_setting(); s = imagine_setting_get(setting); if(s == NULL) { s = imagine_add_setting(setting, comment); s->data.real = default_value; s->type = IMAGINE_ST_DOUBLE; }else if(s->type != IMAGINE_ST_DOUBLE) { float f; text = s->data.text; s->data.real = default_value; if(sscanf(text, "%f", &f) == 1) { s->data.real = f; free(text); } s->type = IMAGINE_ST_DOUBLE; } if(comment != NULL) s->comment = comment; return s->data.real; } void imagine_setting_double_set(const char *setting, double value, const char *comment) { ImagineSetting *s; char *text; init_setting(); s = imagine_setting_get(setting); if(s == NULL) s = imagine_add_setting(setting, comment); s->data.real = value; s->type = IMAGINE_ST_DOUBLE; if(comment != NULL) s->comment = comment; } char *imagine_setting_text_get(const char *setting, char *default_text, const char *comment) { ImagineSetting *s; char *text; uint i; init_setting(); s = imagine_setting_get(setting); if(s == NULL) { s = imagine_add_setting(setting, comment); for(i = 0; default_text[i] != 0; i++); text = malloc((sizeof *text) * (i + 1)); for(i = 0; default_text[i] != 0; i++) text[i] = default_text[i]; text[i] = 0; s->data.text = text; s->type = IMAGINE_ST_TEXT; } if(comment != NULL) s->comment = comment; return s->data.text; } void imagine_setting_text_set(const char *setting, char *text, const char *comment) { ImagineSetting *s; char *t; uint i; init_setting(); s = imagine_setting_get(setting); if(s == NULL) s = imagine_add_setting(setting, comment); for(i = 0; text[i] != 0; i++); t = malloc((sizeof *t) * (i + 1)); for(i = 0; text[i] != 0; i++) t[i] = text[i]; t[i] = 0; s->data.text = t; s->type = IMAGINE_ST_TEXT; if(comment != NULL) s->comment = comment; } boolean imagine_setting_test(const char *setting) { return NULL != imagine_setting_get(setting); } void imagine_settings_save(const char *file_name) { uint i; FILE *settings; init_setting(); #ifdef __APPLE_CC__ imagine_set_working_directory(); /* FUCK APPLE!!!! */ #endif settings = fopen(file_name, "w"); if(settings == NULL) return; fprintf(settings, "<?xml version=\"1.0\"?>\n<ROOT>\n"); for(i = 0; i < ImagineGlobalSettings.count; i++) { switch(ImagineGlobalSettings.array[i].type) { case IMAGINE_ST_UNDEFINED : fprintf(settings, "\t<%s>%s</%s>", ImagineGlobalSettings.array[i].name, ImagineGlobalSettings.array[i].data.text, ImagineGlobalSettings.array[i].name); break; case IMAGINE_ST_BOOLEAN : if(ImagineGlobalSettings.array[i].data.toggle) fprintf(settings, "\t<%s>TRUE</%s>", ImagineGlobalSettings.array[i].name, ImagineGlobalSettings.array[i].name); else fprintf(settings, "\t<%s>FALSE</%s>", ImagineGlobalSettings.array[i].name, ImagineGlobalSettings.array[i].name); break; case IMAGINE_ST_INTEGER : fprintf(settings, "\t<%s>%i</%s>", ImagineGlobalSettings.array[i].name, ImagineGlobalSettings.array[i].data.integer, ImagineGlobalSettings.array[i].name); break; case IMAGINE_ST_DOUBLE : fprintf(settings, "\t<%s>%f</%s>", ImagineGlobalSettings.array[i].name, ImagineGlobalSettings.array[i].data.real, ImagineGlobalSettings.array[i].name); break; case IMAGINE_ST_TEXT : fprintf(settings, "\t<%s>%s</%s>", ImagineGlobalSettings.array[i].name, ImagineGlobalSettings.array[i].data.text, ImagineGlobalSettings.array[i].name); break; } if(ImagineGlobalSettings.array[i].comment == NULL) fprintf(settings, "\n"); else fprintf(settings, " <!-- %s -->\n", ImagineGlobalSettings.array[i].comment); } fprintf(settings, "</ROOT>\n"); fclose(settings); } boolean imagine_settings_load(const char *file_name) { char *buffer, type[256], *text; uint i, j, size; FILE *settings; ImagineSetting *s; init_setting(); if((settings = fopen(file_name, "r")) != NULL) { fseek(settings , 0, SEEK_END); size = ftell(settings) + 1; fseek(settings , 0, SEEK_SET); buffer = malloc(size + 1); fread(buffer, sizeof(char), size, settings); buffer[size] = 0; for(i = 0; buffer[i] != 0; i++) { if(buffer[i] == '<') { i++; if(buffer[i] != '/' && buffer[i] != '!') { for(j = 0; buffer[i] != 0 && buffer[i] != '>'; i++) type[j++] = buffer[i]; type[j] = 0; i++; for(j = 0; buffer[i + j] != 0 && buffer[i + j] != '<'; j++); if(buffer[i + j] != 0 && j != 0) { j++; if(buffer[i + j] == '/') { text = malloc(sizeof(char) * j); for(j = 0; buffer[i + j] != 0 && buffer[i + j] != '<'; j++) text[j] = buffer[i + j]; text[j] = 0; s = imagine_add_setting(type, NULL); s->data.text = text; } } } } } fclose(settings); free(buffer); return TRUE; } return FALSE; } void imagine_settings_test() { /* sui_setting_boolean("BOOLEAN", TRUE, "This is a switch."); sui_setting_integer("IINTEGER", 1138, "This is an integer number."); sui_setting_double("DOUBLE", 3.14, "This is a double precision floating point value."); sui_setting_text("TEXT","hello world", "This is some text.");*/ imagine_settings_load("setings.xml"); imagine_settings_save("setings2.xml"); }