From 3f376a092e1c16429fb52f24736e9da98aff4cd5 Mon Sep 17 00:00:00 2001 From: sapier Date: Wed, 5 Feb 2014 01:35:40 +0100 Subject: [PATCH] Fix settings to honor numeric conversion errors Rename try* non exceptioning functions to *NoEx --- src/emerge.cpp | 16 ++++++++-------- src/exceptions.h | 5 +++++ src/main.cpp | 7 ++++--- src/mapgen_indev.cpp | 2 +- src/mapgen_v6.cpp | 6 +++--- src/mapgen_v7.cpp | 2 +- src/settings.h | 42 +++++++++++++++++++++++++++++++----------- src/util/string.h | 42 ++++++++++++++++++++++++++---------------- 8 files changed, 79 insertions(+), 43 deletions(-) diff --git a/src/emerge.cpp b/src/emerge.cpp index 42e533759..2c46b0e14 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -102,15 +102,15 @@ EmergeManager::EmergeManager(IGameDef *gamedef) { // if unspecified, leave a proc for the main thread and one for // some other misc thread int nthreads = 0; - if (!g_settings->tryGetS16("num_emerge_threads", nthreads)) + if (!g_settings->getS16NoEx("num_emerge_threads", nthreads)) nthreads = porting::getNumberOfProcessors() - 2; if (nthreads < 1) nthreads = 1; qlimit_total = g_settings->getU16("emergequeue_limit_total"); - if (!g_settings->tryGetU16("emergequeue_limit_diskonly", qlimit_diskonly)) + if (!g_settings->getU16NoEx("emergequeue_limit_diskonly", qlimit_diskonly)) qlimit_diskonly = nthreads * 5 + 1; - if (!g_settings->tryGetU16("emergequeue_limit_generate", qlimit_generate)) + if (!g_settings->getU16NoEx("emergequeue_limit_generate", qlimit_generate)) qlimit_generate = nthreads + 1; for (int i = 0; i != nthreads; i++) @@ -352,13 +352,13 @@ void EmergeManager::loadParamsFromSettings(Settings *settings) { std::string seed_str; const char *setname = (settings == g_settings) ? "fixed_map_seed" : "seed"; - if (settings->tryGet(setname, seed_str)) + if (settings->getNoEx(setname, seed_str)) params.seed = read_seed(seed_str.c_str()); - settings->tryGet("mg_name", params.mg_name); - settings->tryGetS16("water_level", params.water_level); - settings->tryGetS16("chunksize", params.chunksize); - settings->tryGetFlagStr("mg_flags", params.flags, flagdesc_mapgen); + settings->getNoEx("mg_name", params.mg_name); + settings->getS16NoEx("water_level", params.water_level); + settings->getS16NoEx("chunksize", params.chunksize); + settings->getFlagStrNoEx("mg_flags", params.flags, flagdesc_mapgen); delete params.sparams; params.sparams = createMapgenParams(params.mg_name); diff --git a/src/exceptions.h b/src/exceptions.h index 6fb97f3ed..703d6c1a5 100644 --- a/src/exceptions.h +++ b/src/exceptions.h @@ -85,6 +85,11 @@ public: SettingNotFoundException(std::string s): BaseException(s) {} }; +class NumericException : public BaseException { +public: + NumericException(std::string s): BaseException(s) {} +}; + class InvalidFilenameException : public BaseException { public: InvalidFilenameException(std::string s): BaseException(s) {} diff --git a/src/main.cpp b/src/main.cpp index 8186e26c8..c90e6fde3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1671,9 +1671,10 @@ int main(int argc, char *argv[]) //infostream<<"Main: password hash: '"<tryGetS16("mgindev_float_islands", float_islands); + settings->getS16NoEx("mgindev_float_islands", float_islands); settings->getNoiseIndevParams("mgindev_np_terrain_base", npindev_terrain_base); settings->getNoiseIndevParams("mgindev_np_terrain_higher", npindev_terrain_higher); diff --git a/src/mapgen_v6.cpp b/src/mapgen_v6.cpp index 526d4af2e..92ae7dff0 100644 --- a/src/mapgen_v6.cpp +++ b/src/mapgen_v6.cpp @@ -112,9 +112,9 @@ MapgenV6Params::MapgenV6Params() { void MapgenV6Params::readParams(Settings *settings) { - settings->tryGetFlagStr("mgv6_spflags", spflags, flagdesc_mapgen_v6); - settings->tryGetFloat("mgv6_freq_desert", freq_desert); - settings->tryGetFloat("mgv6_freq_beach", freq_beach); + settings->getFlagStrNoEx("mgv6_spflags", spflags, flagdesc_mapgen_v6); + settings->getFloatNoEx("mgv6_freq_desert", freq_desert); + settings->getFloatNoEx("mgv6_freq_beach", freq_beach); settings->getNoiseParams("mgv6_np_terrain_base", np_terrain_base); settings->getNoiseParams("mgv6_np_terrain_higher", np_terrain_higher); diff --git a/src/mapgen_v7.cpp b/src/mapgen_v7.cpp index 77e25a672..835915164 100644 --- a/src/mapgen_v7.cpp +++ b/src/mapgen_v7.cpp @@ -126,7 +126,7 @@ MapgenV7Params::MapgenV7Params() { void MapgenV7Params::readParams(Settings *settings) { - settings->tryGetFlagStr("mgv7_spflags", spflags, flagdesc_mapgen_v7); + settings->getFlagStrNoEx("mgv7_spflags", spflags, flagdesc_mapgen_v7); settings->getNoiseParams("mgv7_np_terrain_base", np_terrain_base); settings->getNoiseParams("mgv7_np_terrain_alt", np_terrain_alt); diff --git a/src/settings.h b/src/settings.h index f019ce50c..11b11e635 100644 --- a/src/settings.h +++ b/src/settings.h @@ -745,17 +745,19 @@ fail: } //////////// Try to get value, no exception thrown - bool tryGet(std::string name, std::string &val) + bool getNoEx(std::string name, std::string &val) { try { val = get(name); return true; } catch (SettingNotFoundException &e) { return false; + } catch (NumericException &e) { + return false; } } - bool tryGetFlagStr(std::string name, u32 &val, FlagDesc *flagdesc) + bool getFlagStrNoEx(std::string name, u32 &val, FlagDesc *flagdesc) { try { val = getFlagStr(name, flagdesc); @@ -765,93 +767,111 @@ fail: } } - bool tryGetFloat(std::string name, float &val) + bool getFloatNoEx(std::string name, float &val) { try { val = getFloat(name); return true; } catch (SettingNotFoundException &e) { return false; + } catch (NumericException &e) { + return false; } } - bool tryGetU16(std::string name, int &val) + bool getU16NoEx(std::string name, int &val) { try { val = getU16(name); return true; } catch (SettingNotFoundException &e) { return false; + } catch (NumericException &e) { + return false; } } - bool tryGetU16(std::string name, u16 &val) + bool getU16NoEx(std::string name, u16 &val) { try { val = getU16(name); return true; } catch (SettingNotFoundException &e) { return false; + } catch (NumericException &e) { + return false; } } - bool tryGetS16(std::string name, int &val) + bool getS16NoEx(std::string name, int &val) { try { val = getU16(name); return true; } catch (SettingNotFoundException &e) { return false; + } catch (NumericException &e) { + return false; } } - bool tryGetS16(std::string name, s16 &val) + bool getS16NoEx(std::string name, s16 &val) { try { val = getS16(name); return true; } catch (SettingNotFoundException &e) { return false; + } catch (NumericException &e) { + return false; } } - bool tryGetS32(std::string name, s32 &val) + bool getS32NoEx(std::string name, s32 &val) { try { val = getS32(name); return true; } catch (SettingNotFoundException &e) { return false; + } catch (NumericException &e) { + return false; } } - bool tryGetV3F(std::string name, v3f &val) + bool getV3FNoEx(std::string name, v3f &val) { try { val = getV3F(name); return true; } catch (SettingNotFoundException &e) { return false; + } catch (NumericException &e) { + return false; } } - bool tryGetV2F(std::string name, v2f &val) + bool getV2FNoEx(std::string name, v2f &val) { try { val = getV2F(name); return true; } catch (SettingNotFoundException &e) { return false; + } catch (NumericException &e) { + return false; } } - bool tryGetU64(std::string name, u64 &val) + bool getU64NoEx(std::string name, u64 &val) { try { val = getU64(name); return true; } catch (SettingNotFoundException &e) { return false; + } catch (NumericException &e) { + return false; } } diff --git a/src/util/string.h b/src/util/string.h index e5a60bc47..a3f84c0ea 100644 --- a/src/util/string.h +++ b/src/util/string.h @@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include +#include "exceptions.h" struct FlagDesc { const char *name; @@ -145,17 +146,31 @@ inline std::string trim(const std::string &s) return s.substr(front, back - front); } +inline s32 mystoi(const std::string &s) +{ + char* endptr = NULL; + s32 retval = strtol(s.c_str(),&endptr,10); + + if ((endptr == NULL) || (*endptr != 0) || (endptr == s.c_str())) + throw NumericException("string to convert"); + + return retval; +} + inline bool is_yes(const std::string &s) { std::string s2 = lowercase(trim(s)); - if(s2 == "y" || s2 == "yes" || s2 == "true" || atoi(s2.c_str()) != 0) - return true; + try { + if(s2 == "y" || s2 == "yes" || s2 == "true" || mystoi(s2) != 0) + return true; + } + catch(NumericException&e) {} return false; } inline s32 mystoi(const std::string &s, s32 min, s32 max) { - s32 i = atoi(s.c_str()); + s32 i = mystoi(s); if(i < min) i = min; if(i > max) @@ -173,25 +188,20 @@ inline s64 stoi64(const std::string &s) { // MSVC2010 includes it's own versions of these //#if !defined(_MSC_VER) || _MSC_VER < 1600 -inline s32 mystoi(const std::string &s) -{ - return atoi(s.c_str()); -} - inline s32 mystoi(const std::wstring &s) { - return atoi(wide_to_narrow(s).c_str()); + return mystoi(wide_to_narrow(s).c_str()); } inline float mystof(const std::string &s) { - // This crap causes a segfault in certain cases on MinGW - /*float f; - std::istringstream ss(s); - ss>>f; - return f;*/ - // This works in that case - return atof(s.c_str()); + char* endptr = NULL; + float retval = strtof(s.c_str(),&endptr); + + if ((endptr == NULL) || (*endptr != 0) || (endptr == s.c_str())) + throw NumericException("string to convert"); + + return retval; } //#endif