diff -r 4feced261c68 -r de822cd3df3a project_files/frontlib/util/inihelper.c --- a/project_files/frontlib/util/inihelper.c Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/frontlib/util/inihelper.c Tue Jan 21 22:43:06 2014 +0100 @@ -1,321 +1,321 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "inihelper.h" -#include "../iniparser/dictionary.h" -#include "../iniparser/iniparser.h" - -#include "logging.h" -#include "util.h" - -#include -#include -#include -#include -#include -#include - -struct _flib_ini { - dictionary *inidict; - char *currentSection; -}; - -static char *createDictKey(const char *sectionName, const char *keyName) { - return flib_asprintf("%s:%s", sectionName, keyName); -} - -/** - * Turns a string into a lowercase string, in-place. - */ -static void strToLower(char *str) { - if(str) { - while(*str) { - *str = tolower(*str); - str++; - } - } -} - -flib_ini *flib_ini_create(const char *filename) { - flib_ini *result = NULL; - flib_ini *tmpIni = flib_calloc(1, sizeof(flib_ini)); - if(tmpIni) { - if(filename) { - tmpIni->inidict = iniparser_load(filename); - } - if(!tmpIni->inidict) { - tmpIni->inidict = dictionary_new(0); - } - if(tmpIni->inidict) { - result = tmpIni; - tmpIni = NULL; - } - } - flib_ini_destroy(tmpIni); - return result; -} - -flib_ini *flib_ini_load(const char *filename) { - flib_ini *result = NULL; - if(!log_badargs_if(filename==NULL)) { - flib_ini *tmpIni = flib_calloc(1, sizeof(flib_ini)); - if(tmpIni) { - tmpIni->inidict = iniparser_load(filename); - if(tmpIni->inidict) { - result = tmpIni; - tmpIni = NULL; - } - } - flib_ini_destroy(tmpIni); - } - return result; -} - -int flib_ini_save(flib_ini *ini, const char *filename) { - int result = INI_ERROR_OTHER; - if(!log_badargs_if2(ini==NULL, filename==NULL)) { - FILE *file = fopen(filename, "wb"); - if(!file) { - flib_log_e("Error opening file \"%s\" for writing.", filename); - } else { - iniparser_dump_ini(ini->inidict, file); - if(fclose(file)) { - flib_log_e("Write error on ini file \"%s\"", filename); - } else { - result = 0; - } - } - } - return result; -} - -void flib_ini_destroy(flib_ini *ini) { - if(ini) { - if(ini->inidict) { - iniparser_freedict(ini->inidict); - } - free(ini->currentSection); - free(ini); - } -} - -int flib_ini_enter_section(flib_ini *ini, const char *section) { - int result = INI_ERROR_OTHER; - if(ini) { - free(ini->currentSection); - ini->currentSection = NULL; - } - if(!log_badargs_if2(ini==NULL, section==NULL)) { - if(!iniparser_find_entry(ini->inidict, section)) { - flib_log_d("Ini section %s not found", section); - result = INI_ERROR_NOTFOUND; - } else { - ini->currentSection = flib_strdupnull(section); - if(ini->currentSection) { - // Usually iniparser ignores case, but some section-handling functions don't, - // so we set it to lowercase manually - strToLower(ini->currentSection); - result = 0; - } - } - } - return result; -} - -int flib_ini_create_section(flib_ini *ini, const char *section) { - int result = INI_ERROR_OTHER; - if(!log_badargs_if2(ini==NULL, section==NULL)) { - result = flib_ini_enter_section(ini, section); - if(result == INI_ERROR_NOTFOUND) { - if(iniparser_set(ini->inidict, section, NULL)) { - flib_log_e("Error creating ini section %s", section); - result = INI_ERROR_OTHER; - } else { - result = flib_ini_enter_section(ini, section); - } - } - } - return result; -} - -/** - * The result is an internal string of the iniparser, don't free it. - */ -static char *findValue(dictionary *dict, const char *section, const char *key) { - char *result = NULL; - char *dictKey = createDictKey(section, key); - if(dictKey) { - result = iniparser_getstring(dict, dictKey, NULL); - } - free(dictKey); - return result; -} - -int flib_ini_get_str(flib_ini *ini, char **outVar, const char *key) { - char *tmpValue = NULL; - int result = flib_ini_get_str_opt(ini, &tmpValue, key, NULL); - if(result==0) { - if(tmpValue == NULL) { - result = INI_ERROR_NOTFOUND; - } else { - *outVar = tmpValue; - tmpValue = NULL; - } - } - free(tmpValue); - return result; -} - -int flib_ini_get_str_opt(flib_ini *ini, char **outVar, const char *key, const char *def) { - int result = INI_ERROR_OTHER; - if(!log_badargs_if4(ini==NULL, ini->currentSection==NULL, outVar==NULL, key==NULL)) { - const char *value = findValue(ini->inidict, ini->currentSection, key); - if(!value) { - value = def; - } - char *valueDup = flib_strdupnull(value); - if(valueDup || !def) { - *outVar = valueDup; - result = 0; - } - } - return result; -} - -int flib_ini_get_int(flib_ini *ini, int *outVar, const char *key) { - char *tmpValue = NULL; - int result = flib_ini_get_str(ini, &tmpValue, key); - if(result==0) { - errno = 0; - long val = strtol(tmpValue, NULL, 10); - if(errno!=0 || valINT_MAX) { - flib_log_w("Cannot parse ini setting %s/%s = \"%s\" as integer.", ini->currentSection, key, tmpValue); - result = INI_ERROR_FORMAT; - } else { - *outVar = val; - } - } - free(tmpValue); - return result; -} - -int flib_ini_get_int_opt(flib_ini *ini, int *outVar, const char *key, int def) { - int tmpValue; - int result = flib_ini_get_int(ini, &tmpValue, key); - if(result == 0) { - *outVar = tmpValue; - } else if(result == INI_ERROR_NOTFOUND || result == INI_ERROR_FORMAT) { - *outVar = def; - result = 0; - } - return result; -} - -int flib_ini_get_bool(flib_ini *ini, bool *outVar, const char *key) { - char *tmpValue = NULL; - int result = flib_ini_get_str(ini, &tmpValue, key); - if(result==0) { - bool trueval = strchr("1tTyY", tmpValue[0]); - bool falseval = strchr("0fFnN", tmpValue[0]); - if(!trueval && !falseval) { - flib_log_w("ini setting %s/%s = \"%s\" is not a recognized truth value.", ini->currentSection, key, tmpValue); - result = INI_ERROR_FORMAT; - } else { - *outVar = trueval; - } - } - free(tmpValue); - return result; -} - -int flib_ini_get_bool_opt(flib_ini *ini, bool *outVar, const char *key, bool def) { - bool tmpValue; - int result = flib_ini_get_bool(ini, &tmpValue, key); - if(result == 0) { - *outVar = tmpValue; - } else if(result == INI_ERROR_NOTFOUND || result == INI_ERROR_FORMAT) { - *outVar = def; - result = 0; - } - return result; -} - -int flib_ini_set_str(flib_ini *ini, const char *key, const char *value) { - int result = INI_ERROR_OTHER; - if(!log_badargs_if4(ini==NULL, ini->currentSection==NULL, key==NULL, value==NULL)) { - char *dictKey = createDictKey(ini->currentSection, key); - if(dictKey) { - result = iniparser_set(ini->inidict, dictKey, value); - if(result) { - flib_log_e("Error setting ini entry %s to %s", dictKey, value); - } - } - free(dictKey); - } - return result; -} - -int flib_ini_set_int(flib_ini *ini, const char *key, int value) { - int result = INI_ERROR_OTHER; - char *strvalue = flib_asprintf("%i", value); - if(strvalue) { - result = flib_ini_set_str(ini, key, strvalue); - } - free(strvalue); - return result; -} - -int flib_ini_set_bool(flib_ini *ini, const char *key, bool value) { - return flib_ini_set_str(ini, key, value ? "true" : "false"); -} - -int flib_ini_get_sectioncount(flib_ini *ini) { - if(!log_badargs_if(ini==NULL)) { - return iniparser_getnsec(ini->inidict); - } - return INI_ERROR_OTHER; -} - -char *flib_ini_get_sectionname(flib_ini *ini, int number) { - if(!log_badargs_if2(ini==NULL, number<0)) { - return flib_strdupnull(iniparser_getsecname(ini->inidict, number)); - } - return NULL; -} - -int flib_ini_get_keycount(flib_ini *ini) { - if(!log_badargs_if2(ini==NULL, ini->currentSection==NULL)) { - return iniparser_getsecnkeys(ini->inidict, ini->currentSection); - } - return INI_ERROR_OTHER; -} - -char *flib_ini_get_keyname(flib_ini *ini, int number) { - char *result = NULL; - if(!log_badargs_if3(ini==NULL, ini->currentSection==NULL, number<0)) { - int keyCount = iniparser_getsecnkeys(ini->inidict, ini->currentSection); - char **keys = iniparser_getseckeys(ini->inidict, ini->currentSection); - if(keys && keyCount>number) { - // The keys are in the format section:key, so we have to skip the section and colon. - result = flib_strdupnull(keys[number]+strlen(ini->currentSection)+1); - } - free(keys); - } - return result; -} +/* + * Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "inihelper.h" +#include "../iniparser/dictionary.h" +#include "../iniparser/iniparser.h" + +#include "logging.h" +#include "util.h" + +#include +#include +#include +#include +#include +#include + +struct _flib_ini { + dictionary *inidict; + char *currentSection; +}; + +static char *createDictKey(const char *sectionName, const char *keyName) { + return flib_asprintf("%s:%s", sectionName, keyName); +} + +/** + * Turns a string into a lowercase string, in-place. + */ +static void strToLower(char *str) { + if(str) { + while(*str) { + *str = tolower(*str); + str++; + } + } +} + +flib_ini *flib_ini_create(const char *filename) { + flib_ini *result = NULL; + flib_ini *tmpIni = flib_calloc(1, sizeof(flib_ini)); + if(tmpIni) { + if(filename) { + tmpIni->inidict = iniparser_load(filename); + } + if(!tmpIni->inidict) { + tmpIni->inidict = dictionary_new(0); + } + if(tmpIni->inidict) { + result = tmpIni; + tmpIni = NULL; + } + } + flib_ini_destroy(tmpIni); + return result; +} + +flib_ini *flib_ini_load(const char *filename) { + flib_ini *result = NULL; + if(!log_badargs_if(filename==NULL)) { + flib_ini *tmpIni = flib_calloc(1, sizeof(flib_ini)); + if(tmpIni) { + tmpIni->inidict = iniparser_load(filename); + if(tmpIni->inidict) { + result = tmpIni; + tmpIni = NULL; + } + } + flib_ini_destroy(tmpIni); + } + return result; +} + +int flib_ini_save(flib_ini *ini, const char *filename) { + int result = INI_ERROR_OTHER; + if(!log_badargs_if2(ini==NULL, filename==NULL)) { + FILE *file = fopen(filename, "wb"); + if(!file) { + flib_log_e("Error opening file \"%s\" for writing.", filename); + } else { + iniparser_dump_ini(ini->inidict, file); + if(fclose(file)) { + flib_log_e("Write error on ini file \"%s\"", filename); + } else { + result = 0; + } + } + } + return result; +} + +void flib_ini_destroy(flib_ini *ini) { + if(ini) { + if(ini->inidict) { + iniparser_freedict(ini->inidict); + } + free(ini->currentSection); + free(ini); + } +} + +int flib_ini_enter_section(flib_ini *ini, const char *section) { + int result = INI_ERROR_OTHER; + if(ini) { + free(ini->currentSection); + ini->currentSection = NULL; + } + if(!log_badargs_if2(ini==NULL, section==NULL)) { + if(!iniparser_find_entry(ini->inidict, section)) { + flib_log_d("Ini section %s not found", section); + result = INI_ERROR_NOTFOUND; + } else { + ini->currentSection = flib_strdupnull(section); + if(ini->currentSection) { + // Usually iniparser ignores case, but some section-handling functions don't, + // so we set it to lowercase manually + strToLower(ini->currentSection); + result = 0; + } + } + } + return result; +} + +int flib_ini_create_section(flib_ini *ini, const char *section) { + int result = INI_ERROR_OTHER; + if(!log_badargs_if2(ini==NULL, section==NULL)) { + result = flib_ini_enter_section(ini, section); + if(result == INI_ERROR_NOTFOUND) { + if(iniparser_set(ini->inidict, section, NULL)) { + flib_log_e("Error creating ini section %s", section); + result = INI_ERROR_OTHER; + } else { + result = flib_ini_enter_section(ini, section); + } + } + } + return result; +} + +/** + * The result is an internal string of the iniparser, don't free it. + */ +static char *findValue(dictionary *dict, const char *section, const char *key) { + char *result = NULL; + char *dictKey = createDictKey(section, key); + if(dictKey) { + result = iniparser_getstring(dict, dictKey, NULL); + } + free(dictKey); + return result; +} + +int flib_ini_get_str(flib_ini *ini, char **outVar, const char *key) { + char *tmpValue = NULL; + int result = flib_ini_get_str_opt(ini, &tmpValue, key, NULL); + if(result==0) { + if(tmpValue == NULL) { + result = INI_ERROR_NOTFOUND; + } else { + *outVar = tmpValue; + tmpValue = NULL; + } + } + free(tmpValue); + return result; +} + +int flib_ini_get_str_opt(flib_ini *ini, char **outVar, const char *key, const char *def) { + int result = INI_ERROR_OTHER; + if(!log_badargs_if4(ini==NULL, ini->currentSection==NULL, outVar==NULL, key==NULL)) { + const char *value = findValue(ini->inidict, ini->currentSection, key); + if(!value) { + value = def; + } + char *valueDup = flib_strdupnull(value); + if(valueDup || !def) { + *outVar = valueDup; + result = 0; + } + } + return result; +} + +int flib_ini_get_int(flib_ini *ini, int *outVar, const char *key) { + char *tmpValue = NULL; + int result = flib_ini_get_str(ini, &tmpValue, key); + if(result==0) { + errno = 0; + long val = strtol(tmpValue, NULL, 10); + if(errno!=0 || valINT_MAX) { + flib_log_w("Cannot parse ini setting %s/%s = \"%s\" as integer.", ini->currentSection, key, tmpValue); + result = INI_ERROR_FORMAT; + } else { + *outVar = val; + } + } + free(tmpValue); + return result; +} + +int flib_ini_get_int_opt(flib_ini *ini, int *outVar, const char *key, int def) { + int tmpValue; + int result = flib_ini_get_int(ini, &tmpValue, key); + if(result == 0) { + *outVar = tmpValue; + } else if(result == INI_ERROR_NOTFOUND || result == INI_ERROR_FORMAT) { + *outVar = def; + result = 0; + } + return result; +} + +int flib_ini_get_bool(flib_ini *ini, bool *outVar, const char *key) { + char *tmpValue = NULL; + int result = flib_ini_get_str(ini, &tmpValue, key); + if(result==0) { + bool trueval = strchr("1tTyY", tmpValue[0]); + bool falseval = strchr("0fFnN", tmpValue[0]); + if(!trueval && !falseval) { + flib_log_w("ini setting %s/%s = \"%s\" is not a recognized truth value.", ini->currentSection, key, tmpValue); + result = INI_ERROR_FORMAT; + } else { + *outVar = trueval; + } + } + free(tmpValue); + return result; +} + +int flib_ini_get_bool_opt(flib_ini *ini, bool *outVar, const char *key, bool def) { + bool tmpValue; + int result = flib_ini_get_bool(ini, &tmpValue, key); + if(result == 0) { + *outVar = tmpValue; + } else if(result == INI_ERROR_NOTFOUND || result == INI_ERROR_FORMAT) { + *outVar = def; + result = 0; + } + return result; +} + +int flib_ini_set_str(flib_ini *ini, const char *key, const char *value) { + int result = INI_ERROR_OTHER; + if(!log_badargs_if4(ini==NULL, ini->currentSection==NULL, key==NULL, value==NULL)) { + char *dictKey = createDictKey(ini->currentSection, key); + if(dictKey) { + result = iniparser_set(ini->inidict, dictKey, value); + if(result) { + flib_log_e("Error setting ini entry %s to %s", dictKey, value); + } + } + free(dictKey); + } + return result; +} + +int flib_ini_set_int(flib_ini *ini, const char *key, int value) { + int result = INI_ERROR_OTHER; + char *strvalue = flib_asprintf("%i", value); + if(strvalue) { + result = flib_ini_set_str(ini, key, strvalue); + } + free(strvalue); + return result; +} + +int flib_ini_set_bool(flib_ini *ini, const char *key, bool value) { + return flib_ini_set_str(ini, key, value ? "true" : "false"); +} + +int flib_ini_get_sectioncount(flib_ini *ini) { + if(!log_badargs_if(ini==NULL)) { + return iniparser_getnsec(ini->inidict); + } + return INI_ERROR_OTHER; +} + +char *flib_ini_get_sectionname(flib_ini *ini, int number) { + if(!log_badargs_if2(ini==NULL, number<0)) { + return flib_strdupnull(iniparser_getsecname(ini->inidict, number)); + } + return NULL; +} + +int flib_ini_get_keycount(flib_ini *ini) { + if(!log_badargs_if2(ini==NULL, ini->currentSection==NULL)) { + return iniparser_getsecnkeys(ini->inidict, ini->currentSection); + } + return INI_ERROR_OTHER; +} + +char *flib_ini_get_keyname(flib_ini *ini, int number) { + char *result = NULL; + if(!log_badargs_if3(ini==NULL, ini->currentSection==NULL, number<0)) { + int keyCount = iniparser_getsecnkeys(ini->inidict, ini->currentSection); + char **keys = iniparser_getseckeys(ini->inidict, ini->currentSection); + if(keys && keyCount>number) { + // The keys are in the format section:key, so we have to skip the section and colon. + result = flib_strdupnull(keys[number]+strlen(ini->currentSection)+1); + } + free(keys); + } + return result; +}