mirror of
https://github.com/quelsolaar/MergeSource
synced 2025-02-01 09:58:42 -05:00
413 lines
10 KiB
C
413 lines
10 KiB
C
#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");
|
|
}
|