diff -r 1c859f572d72 -r 240620f46dd7 project_files/frontlib/model/cfg.c --- a/project_files/frontlib/model/cfg.c Tue Jun 12 21:10:11 2012 +0200 +++ b/project_files/frontlib/model/cfg.c Fri Jun 15 19:57:25 2012 +0200 @@ -3,96 +3,25 @@ #include "../util/inihelper.h" #include "../util/logging.h" #include "../util/util.h" +#include "../util/refcounter.h" #include #include - -static flib_cfg_meta *flib_cfg_meta_from_ini_handleError(flib_cfg_meta *result, flib_ini *settingfile, flib_ini *modfile) { - flib_cfg_meta_destroy(result); - flib_ini_destroy(settingfile); - flib_ini_destroy(modfile); - return NULL; -} - -flib_cfg_meta *flib_cfg_meta_from_ini(const char *settingpath, const char *modpath) { - if(!settingpath || !modpath) { - flib_log_e("null parameter in flib_cfg_meta_from_ini"); - return NULL; - } - flib_cfg_meta *result = flib_calloc(1, sizeof(flib_cfg_meta)); - flib_ini *settingfile = flib_ini_load(settingpath); - flib_ini *modfile = flib_ini_load(modpath); - - if(!result || !settingfile || !modfile) { - return flib_cfg_meta_from_ini_handleError(result, settingfile, modfile); - } - - result->settingCount = flib_ini_get_sectioncount(settingfile); - result->modCount = flib_ini_get_sectioncount(modfile); - result->settings = flib_calloc(result->settingCount, sizeof(flib_cfg_setting_meta)); - result->mods = flib_calloc(result->modCount, sizeof(flib_cfg_mod_meta)); - - if(!result->settings || !result->mods) { - return flib_cfg_meta_from_ini_handleError(result, settingfile, modfile); - } - - for(int i=0; isettingCount; i++) { - result->settings[i].iniName = flib_ini_get_sectionname(settingfile, i); - if(!result->settings[i].iniName) { - return flib_cfg_meta_from_ini_handleError(result, settingfile, modfile); - } +#include +#include - bool error = false; - error |= flib_ini_enter_section(settingfile, result->settings[i].iniName); - error |= flib_ini_get_str(settingfile, &result->settings[i].title, "title"); - error |= flib_ini_get_str(settingfile, &result->settings[i].engineCommand, "command"); - error |= flib_ini_get_str(settingfile, &result->settings[i].image, "image"); - error |= flib_ini_get_bool(settingfile, &result->settings[i].checkOverMax, "checkOverMax"); - error |= flib_ini_get_bool(settingfile, &result->settings[i].times1000, "times1000"); - error |= flib_ini_get_int(settingfile, &result->settings[i].min, "min"); - error |= flib_ini_get_int(settingfile, &result->settings[i].max, "max"); - error |= flib_ini_get_int(settingfile, &result->settings[i].def, "default"); - - if(error) { - flib_log_e("Missing or malformed ini parameter in file %s, section %s", settingpath, result->settings[i].iniName); - return flib_cfg_meta_from_ini_handleError(result, settingfile, modfile); - } - } - - for(int i=0; imodCount; i++) { - result->mods[i].iniName = flib_ini_get_sectionname(modfile, i); - if(!result->mods[i].iniName) { - return flib_cfg_meta_from_ini_handleError(result, settingfile, modfile); - } - - bool error = false; - error |= flib_ini_enter_section(modfile, result->mods[i].iniName); - error |= flib_ini_get_int(modfile, &result->mods[i].bitmaskIndex, "bitmaskIndex"); - if(error) { - flib_log_e("Missing or malformed ini parameter in file %s, section %s", modpath, result->mods[i].iniName); - return flib_cfg_meta_from_ini_handleError(result, settingfile, modfile); - } - } - - flib_ini_destroy(settingfile); - flib_ini_destroy(modfile); - return result; -} - -void flib_cfg_meta_destroy(flib_cfg_meta *cfg) { +static void flib_cfg_meta_destroy(flib_cfg_meta *cfg) { if(cfg) { if(cfg->settings) { for(int i=0; isettingCount; i++) { - free(cfg->settings[i].iniName); - free(cfg->settings[i].title); + free(cfg->settings[i].name); free(cfg->settings[i].engineCommand); - free(cfg->settings[i].image); } free(cfg->settings); } if(cfg->mods) { for(int i=0; imodCount; i++) { - free(cfg->mods[i].iniName); + free(cfg->mods[i].name); } free(cfg->mods); } @@ -100,15 +29,132 @@ } } -flib_cfg *flib_cfg_create(const flib_cfg_meta *meta, const char *schemeName) { - flib_cfg *result = flib_calloc(1, sizeof(flib_cfg)); +static void flib_cfg_destroy(flib_cfg* cfg) { + if(cfg) { + flib_cfg_meta_release(cfg->meta); + free(cfg->mods); + free(cfg->settings); + free(cfg->schemeName); + free(cfg); + } +} + +static flib_cfg_meta *flib_cfg_meta_from_ini_handleError(flib_cfg_meta *result, flib_ini *ini) { + flib_cfg_meta_destroy(result); + flib_ini_destroy(ini); + return NULL; +} + +static int readMetaSettingSections(flib_ini *ini, flib_cfg_meta *result, int limit) { + while(result->settingCountsettingCount) <= 0) { + return -1; + } + if(!flib_ini_enter_section(ini, sectionName)) { + flib_cfg_setting_meta *metasetting = &result->settings[result->settingCount]; + result->settingCount++; + + bool error = false; + error |= flib_ini_get_str(ini, &metasetting->name, "name"); + error |= flib_ini_get_str_opt(ini, &metasetting->engineCommand, "command", NULL); + error |= flib_ini_get_bool(ini, &metasetting->times1000, "times1000"); + error |= flib_ini_get_bool(ini, &metasetting->maxMeansInfinity, "maxmeansinfinity"); + error |= flib_ini_get_int(ini, &metasetting->min, "min"); + error |= flib_ini_get_int(ini, &metasetting->max, "max"); + error |= flib_ini_get_int(ini, &metasetting->def, "default"); + if(error) { + flib_log_e("Missing or malformed ini parameter in metaconfig, section %s", sectionName); + return -1; + } + } else { + return 0; + } + } + return 0; +} + +static int readMetaModSections(flib_ini *ini, flib_cfg_meta *result, int limit) { + while(result->modCountmodCount) <= 0) { + return -1; + } + if(!flib_ini_enter_section(ini, sectionName)) { + flib_cfg_mod_meta *metamod = &result->mods[result->modCount]; + result->modCount++; + + bool error = false; + error |= flib_ini_get_str(ini, &metamod->name, "name"); + error |= flib_ini_get_int(ini, &metamod->bitmaskIndex, "bitmaskIndex"); + if(error) { + flib_log_e("Missing or malformed ini parameter in metaconfig, section %s", sectionName); + return -1; + } + } else { + return 0; + } + } + return 0; +} + +flib_cfg_meta *flib_cfg_meta_from_ini(const char *filename) { + if(!filename) { + flib_log_e("null parameter in flib_cfg_meta_from_ini"); + return NULL; + } + flib_cfg_meta *result = flib_cfg_meta_retain(flib_calloc(1, sizeof(flib_cfg_meta))); + flib_ini *ini = flib_ini_load(filename); + + if(!result || !ini) { + return flib_cfg_meta_from_ini_handleError(result, ini); + } + + // We're overallocating here for simplicity + int sectionCount = flib_ini_get_sectioncount(ini); + result->settingCount = 0; + result->modCount = 0; + result->settings = flib_calloc(sectionCount, sizeof(flib_cfg_setting_meta)); + result->mods = flib_calloc(sectionCount, sizeof(flib_cfg_mod_meta)); + + if(!result->settings || !result->mods) { + return flib_cfg_meta_from_ini_handleError(result, ini); + } + + if(readMetaSettingSections(ini, result, sectionCount) || readMetaModSections(ini, result, sectionCount)) { + return flib_cfg_meta_from_ini_handleError(result, ini); + } + + if(result->settingCount+result->modCount != sectionCount) { + flib_log_e("Unknown or non-contiguous sections headers in metaconfig."); + return flib_cfg_meta_from_ini_handleError(result, ini); + } + + flib_ini_destroy(ini); + return result; +} + +flib_cfg_meta *flib_cfg_meta_retain(flib_cfg_meta *metainfo) { + if(metainfo) { + flib_retain(&metainfo->_referenceCount, "flib_cfg_meta"); + } + return metainfo; +} + +void flib_cfg_meta_release(flib_cfg_meta *cfg) { + if(cfg && flib_release(&cfg->_referenceCount, "flib_cfg_meta")) { + flib_cfg_meta_destroy(cfg); + } +} + +flib_cfg *flib_cfg_create(flib_cfg_meta *meta, const char *schemeName) { + flib_cfg *result = flib_cfg_retain(flib_calloc(1, sizeof(flib_cfg))); if(!meta || !result || !schemeName) { flib_log_e("null parameter in flib_cfg_create"); return NULL; } - result->modCount = meta->modCount; - result->settingCount = meta->settingCount; + result->meta = flib_cfg_meta_retain(meta); result->schemeName = flib_strdupnull(schemeName); result->mods = flib_calloc(meta->modCount, sizeof(*result->mods)); result->settings = flib_calloc(meta->settingCount, sizeof(*result->settings)); @@ -124,103 +170,27 @@ return result; } -flib_cfg *flib_cfg_from_ini_handleError(flib_cfg *result, flib_ini *settingfile) { - flib_ini_destroy(settingfile); - flib_cfg_destroy(result); - return NULL; -} - -flib_cfg *flib_cfg_from_ini(const flib_cfg_meta *meta, const char *filename) { - if(!meta || !filename) { - flib_log_e("null parameter in flib_cfg_from_ini"); - return NULL; - } - flib_ini *settingfile = flib_ini_load(filename); - if(!settingfile) { - return NULL; - } - - char *schemename = NULL; - if(flib_ini_enter_section(settingfile, "Scheme")) { - flib_log_e("Missing section \"Scheme\" in config file %s.", filename); - return flib_cfg_from_ini_handleError(NULL, settingfile); - } - if(flib_ini_get_str(settingfile, &schemename, "name")) { - flib_log_e("Missing scheme name in config file %s.", filename); - return flib_cfg_from_ini_handleError(NULL, settingfile); - } - - flib_cfg *result = flib_cfg_create(meta, schemename); - - if(flib_ini_enter_section(settingfile, "BasicSettings")) { - flib_log_w("Missing section \"BasicSettings\" in config file %s, using defaults.", filename); - } else { - for(int i=0; isettingCount; i++) { - if(flib_ini_get_int_opt(settingfile, &result->settings[i], meta->settings[i].iniName, meta->settings[i].def)) { - flib_log_e("Error reading BasicSetting %s in config file %s.", meta->settings[i].iniName, filename); - return flib_cfg_from_ini_handleError(result, settingfile); - } +flib_cfg *flib_cfg_copy(flib_cfg *cfg) { + flib_cfg *result = NULL; + if(cfg) { + result = flib_cfg_create(cfg->meta, cfg->schemeName); + if(result) { + memcpy(result->mods, cfg->mods, cfg->meta->modCount * sizeof(*cfg->mods)); + memcpy(result->settings, cfg->settings, cfg->meta->settingCount * sizeof(*cfg->settings)); } } - - if(flib_ini_enter_section(settingfile, "GameMods")) { - flib_log_w("Missing section \"GameMods\" in config file %s, using defaults.", filename); - } else { - for(int i=0; imodCount; i++) { - if(flib_ini_get_bool_opt(settingfile, &result->mods[i], meta->mods[i].iniName, false)) { - flib_log_e("Error reading GameMod %s in config file %s.", meta->mods[i].iniName, filename); - return flib_cfg_from_ini_handleError(result, settingfile); - } - } - } - flib_ini_destroy(settingfile); - return result; -} - -int flib_cfg_to_ini(const flib_cfg_meta *meta, const char *filename, const flib_cfg *config) { - int result = -1; - if(!meta || !filename || !config || config->modCount!=meta->modCount || config->settingCount!=meta->settingCount) { - flib_log_e("Invalid parameter in flib_cfg_to_ini"); - } else { - flib_ini *ini = flib_ini_create(filename); - if(ini) { - bool error = false; - - // Add the values - error |= flib_ini_create_section(ini, "Scheme"); - if(!error) { - error |= flib_ini_set_str(ini, "name", config->schemeName); - } - - - error |= flib_ini_create_section(ini, "BasicSettings"); - if(!error) { - for(int i=0; isettingCount; i++) { - error |= flib_ini_set_int(ini, meta->settings[i].iniName, config->settings[i]); - } - } - - error |= flib_ini_create_section(ini, "GameMods"); - if(!error) { - for(int i=0; imodCount; i++) { - error |= flib_ini_set_bool(ini, meta->mods[i].iniName, config->mods[i]); - } - } - - if(!error) { - result = flib_ini_save(ini, filename); - } - } - flib_ini_destroy(ini); - } return result; } -void flib_cfg_destroy(flib_cfg* cfg) { +flib_cfg *flib_cfg_retain(flib_cfg *cfg) { if(cfg) { - free(cfg->mods); - free(cfg->settings); - free(cfg->schemeName); - free(cfg); + flib_retain(&cfg->_referenceCount, "flib_cfg"); + } + return cfg; +} + +void flib_cfg_release(flib_cfg *cfg) { + if(cfg && flib_release(&cfg->_referenceCount, "flib_cfg")) { + flib_cfg_destroy(cfg); } }