diff options
-rw-r--r-- | build/android/jni/Android.mk | 3 | ||||
-rw-r--r-- | src/CMakeLists.txt | 155 | ||||
-rw-r--r-- | src/client.cpp | 17 | ||||
-rw-r--r-- | src/clientiface.cpp | 7 | ||||
-rw-r--r-- | src/clientmedia.cpp | 5 | ||||
-rw-r--r-- | src/content_cao.cpp | 19 | ||||
-rw-r--r-- | src/content_mapblock.cpp | 7 | ||||
-rw-r--r-- | src/content_sao.cpp | 5 | ||||
-rw-r--r-- | src/database-leveldb.cpp | 5 | ||||
-rw-r--r-- | src/database-sqlite3.cpp | 1 | ||||
-rw-r--r-- | src/emerge.cpp | 6 | ||||
-rw-r--r-- | src/environment.cpp | 33 | ||||
-rw-r--r-- | src/guiEngine.cpp | 7 | ||||
-rw-r--r-- | src/inventorymanager.cpp | 1 | ||||
-rw-r--r-- | src/keycode.cpp | 1 | ||||
-rw-r--r-- | src/map.cpp | 30 | ||||
-rw-r--r-- | src/mapgen.cpp | 2 | ||||
-rw-r--r-- | src/mapgen.h | 4 | ||||
-rw-r--r-- | src/nodedef.cpp | 3 | ||||
-rw-r--r-- | src/player.cpp | 22 | ||||
-rw-r--r-- | src/script/lua_api/l_mapgen.cpp | 2 | ||||
-rw-r--r-- | src/script/lua_api/l_util.cpp | 3 | ||||
-rw-r--r-- | src/settings.cpp | 702 | ||||
-rw-r--r-- | src/settings.h | 836 | ||||
-rw-r--r-- | src/socket.cpp | 29 | ||||
-rw-r--r-- | src/test.cpp | 14 | ||||
-rw-r--r-- | src/tile.cpp | 12 |
27 files changed, 993 insertions, 938 deletions
diff --git a/build/android/jni/Android.mk b/build/android/jni/Android.mk index 9b2057781..96693fa4d 100644 --- a/build/android/jni/Android.mk +++ b/build/android/jni/Android.mk @@ -206,7 +206,8 @@ LOCAL_SRC_FILES := \ jni/src/util/string.cpp \ jni/src/util/timetaker.cpp \ jni/src/touchscreengui.cpp \ - jni/src/database-leveldb.cpp + jni/src/database-leveldb.cpp \ + jni/src/settings.cpp # lua api LOCAL_SRC_FILES += \ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index de1ea2c28..4c1522fac 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -333,74 +333,75 @@ add_subdirectory(script) add_subdirectory(util) set(common_SRCS - version.cpp - rollback_interface.cpp - rollback.cpp - genericobject.cpp - voxelalgorithms.cpp - sound.cpp - quicktune.cpp - subgame.cpp - inventorymanager.cpp - mods.cpp + ban.cpp + base64.cpp + biome.cpp + cavegen.cpp + clientiface.cpp + collision.cpp + connection.cpp content_abm.cpp + content_mapnode.cpp + content_nodemeta.cpp + content_sao.cpp + convert_json.cpp craftdef.cpp - nameidmapping.cpp + database-dummy.cpp + database-leveldb.cpp + database-redis.cpp + database-sqlite3.cpp + database.cpp + debug.cpp + defaultsettings.cpp + dungeongen.cpp + emerge.cpp + environment.cpp + filesys.cpp + genericobject.cpp + gettext.cpp + httpfetch.cpp + inventory.cpp + inventorymanager.cpp itemdef.cpp - nodedef.cpp - object_properties.cpp + light.cpp log.cpp - content_sao.cpp - emerge.cpp + map.cpp + mapblock.cpp mapgen.cpp + mapgen_singlenode.cpp mapgen_v6.cpp mapgen_v7.cpp - mapgen_singlenode.cpp - treegen.cpp - dungeongen.cpp - cavegen.cpp - content_nodemeta.cpp - content_mapnode.cpp - collision.cpp + mapnode.cpp + mapsector.cpp + mods.cpp + nameidmapping.cpp + nodedef.cpp nodemetadata.cpp nodetimer.cpp - serverobject.cpp noise.cpp + object_properties.cpp + pathfinder.cpp + player.cpp porting.cpp - tool.cpp - defaultsettings.cpp - mapnode.cpp - voxel.cpp - inventory.cpp - debug.cpp + quicktune.cpp + rollback.cpp + rollback_interface.cpp serialization.cpp - light.cpp - filesys.cpp - connection.cpp - environment.cpp server.cpp - clientiface.cpp - socket.cpp - mapblock.cpp - mapsector.cpp - map.cpp - database.cpp - database-dummy.cpp - database-leveldb.cpp - database-sqlite3.cpp - database-redis.cpp - player.cpp - test.cpp + serverlist.cpp + serverobject.cpp + settings.cpp sha1.cpp - base64.cpp - ban.cpp - biome.cpp + socket.cpp + sound.cpp staticobject.cpp - serverlist.cpp - pathfinder.cpp - convert_json.cpp - gettext.cpp - httpfetch.cpp + subgame.cpp + test.cpp + tool.cpp + treegen.cpp + version.cpp + voxel.cpp + voxelalgorithms.cpp ${JTHREAD_SRCS} ${common_SCRIPT_SRCS} ${UTIL_SRCS} @@ -429,38 +430,38 @@ endif() set(minetest_SRCS ${common_SRCS} ${sound_SRCS} - localplayer.cpp - sky.cpp - clientmap.cpp - content_cso.cpp - content_mapblock.cpp - content_cao.cpp - mesh.cpp - mapblock_mesh.cpp - keycode.cpp camera.cpp - clouds.cpp - particles.cpp - clientobject.cpp chat.cpp - hud.cpp - guiKeyChangeMenu.cpp - guiFormSpecMenu.cpp - guiTable.cpp - guiPasswordChange.cpp - guiVolumeChange.cpp - guiChatConsole.cpp client.cpp + clientmap.cpp clientmedia.cpp + clientobject.cpp + clouds.cpp + content_cao.cpp + content_cso.cpp + content_mapblock.cpp + convert_json.cpp + drawscene.cpp filecache.cpp - tile.cpp - shader.cpp game.cpp - main.cpp + guiChatConsole.cpp guiEngine.cpp guiFileSelectMenu.cpp - convert_json.cpp - drawscene.cpp + guiFormSpecMenu.cpp + guiKeyChangeMenu.cpp + guiPasswordChange.cpp + guiTable.cpp + guiVolumeChange.cpp + hud.cpp + keycode.cpp + localplayer.cpp + main.cpp + mapblock_mesh.cpp + mesh.cpp + particles.cpp + shader.cpp + sky.cpp + tile.cpp ${minetest_SCRIPT_SRCS} ) list(SORT minetest_SRCS) diff --git a/src/client.cpp b/src/client.cpp index accff4b01..5a276e306 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -17,13 +17,19 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "client.h" #include <iostream> #include <algorithm> -#include "clientserver.h" +#include <sstream> +#include <IFileSystem.h> #include "jthread/jmutexautolock.h" +#include "util/directiontables.h" +#include "util/pointedthing.h" +#include "util/serialize.h" +#include "util/string.h" +#include "strfnd.h" +#include "client.h" +#include "clientserver.h" #include "main.h" -#include <sstream> #include "filesys.h" #include "porting.h" #include "mapsector.h" @@ -37,18 +43,13 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "nodedef.h" #include "itemdef.h" #include "shader.h" -#include <IFileSystem.h> #include "base64.h" #include "clientmap.h" #include "clientmedia.h" #include "sound.h" -#include "util/string.h" #include "IMeshCache.h" #include "serialization.h" -#include "util/serialize.h" #include "config.h" -#include "util/directiontables.h" -#include "util/pointedthing.h" #include "version.h" #include "drawscene.h" diff --git a/src/clientiface.cpp b/src/clientiface.cpp index ebbbc65bc..cd2e2d4d9 100644 --- a/src/clientiface.cpp +++ b/src/clientiface.cpp @@ -20,6 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include <sstream> #include "clientiface.h" +#include "util/numeric.h" +#include "util/mathconstants.h" #include "player.h" #include "settings.h" #include "mapblock.h" @@ -28,11 +30,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "map.h" #include "emerge.h" #include "serverobject.h" // TODO this is used for cleanup of only - -#include "util/numeric.h" -#include "util/mathconstants.h" - #include "main.h" // for g_settings +#include "log.h" const char *ClientInterface::statenames[] = { "Invalid", diff --git a/src/clientmedia.cpp b/src/clientmedia.cpp index e2679ed46..434eeb248 100644 --- a/src/clientmedia.cpp +++ b/src/clientmedia.cpp @@ -18,10 +18,13 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "clientmedia.h" +#include "util/serialize.h" +#include "util/string.h" #include "httpfetch.h" #include "client.h" #include "clientserver.h" #include "filecache.h" +#include "filesys.h" #include "hex.h" #include "sha1.h" #include "debug.h" @@ -29,8 +32,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "porting.h" #include "settings.h" #include "main.h" -#include "util/serialize.h" -#include "util/string.h" static std::string getMediaCacheDir() { diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 02622f5b4..d1de23d2a 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -17,14 +17,20 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include <ICameraSceneNode.h> +#include <ITextSceneNode.h> +#include <IBillboardSceneNode.h> +#include <IMeshManipulator.h> +#include <IAnimatedMeshSceneNode.h> +#include <IBoneSceneNode.h> #include "content_cao.h" +#include "util/numeric.h" // For IntervalLimiter +#include "util/serialize.h" +#include "util/mathconstants.h" #include "tile.h" #include "environment.h" #include "collision.h" #include "settings.h" -#include <ICameraSceneNode.h> -#include <ITextSceneNode.h> -#include <IBillboardSceneNode.h> #include "serialization.h" // For decompressZlib #include "gamedef.h" #include "clientobject.h" @@ -36,15 +42,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "sound.h" #include "nodedef.h" #include "localplayer.h" -#include "util/numeric.h" // For IntervalLimiter -#include "util/serialize.h" -#include "util/mathconstants.h" #include "map.h" #include "main.h" // g_settings #include "camera.h" // CameraModes -#include <IMeshManipulator.h> -#include <IAnimatedMeshSceneNode.h> -#include <IBoneSceneNode.h> +#include "log.h" class Settings; struct ToolCapabilities; diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp index b7a48d57e..c94ff590e 100644 --- a/src/content_mapblock.cpp +++ b/src/content_mapblock.cpp @@ -18,15 +18,16 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "content_mapblock.h" - +#include "util/numeric.h" +#include "util/directiontables.h" #include "main.h" // For g_settings #include "mapblock_mesh.h" // For MapBlock_LightColor() and MeshCollector #include "settings.h" #include "nodedef.h" #include "tile.h" #include "gamedef.h" -#include "util/numeric.h" -#include "util/directiontables.h" +#include "log.h" + // Create a cuboid. // collector - the MeshCollector for the resulting polygons diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 4ee92f4d3..40313f7a5 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -18,6 +18,8 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "content_sao.h" +#include "util/serialize.h" +#include "util/mathconstants.h" #include "collision.h" #include "environment.h" #include "settings.h" @@ -29,8 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "player.h" #include "scripting_game.h" #include "genericobject.h" -#include "util/serialize.h" -#include "util/mathconstants.h" +#include "log.h" std::map<u16, ServerActiveObject::Factory> ServerActiveObject::m_types; diff --git a/src/database-leveldb.cpp b/src/database-leveldb.cpp index d57462be9..1681b0195 100644 --- a/src/database-leveldb.cpp +++ b/src/database-leveldb.cpp @@ -20,10 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "config.h" #if USE_LEVELDB -/* -LevelDB databases -*/ - #include "database-leveldb.h" #include "leveldb/db.h" @@ -35,6 +31,7 @@ LevelDB databases #include "main.h" #include "settings.h" #include "log.h" +#include "filesys.h" #define ENSURE_STATUS_OK(s) \ if (!(s).ok()) { \ diff --git a/src/database-sqlite3.cpp b/src/database-sqlite3.cpp index 4d48796fc..8e1501786 100644 --- a/src/database-sqlite3.cpp +++ b/src/database-sqlite3.cpp @@ -44,6 +44,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "main.h" #include "settings.h" #include "log.h" +#include "filesys.h" Database_SQLite3::Database_SQLite3(ServerMap *map, std::string savedir) { diff --git a/src/emerge.cpp b/src/emerge.cpp index a2b265486..b6e2080a6 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -97,7 +97,7 @@ EmergeManager::EmergeManager(IGameDef *gamedef) { // if unspecified, leave a proc for the main thread and one for // some other misc thread - int nthreads = 0; + s16 nthreads = 0; if (!g_settings->getS16NoEx("num_emerge_threads", nthreads)) nthreads = porting::getNumberOfProcessors() - 2; if (nthreads < 1) @@ -117,8 +117,8 @@ EmergeManager::EmergeManager(IGameDef *gamedef) { if (qlimit_generate < 1) qlimit_generate = 1; - for (int i = 0; i != nthreads; i++) - emergethread.push_back(new EmergeThread((Server *)gamedef, i)); + for (s16 i = 0; i < nthreads; i++) + emergethread.push_back(new EmergeThread((Server *) gamedef, i)); infostream << "EmergeManager: using " << nthreads << " threads" << std::endl; } diff --git a/src/environment.cpp b/src/environment.cpp index c8af72f6b..66898f012 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -508,38 +508,29 @@ void ServerEnvironment::loadMeta() // Open file and deserialize std::ifstream is(path.c_str(), std::ios_base::binary); - if(is.good() == false) - { - infostream<<"ServerEnvironment::loadMeta(): Failed to open " - <<path<<std::endl; + if (!is.good()) { + infostream << "ServerEnvironment::loadMeta(): Failed to open " + << path << std::endl; throw SerializationError("Couldn't load env meta"); } Settings args; - - for(;;) - { - if(is.eof()) - throw SerializationError - ("ServerEnvironment::loadMeta(): EnvArgsEnd not found"); - std::string line; - std::getline(is, line); - std::string trimmedline = trim(line); - if(trimmedline == "EnvArgsEnd") - break; - args.parseConfigLine(line); + + if (!args.parseConfigLines(is, "EnvArgsEnd")) { + throw SerializationError("ServerEnvironment::loadMeta(): " + "EnvArgsEnd not found!"); } - - try{ + + try { m_game_time = args.getU64("game_time"); - }catch(SettingNotFoundException &e){ + } catch (SettingNotFoundException &e) { // Getting this is crucial, otherwise timestamps are useless throw SerializationError("Couldn't load env meta game_time"); } - try{ + try { m_time_of_day = args.getU64("time_of_day"); - }catch(SettingNotFoundException &e){ + } catch (SettingNotFoundException &e) { // This is not as important m_time_of_day = 9000; } diff --git a/src/guiEngine.cpp b/src/guiEngine.cpp index e2f1a0aad..41a522caf 100644 --- a/src/guiEngine.cpp +++ b/src/guiEngine.cpp @@ -19,7 +19,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "guiEngine.h" +#include <IGUIStaticText.h> +#include <ICameraSceneNode.h> #include "scripting_mainmenu.h" +#include "util/numeric.h" #include "config.h" #include "version.h" #include "porting.h" @@ -31,14 +34,12 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "sound_openal.h" #include "clouds.h" #include "httpfetch.h" -#include "util/numeric.h" +#include "log.h" #ifdef __ANDROID__ #include "tile.h" #include <GLES/gl.h> #endif -#include <IGUIStaticText.h> -#include <ICameraSceneNode.h> /******************************************************************************/ /** TextDestGuiEngine */ diff --git a/src/inventorymanager.cpp b/src/inventorymanager.cpp index 1c511e9cb..1ffcc3460 100644 --- a/src/inventorymanager.cpp +++ b/src/inventorymanager.cpp @@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "settings.h" #include "craftdef.h" #include "rollback_interface.h" +#include "strfnd.h" #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" diff --git a/src/keycode.cpp b/src/keycode.cpp index 890c97cc2..c5f102b44 100644 --- a/src/keycode.cpp +++ b/src/keycode.cpp @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "settings.h" #include "log.h" #include "hex.h" +#include "debug.h" class UnknownKeycode : public BaseException { diff --git a/src/map.cpp b/src/map.cpp index 236972ae9..1fe0ca9ad 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -3065,37 +3065,25 @@ void ServerMap::loadMapMeta() { DSTACK(__FUNCTION_NAME); - /*infostream<<"ServerMap::loadMapMeta(): Loading map metadata" - <<std::endl;*/ - - std::string fullpath = m_savedir + DIR_DELIM + "map_meta.txt"; + std::string fullpath = m_savedir + DIR_DELIM "map_meta.txt"; std::ifstream is(fullpath.c_str(), std::ios_base::binary); - if(is.good() == false) - { - infostream<<"ERROR: ServerMap::loadMapMeta(): " - <<"could not open"<<fullpath<<std::endl; + if (!is.good()) { + errorstream << "ServerMap::loadMapMeta(): " + << "could not open" << fullpath << std::endl; throw FileNotGoodException("Cannot open map metadata"); } Settings params; - for(;;) - { - if(is.eof()) - throw SerializationError - ("ServerMap::loadMapMeta(): [end_of_params] not found"); - std::string line; - std::getline(is, line); - std::string trimmedline = trim(line); - if(trimmedline == "[end_of_params]") - break; - params.parseConfigLine(line); + if (!params.parseConfigLines(is, "[end_of_params]")) { + throw SerializationError("ServerMap::loadMapMeta(): " + "[end_of_params] not found!"); } m_emerge->loadParamsFromSettings(¶ms); - verbosestream<<"ServerMap::loadMapMeta(): seed=" - << m_emerge->params.seed<<std::endl; + verbosestream << "ServerMap::loadMapMeta(): seed=" + << m_emerge->params.seed << std::endl; } void ServerMap::saveSectorMeta(ServerMapSector *sector) diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 1a31a8bcb..176c8a8a3 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -24,7 +24,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapblock.h" #include "mapnode.h" #include "map.h" -//#include "serverobject.h" #include "content_sao.h" #include "nodedef.h" #include "content_mapnode.h" // For content_mapnode_get_new_name @@ -38,6 +37,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "serialization.h" #include "util/serialize.h" #include "filesys.h" +#include "log.h" FlagDesc flagdesc_mapgen[] = { diff --git a/src/mapgen.h b/src/mapgen.h index 3c897e023..b272b5cb2 100644 --- a/src/mapgen.h +++ b/src/mapgen.h @@ -106,9 +106,9 @@ struct MapgenSpecificParams { struct MapgenParams { std::string mg_name; - int chunksize; + s16 chunksize; u64 seed; - int water_level; + s16 water_level; u32 flags; MapgenSpecificParams *sparams; diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 93751c70e..f14311fc3 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -29,7 +29,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "nameidmapping.h" #include "util/numeric.h" #include "util/serialize.h" -//#include "profiler.h" // For TimeTaker +#include "exceptions.h" +#include "debug.h" /* NodeBox diff --git a/src/player.cpp b/src/player.cpp index 40d403952..8e5f56199 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -18,12 +18,16 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "player.h" + +#include <fstream> +#include "util/numeric.h" #include "hud.h" #include "constants.h" #include "gamedef.h" #include "settings.h" #include "content_sao.h" -#include "util/numeric.h" +#include "filesys.h" +#include "log.h" Player::Player(IGameDef *gamedef): touching_ground(false), @@ -195,18 +199,10 @@ void Player::serialize(std::ostream &os) void Player::deSerialize(std::istream &is, std::string playername) { Settings args; - - for(;;) - { - if(is.eof()) - throw SerializationError - (("Player::deSerialize(): PlayerArgsEnd of player \"" + playername + "\" not found").c_str()); - std::string line; - std::getline(is, line); - std::string trimmedline = trim(line); - if(trimmedline == "PlayerArgsEnd") - break; - args.parseConfigLine(line); + + if (!args.parseConfigLines(is, "PlayerArgsEnd")) { + throw SerializationError("PlayerArgsEnd of player " + + playername + " not found!"); } //args.getS32("version"); // Version field value not used diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp index c6d41050b..d31e84b3d 100644 --- a/src/script/lua_api/l_mapgen.cpp +++ b/src/script/lua_api/l_mapgen.cpp @@ -22,12 +22,14 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "lua_api/l_vmanip.h" #include "common/c_converter.h" #include "common/c_content.h" +#include "util/serialize.h" #include "server.h" #include "environment.h" #include "biome.h" #include "emerge.h" #include "mapgen_v7.h" #include "main.h" +#include "log.h" struct EnumString ModApiMapgen::es_BiomeTerrainType[] = diff --git a/src/script/lua_api/l_util.cpp b/src/script/lua_api/l_util.cpp index dda5b5abf..eb6c1835d 100644 --- a/src/script/lua_api/l_util.cpp +++ b/src/script/lua_api/l_util.cpp @@ -23,13 +23,14 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "common/c_content.h" #include "cpp_api/s_async.h" #include "serialization.h" +#include "json/json.h" #include "debug.h" #include "porting.h" #include "log.h" #include "tool.h" +#include "filesys.h" #include "settings.h" #include "main.h" //required for g_settings, g_settings_path -#include "json/json.h" // debug(...) // Writes a line to dstream diff --git a/src/settings.cpp b/src/settings.cpp new file mode 100644 index 000000000..760f07e21 --- /dev/null +++ b/src/settings.cpp @@ -0,0 +1,702 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser 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 "settings.h" +#include "irrlichttypes_bloated.h" +#include "exceptions.h" +#include "jthread/jmutexautolock.h" +#include "strfnd.h" +#include <iostream> +#include <fstream> +#include <sstream> +#include "debug.h" +#include "log.h" +#include "util/serialize.h" +#include "filesys.h" +#include <cctype> + + +Settings & Settings::operator += (const Settings &other) +{ + update(other); + + return *this; +} + + +Settings & Settings::operator = (const Settings &other) +{ + if (&other == this) + return *this; + + JMutexAutoLock lock(m_mutex); + JMutexAutoLock lock2(other.m_mutex); + + clearNoLock(); + updateNoLock(other); + + return *this; +} + + +bool Settings::parseConfigLines(std::istream &is, + const std::string &end) +{ + JMutexAutoLock lock(m_mutex); + + std::string name, value; + bool end_found = false; + + while (is.good() && !end_found) { + if (parseConfigObject(is, name, value, end, end_found)) { + m_settings[name] = value; + } + } + if (!end.empty() && !end_found) { + return false; + } + return true; +} + + +bool Settings::readConfigFile(const char *filename) +{ + std::ifstream is(filename); + if (!is.good()) + return false; + + JMutexAutoLock lock(m_mutex); + + std::string name, value; + + while (is.good()) { + if (parseConfigObject(is, name, value)) { + m_settings[name] = value; + } + } + + return true; +} + + +void Settings::writeLines(std::ostream &os) const +{ + JMutexAutoLock lock(m_mutex); + + for (std::map<std::string, std::string>::const_iterator + i = m_settings.begin(); + i != m_settings.end(); ++i) { + os << i->first << " = " << i->second << '\n'; + } +} + + +bool Settings::updateConfigFile(const char *filename) +{ + std::list<std::string> objects; + std::set<std::string> updated; + bool changed = false; + + JMutexAutoLock lock(m_mutex); + + // Read the file and check for differences + { + std::ifstream is(filename); + while (is.good()) { + getUpdatedConfigObject(is, objects, + updated, changed); + } + } + + // If something not yet determined to have been changed, check if + // any new stuff was added + if (!changed) { + for (std::map<std::string, std::string>::const_iterator + i = m_settings.begin(); + i != m_settings.end(); ++i) { + if (updated.find(i->first) == updated.end()) { + changed = true; + break; + } + } + } + + // If nothing was actually changed, skip writing the file + if (!changed) { + return true; + } + + // Write stuff back + { + std::ostringstream ss(std::ios_base::binary); + + // Write changes settings + for (std::list<std::string>::const_iterator + i = objects.begin(); + i != objects.end(); ++i) { + ss << (*i); + } + + // Write new settings + for (std::map<std::string, std::string>::const_iterator + i = m_settings.begin(); + i != m_settings.end(); ++i) { + if (updated.find(i->first) != updated.end()) + continue; + ss << i->first << " = " << i->second << '\n'; + } + + if (!fs::safeWriteToFile(filename, ss.str())) { + errorstream << "Error writing configuration file: \"" + << filename << "\"" << std::endl; + return false; + } + } + + return true; +} + + +bool Settings::parseCommandLine(int argc, char *argv[], + std::map<std::string, ValueSpec> &allowed_options) +{ + int nonopt_index = 0; + for (int i = 1; i < argc; i++) { + std::string arg_name = argv[i]; + if (arg_name.substr(0, 2) != "--") { + // If option doesn't start with -, read it in as nonoptX + if (arg_name[0] != '-'){ + std::string name = "nonopt"; + name += itos(nonopt_index); + set(name, arg_name); + nonopt_index++; + continue; + } + errorstream << "Invalid command-line parameter \"" + << arg_name << "\": --<option> expected." << std::endl; + return false; + } + + std::string name = arg_name.substr(2); + + std::map<std::string, ValueSpec>::iterator n; + n = allowed_options.find(name); + if (n == allowed_options.end()) { + errorstream << "Unknown command-line parameter \"" + << arg_name << "\"" << std::endl; + return false; + } + + ValueType type = n->second.type; + + std::string value = ""; + + if (type == VALUETYPE_FLAG) { + value = "true"; + } else { + if ((i + 1) >= argc) { + errorstream << "Invalid command-line parameter \"" + << name << "\": missing value" << std::endl; + return false; + } + value = argv[i++]; + } + + set(name, value); + } + + return true; +} + + + +/*********** + * Getters * + ***********/ + + +std::string Settings::get(const std::string &name) const +{ + JMutexAutoLock lock(m_mutex); + + std::map<std::string, std::string>::const_iterator n; + if ((n = m_settings.find(name)) == m_settings.end()) { + if ((n = m_defaults.find(name)) == m_defaults.end()) { + throw SettingNotFoundException("Setting [" + name + "] not found."); + } + } + return n->second; +} + + +bool Settings::getBool(const std::string &name) const +{ + return is_yes(get(name)); +} + + +u16 Settings::getU16(const std::string &name) const +{ + return stoi(get(name), 0, 65535); +} + + +s16 Settings::getS16(const std::string &name) const +{ + return stoi(get(name), -32768, 32767); +} + + +s32 Settings::getS32(const std::string &name) const +{ + return stoi(get(name)); +} + + +float Settings::getFloat(const std::string &name) const +{ + return stof(get(name)); +} + + +u64 Settings::getU64(const std::string &name) const +{ + u64 value = 0; + std::string s = get(name); + std::istringstream ss(s); + ss >> value; + return value; +} + + +v2f Settings::getV2F(const std::string &name) const +{ + v2f value; + Strfnd f(get(name)); + f.next("("); + value.X = stof(f.next(",")); + value.Y = stof(f.next(")")); + return value; +} + + +v3f Settings::getV3F(const std::string &name) const +{ + v3f value; + Strfnd f(get(name)); + f.next("("); + value.X = stof(f.next(",")); + value.Y = stof(f.next(",")); + value.Z = stof(f.next(")")); + return value; +} + + +u32 Settings::getFlagStr(const std::string &name, const FlagDesc *flagdesc, + u32 *flagmask) const +{ + std::string val = get(name); + return std::isdigit(val[0]) + ? stoi(val) + : readFlagString(val, flagdesc, flagmask); +} + + +// N.B. if getStruct() is used to read a non-POD aggregate type, +// the behavior is undefined. +bool Settings::getStruct(const std::string &name, const std::string &format, + void *out, size_t olen) const +{ + std::string valstr; + + try { + valstr = get(name); + } catch (SettingNotFoundException &e) { + return false; + } + + if (!deSerializeStringToStruct(valstr, format, out, olen)) + return false; + + return true; +} + + +bool Settings::exists(const std::string &name) const +{ + JMutexAutoLock lock(m_mutex); + + return (m_settings.find(name) != m_settings.end() || + m_defaults.find(name) != m_defaults.end()); +} + + +std::vector<std::string> Settings::getNames() const +{ + std::vector<std::string> names; + for (std::map<std::string, std::string>::const_iterator + i = m_settings.begin(); + i != m_settings.end(); ++i) { + names.push_back(i->first); + } + return names; +} + + + +/*************************************** + * Getters that don't throw exceptions * + ***************************************/ + + +bool Settings::getNoEx(const std::string &name, std::string &val) const +{ + try { + val = get(name); + return true; + } catch (SettingNotFoundException &e) { + return false; + } +} + + +bool Settings::getFlag(const std::string &name) const +{ + try { + return getBool(name); + } catch(SettingNotFoundException &e) { + return false; + } +} + + +bool Settings::getFloatNoEx(const std::string &name, float &val) const +{ + try { + val = getFloat(name); + return true; + } catch (SettingNotFoundException &e) { + return false; + } +} + + +bool Settings::getU16NoEx(const std::string &name, u16 &val) const +{ + try { + val = getU16(name); + return true; + } catch (SettingNotFoundException &e) { + return false; + } +} + + +bool Settings::getS16NoEx(const std::string &name, s16 &val) const +{ + try { + val = getS16(name); + return true; + } catch (SettingNotFoundException &e) { + return false; + } +} + + +bool Settings::getS32NoEx(const std::string &name, s32 &val) const +{ + try { + val = getS32(name); + return true; + } catch (SettingNotFoundException &e) { + return false; + } +} + + +bool Settings::getU64NoEx(const std::string &name, u64 &val) const +{ + try { + val = getU64(name); + return true; + } catch (SettingNotFoundException &e) { + return false; + } +} + + +bool Settings::getV2FNoEx(const std::string &name, v2f &val) const +{ + try { + val = getV2F(name); + return true; + } catch (SettingNotFoundException &e) { + return false; + } +} + + +bool Settings::getV3FNoEx(const std::string &name, v3f &val) const +{ + try { + val = getV3F(name); + return true; + } catch (SettingNotFoundException &e) { + return false; + } +} + + +// N.B. getFlagStrNoEx() does not set val, but merely modifies it. Thus, +// val must be initialized before using getFlagStrNoEx(). The intention of +// this is to simplify modifying a flags field from a default value. +bool Settings::getFlagStrNoEx(const std::string &name, u32 &val, FlagDesc *flagdesc) const +{ + try { + u32 flags, flagmask; + + flags = getFlagStr(name, flagdesc, &flagmask); + + val &= ~flagmask; + val |= flags; + + return true; + } catch (SettingNotFoundException &e) { + return false; + } +} + + + +/*********** + * Setters * + ***********/ + + +void Settings::set(const std::string &name, std::string value) +{ + JMutexAutoLock lock(m_mutex); + + m_settings[name] = value; +} + + +void Settings::set(const std::string &name, const char *value) +{ + JMutexAutoLock lock(m_mutex); + + m_settings[name] = value; +} + + +void Settings::setDefault(const std::string &name, std::string value) +{ + JMutexAutoLock lock(m_mutex); + + m_defaults[name] = value; +} + + +void Settings::setBool(const std::string &name, bool value) +{ + set(name, value ? "true" : "false"); +} + + +void Settings::setS16(const std::string &name, s16 value) +{ + set(name, itos(value)); +} + + +void Settings::setS32(const std::string &name, s32 value) +{ + set(name, itos(value)); +} + + +void Settings::setU64(const std::string &name, u64 value) +{ + std::ostringstream os; + os << value; + set(name, os.str()); +} + + +void Settings::setFloat(const std::string &name, float value) +{ + set(name, ftos(value)); +} + + +void Settings::setV2F(const std::string &name, v2f value) +{ + std::ostringstream os; + os << "(" << value.X << "," << value.Y << ")"; + set(name, os.str()); +} + + +void Settings::setV3F(const std::string &name, v3f value) +{ + std::ostringstream os; + os << "(" << value.X << "," << value.Y << "," << value.Z << ")"; + set(name, os.str()); +} + + +void Settings::setFlagStr(const std::string &name, u32 flags, + const FlagDesc *flagdesc, u32 flagmask) +{ + set(name, writeFlagString(flags, flagdesc, flagmask)); +} + + +bool Settings::setStruct(const std::string &name, const std::string &format, void *value) +{ + std::string structstr; + if (!serializeStructToString(&structstr, format, value)) + return false; + + set(name, structstr); + return true; +} + + +bool Settings::remove(const std::string &name) +{ + JMutexAutoLock lock(m_mutex); + return m_settings.erase(name); +} + + +void Settings::clear() +{ + JMutexAutoLock lock(m_mutex); + clearNoLock(); +} + + +void Settings::updateValue(const Settings &other, const std::string &name) +{ + if (&other == this) + return; + + JMutexAutoLock lock(m_mutex); + + try { + std::string val = other.get(name); + m_settings[name] = val; + } catch (SettingNotFoundException &e) { + } +} + + +void Settings::update(const Settings &other) +{ + if (&other == this) + return; + + JMutexAutoLock lock(m_mutex); + JMutexAutoLock lock2(other.m_mutex); + + updateNoLock(other); +} + + +inline bool Settings::parseConfigObject(std::istream &is, + std::string &name, std::string &value) +{ + bool end_found = false; + return parseConfigObject(is, name, value, "", end_found); +} + + +// NOTE: This function might be expanded to allow multi-line settings. +bool Settings::parseConfigObject(std::istream &is, + std::string &name, std::string &value, + const std::string &end, bool &end_found) +{ + std::string line; + std::getline(is, line); + std::string trimmed_line = trim(line); + + // Ignore empty lines and comments + if (trimmed_line.empty() || trimmed_line[0] == '#') { + value = trimmed_line; + return false; + } + if (trimmed_line == end) { + end_found = true; + return false; + } + + Strfnd sf(trimmed_line); + + name = trim(sf.next("=")); + if (name.empty()) { + value = trimmed_line; + return false; + } + + value = trim(sf.next("\n")); + + return true; +} + + +void Settings::getUpdatedConfigObject(std::istream &is, + std::list<std::string> &dst, + std::set<std::string> &updated, + bool &changed) +{ + std::string name, value; + if (!parseConfigObject(is, name, value)) { + dst.push_back(value + '\n'); + return; + } + + if (m_settings.find(name) != m_settings.end()) { + std::string new_value = m_settings[name]; + + if (new_value != value) { + changed = true; + } + + dst.push_back(name + " = " + new_value + '\n'); + updated.insert(name); + } else { // File contains a setting which is not in m_settings + changed = true; + } +} + + +void Settings::updateNoLock(const Settings &other) +{ + m_settings.insert(other.m_settings.begin(), other.m_settings.end()); + m_defaults.insert(other.m_defaults.begin(), other.m_defaults.end()); +} + + +void Settings::clearNoLock() +{ + m_settings.clear(); + m_defaults.clear(); +} + diff --git a/src/settings.h b/src/settings.h index bfe7dd5a4..f0ef9f6b2 100644 --- a/src/settings.h +++ b/src/settings.h @@ -21,23 +21,12 @@ with this program; if not, write to the Free Software Foundation, Inc., #define SETTINGS_HEADER #include "irrlichttypes_bloated.h" -#include "exceptions.h" -#include <string> -#include "jthread/jmutex.h" -#include "jthread/jmutexautolock.h" -#include "strfnd.h" -#include <iostream> -#include <fstream> -#include <sstream> -#include "debug.h" -#include "log.h" #include "util/string.h" -#include "util/serialize.h" -#include <list> +#include "jthread/jmutex.h" +#include <string> #include <map> +#include <list> #include <set> -#include "filesys.h" -#include <cctype> enum ValueType { @@ -56,753 +45,126 @@ struct ValueSpec const char *help; }; + class Settings { public: - Settings() - { - } - - void writeLines(std::ostream &os) const - { - JMutexAutoLock lock(m_mutex); - - for(std::map<std::string, std::string>::const_iterator - i = m_settings.begin(); - i != m_settings.end(); ++i) - { - std::string name = i->first; - std::string value = i->second; - os<<name<<" = "<<value<<"\n"; - } - } - - // return all keys used - std::vector<std::string> getNames() const - { - std::vector<std::string> names; - for(std::map<std::string, std::string>::const_iterator - i = m_settings.begin(); - i != m_settings.end(); ++i) - { - names.push_back(i->first); - } - return names; - } - - // remove a setting - bool remove(const std::string &name) - { - return m_settings.erase(name); - } - - - bool parseConfigLine(const std::string &line) - { - JMutexAutoLock lock(m_mutex); - - std::string trimmedline = trim(line); - - // Ignore empty lines and comments - if(trimmedline.size() == 0 || trimmedline[0] == '#') - return true; - - //infostream<<"trimmedline=\""<<trimmedline<<"\""<<std::endl; - - Strfnd sf(trim(line)); - - std::string name = sf.next("="); - name = trim(name); - - if(name == "") - return true; - - std::string value = sf.next("\n"); - value = trim(value); - - /*infostream<<"Config name=\""<<name<<"\" value=\"" - <<value<<"\""<<std::endl;*/ - - m_settings[name] = value; - - return true; - } - - void parseConfigLines(std::istream &is, const std::string &endstring) - { - for(;;){ - if(is.eof()) - break; - std::string line; - std::getline(is, line); - std::string trimmedline = trim(line); - if(endstring != ""){ - if(trimmedline == endstring) - break; - } - parseConfigLine(line); - } - } - - // Returns false on EOF - bool parseConfigObject(std::istream &is) - { - if(is.eof()) - return false; - - /* - NOTE: This function might be expanded to allow multi-line - settings. - */ - std::string line; - std::getline(is, line); - //infostream<<"got line: \""<<line<<"\""<<std::endl; - - return parseConfigLine(line); - } - - /* - Read configuration file - - Returns true on success - */ - bool readConfigFile(const char *filename) - { - std::ifstream is(filename); - if(is.good() == false) - return false; - - /*infostream<<"Parsing configuration file: \"" - <<filename<<"\""<<std::endl;*/ - - while(parseConfigObject(is)); - - return true; - } - - /* - Reads a configuration object from stream (usually a single line) - and adds it to dst. - - Preserves comments and empty lines. - - Settings that were added to dst are also added to updated. - key of updated is setting name, value of updated is dummy. - - Returns false on EOF - */ - bool getUpdatedConfigObject(std::istream &is, - std::list<std::string> &dst, - std::set<std::string> &updated, - bool &value_changed) - { - JMutexAutoLock lock(m_mutex); - - if(is.eof()) - return false; - - // NOTE: This function will be expanded to allow multi-line settings - std::string line; - std::getline(is, line); - - std::string trimmedline = trim(line); - - std::string line_end = ""; - if(is.eof() == false) - line_end = "\n"; - - // Ignore empty lines and comments - if(trimmedline.size() == 0 || trimmedline[0] == '#') - { - dst.push_back(line+line_end); - return true; - } - - Strfnd sf(trim(line)); - - std::string name = sf.next("="); - name = trim(name); - - if(name == "") - { - dst.push_back(line+line_end); - return true; - } - - std::string value = sf.next("\n"); - value = trim(value); - - if(m_settings.find(name) != m_settings.end()) - { - std::string newvalue = m_settings[name]; - - if(newvalue != value) - { - infostream<<"Changing value of \""<<name<<"\" = \"" - <<value<<"\" -> \""<<newvalue<<"\"" - <<std::endl; - value_changed = true; - } - - dst.push_back(name + " = " + newvalue + line_end); - - updated.insert(name); - } - else //file contains a setting which is not in m_settings - value_changed=true; - - return true; - } + Settings() {} - /* - Updates configuration file + Settings & operator += (const Settings &other); + Settings & operator = (const Settings &other); - Returns true on success - */ - bool updateConfigFile(const char *filename) - { - infostream<<"Updating configuration file: \"" - <<filename<<"\""<<std::endl; - - std::list<std::string> objects; - std::set<std::string> updated; - bool something_actually_changed = false; - - // Read and modify stuff - { - std::ifstream is(filename); - if(is.good() == false) - { - infostream<<"updateConfigFile():" - " Error opening configuration file" - " for reading: \"" - <<filename<<"\""<<std::endl; - } - else - { - while(getUpdatedConfigObject(is, objects, updated, - something_actually_changed)); - } - } - - JMutexAutoLock lock(m_mutex); - - // If something not yet determined to have been changed, check if - // any new stuff was added - if(!something_actually_changed){ - for(std::map<std::string, std::string>::const_iterator - i = m_settings.begin(); - i != m_settings.end(); ++i) - { - if(updated.find(i->first) != updated.end()) - continue; - something_actually_changed = true; - break; - } - } - - // If nothing was actually changed, skip writing the file - if(!something_actually_changed){ - infostream<<"Skipping writing of "<<filename - <<" because content wouldn't be modified"<<std::endl; - return true; - } - - // Write stuff back - { - std::ostringstream ss(std::ios_base::binary); - - /* - Write updated stuff - */ - for(std::list<std::string>::const_iterator - i = objects.begin(); - i != objects.end(); ++i) - { - ss<<(*i); - } - - /* - Write stuff that was not already in the file - */ - for(std::map<std::string, std::string>::const_iterator - i = m_settings.begin(); - i != m_settings.end(); ++i) - { - if(updated.find(i->first) != updated.end()) - continue; - std::string name = i->first; - std::string value = i->second; - infostream<<"Adding \""<<name<<"\" = \""<<value<<"\"" - <<std::endl; - ss<<name<<" = "<<value<<"\n"; - } - - if(!fs::safeWriteToFile(filename, ss.str())) - { - errorstream<<"Error writing configuration file: \"" - <<filename<<"\""<<std::endl; - return false; - } - } - - return true; - } - /* - NOTE: Types of allowed_options are ignored + /*********************** + * Reading and writing * + ***********************/ - returns true on success - */ + // Read configuration file. Returns success. + bool readConfigFile(const char *filename); + //Updates configuration file. Returns success. + bool updateConfigFile(const char *filename); + // NOTE: Types of allowed_options are ignored. Returns success. bool parseCommandLine(int argc, char *argv[], - std::map<std::string, ValueSpec> &allowed_options) - { - int nonopt_index = 0; - int i=1; - for(;;) - { - if(i >= argc) - break; - std::string argname = argv[i]; - if(argname.substr(0, 2) != "--") - { - // If option doesn't start with -, read it in as nonoptX - if(argname[0] != '-'){ - std::string name = "nonopt"; - name += itos(nonopt_index); - set(name, argname); - nonopt_index++; - i++; - continue; - } - errorstream<<"Invalid command-line parameter \"" - <<argname<<"\": --<option> expected."<<std::endl; - return false; - } - i++; - - std::string name = argname.substr(2); - - std::map<std::string, ValueSpec>::iterator n; - n = allowed_options.find(name); - if(n == allowed_options.end()) - { - errorstream<<"Unknown command-line parameter \"" - <<argname<<"\""<<std::endl; - return false; - } - - ValueType type = n->second.type; - - std::string value = ""; - - if(type == VALUETYPE_FLAG) - { - value = "true"; - } - else - { - if(i >= argc) - { - errorstream<<"Invalid command-line parameter \"" - <<name<<"\": missing value"<<std::endl; - return false; - } - value = argv[i]; - i++; - } - - - infostream<<"Valid command-line parameter: \"" - <<name<<"\" = \""<<value<<"\"" - <<std::endl; - set(name, value); - } - - return true; - } - - void set(const std::string &name, std::string value) - { - JMutexAutoLock lock(m_mutex); - - m_settings[name] = value; - } - - void set(const std::string &name, const char *value) - { - JMutexAutoLock lock(m_mutex); - - m_settings[name] = value; - } - - - void setDefault(const std::string &name, std::string value) - { - JMutexAutoLock lock(m_mutex); - - m_defaults[name] = value; - } - - bool exists(const std::string &name) const - { - JMutexAutoLock lock(m_mutex); - - return (m_settings.find(name) != m_settings.end() || - m_defaults.find(name) != m_defaults.end()); - } - - std::string get(const std::string &name) const - { - JMutexAutoLock lock(m_mutex); - - std::map<std::string, std::string>::const_iterator n; - if ((n = m_settings.find(name)) == m_settings.end()) - if ((n = m_defaults.find(name)) == m_defaults.end()) - throw SettingNotFoundException(("Setting [" + name + "] not found ").c_str()); - - return n->second; - } - - //////////// Get setting - bool getBool(const std::string &name) const - { - return is_yes(get(name)); - } - - bool getFlag(const std::string &name) const - { - try { - return getBool(name); - } catch(SettingNotFoundException &e) { - return false; - } - } - - float getFloat(const std::string &name) const - { - return stof(get(name)); - } - - u16 getU16(const std::string &name) const - { - return stoi(get(name), 0, 65535); - } - - s16 getS16(const std::string &name) const - { - return stoi(get(name), -32768, 32767); - } - - s32 getS32(const std::string &name) const - { - return stoi(get(name)); - } - - v3f getV3F(const std::string &name) const - { - v3f value; - Strfnd f(get(name)); - f.next("("); - value.X = stof(f.next(",")); - value.Y = stof(f.next(",")); - value.Z = stof(f.next(")")); - return value; - } - - v2f getV2F(const std::string &name) const - { - v2f value; - Strfnd f(get(name)); - f.next("("); - value.X = stof(f.next(",")); - value.Y = stof(f.next(")")); - return value; - } - - u64 getU64(const std::string &name) const - { - u64 value = 0; - std::string s = get(name); - std::istringstream ss(s); - ss >> value; - return value; - } - + std::map<std::string, ValueSpec> &allowed_options); + bool parseConfigLines(std::istream &is, const std::string &end = ""); + void writeLines(std::ostream &os) const; + + + /*********** + * Getters * + ***********/ + + std::string get(const std::string &name) const; + bool getBool(const std::string &name) const; + u16 getU16(const std::string &name) const; + s16 getS16(const std::string &name) const; + s32 getS32(const std::string &name) const; + u64 getU64(const std::string &name) const; + float getFloat(const std::string &name) const; + v2f getV2F(const std::string &name) const; + v3f getV3F(const std::string &name) const; u32 getFlagStr(const std::string &name, const FlagDesc *flagdesc, - u32 *flagmask) const - { - std::string val = get(name); - return std::isdigit(val[0]) - ? stoi(val) - : readFlagString(val, flagdesc, flagmask); - } - + u32 *flagmask) const; // N.B. if getStruct() is used to read a non-POD aggregate type, // the behavior is undefined. bool getStruct(const std::string &name, const std::string &format, - void *out, size_t olen) const - { - std::string valstr; - - try { - valstr = get(name); - } catch (SettingNotFoundException &e) { - return false; - } - - if (!deSerializeStringToStruct(valstr, format, out, olen)) - return false; - - return true; - } - - //////////// Try to get value, no exception thrown - bool getNoEx(const std::string &name, std::string &val) const - { - try { - val = get(name); - return true; - } catch (SettingNotFoundException &e) { - return false; - } - } + void *out, size_t olen) const; + // return all keys used + std::vector<std::string> getNames() const; + bool exists(const std::string &name) const; + + + /*************************************** + * Getters that don't throw exceptions * + ***************************************/ + + bool getNoEx(const std::string &name, std::string &val) const; + bool getFlag(const std::string &name) const; + bool getU16NoEx(const std::string &name, u16 &val) const; + bool getS16NoEx(const std::string &name, s16 &val) const; + bool getS32NoEx(const std::string &name, s32 &val) const; + bool getU64NoEx(const std::string &name, u64 &val) const; + bool getFloatNoEx(const std::string &name, float &val) const; + bool getV2FNoEx(const std::string &name, v2f &val) const; + bool getV3FNoEx(const std::string &name, v3f &val) const; // N.B. getFlagStrNoEx() does not set val, but merely modifies it. Thus, // val must be initialized before using getFlagStrNoEx(). The intention of // this is to simplify modifying a flags field from a default value. - bool getFlagStrNoEx(const std::string &name, u32 &val, FlagDesc *flagdesc) const - { - try { - u32 flags, flagmask; - - flags = getFlagStr(name, flagdesc, &flagmask); - - val &= ~flagmask; - val |= flags; - - return true; - } catch (SettingNotFoundException &e) { - return false; - } - } - - bool getFloatNoEx(const std::string &name, float &val) const - { - try { - val = getFloat(name); - return true; - } catch (SettingNotFoundException &e) { - return false; - } - } - - bool getU16NoEx(const std::string &name, int &val) const - { - try { - val = getU16(name); - return true; - } catch (SettingNotFoundException &e) { - return false; - } - } - - bool getU16NoEx(const std::string &name, u16 &val) const - { - try { - val = getU16(name); - return true; - } catch (SettingNotFoundException &e) { - return false; - } - } - - bool getS16NoEx(const std::string &name, int &val) const - { - try { - val = getU16(name); - return true; - } catch (SettingNotFoundException &e) { - return false; - } - } - - bool getS16NoEx(const std::string &name, s16 &val) const - { - try { - val = getS16(name); - return true; - } catch (SettingNotFoundException &e) { - return false; - } - } - - bool getS32NoEx(const std::string &name, s32 &val) const - { - try { - val = getS32(name); - return true; - } catch (SettingNotFoundException &e) { - return false; - } - } - - bool getV3FNoEx(const std::string &name, v3f &val) const - { - try { - val = getV3F(name); - return true; - } catch (SettingNotFoundException &e) { - return false; - } - } - - bool getV2FNoEx(const std::string &name, v2f &val) const - { - try { - val = getV2F(name); - return true; - } catch (SettingNotFoundException &e) { - return false; - } - } - - bool getU64NoEx(const std::string &name, u64 &val) const - { - try { - val = getU64(name); - return true; - } catch (SettingNotFoundException &e) { - return false; - } - } - - //////////// Set setting - + bool getFlagStrNoEx(const std::string &name, u32 &val, FlagDesc *flagdesc) const; + + + /*********** + * Setters * + ***********/ + + void set(const std::string &name, std::string value); + void set(const std::string &name, const char *value); + void setDefault(const std::string &name, std::string value); + void setBool(const std::string &name, bool value); + void setS16(const std::string &name, s16 value); + void setS32(const std::string &name, s32 value); + void setU64(const std::string &name, u64 value); + void setFloat(const std::string &name, float value); + void setV2F(const std::string &name, v2f value); + void setV3F(const std::string &name, v3f value); + void setFlagStr(const std::string &name, u32 flags, + const FlagDesc *flagdesc, u32 flagmask); // N.B. if setStruct() is used to write a non-POD aggregate type, // the behavior is undefined. - bool setStruct(const std::string &name, const std::string &format, void *value) - { - std::string structstr; - if (!serializeStructToString(&structstr, format, value)) - return false; - - set(name, structstr); - return true; - } + bool setStruct(const std::string &name, const std::string &format, void *value); - void setFlagStr(const std::string &name, u32 flags, - const FlagDesc *flagdesc, u32 flagmask) - { - set(name, writeFlagString(flags, flagdesc, flagmask)); - } - - void setBool(const std::string &name, bool value) - { - set(name, value ? "true" : "false"); - } - - void setFloat(const std::string &name, float value) - { - set(name, ftos(value)); - } - - void setV3F(const std::string &name, v3f value) - { - std::ostringstream os; - os<<"("<<value.X<<","<<value.Y<<","<<value.Z<<")"; - set(name, os.str()); - } - - void setV2F(const std::string &name, v2f value) - { - std::ostringstream os; - os<<"("<<value.X<<","<<value.Y<<")"; - set(name, os.str()); - } - - void setS16(const std::string &name, s16 value) - { - set(name, itos(value)); - } - - void setS32(const std::string &name, s32 value) - { - set(name, itos(value)); - } - - void setU64(const std::string &name, u64 value) - { - std::ostringstream os; - os<<value; - set(name, os.str()); - } - - void clear() - { - JMutexAutoLock lock(m_mutex); - clearNoLock(); - } - - void updateValue(const Settings &other, const std::string &name) - { - if (&other == this) - return; - - JMutexAutoLock lock(m_mutex); - - try { - std::string val = other.get(name); - m_settings[name] = val; - } catch (SettingNotFoundException &e) { - } - } - - void update(const Settings &other) - { - if (&other == this) - return; - - JMutexAutoLock lock(m_mutex); - JMutexAutoLock lock2(other.m_mutex); - - updateNoLock(other); - } - - Settings & operator+=(const Settings &other) - { - update(other); - - return *this; - } - - Settings & operator=(const Settings &other) - { - if (&other == this) - return *this; - - JMutexAutoLock lock(m_mutex); - JMutexAutoLock lock2(other.m_mutex); - - clearNoLock(); - updateNoLock(other); + // remove a setting + bool remove(const std::string &name); + void clear(); + void updateValue(const Settings &other, const std::string &name); + void update(const Settings &other); - return *this; - } private: + /*********************** + * Reading and writing * + ***********************/ + + bool parseConfigObject(std::istream &is, + std::string &name, std::string &value); + bool parseConfigObject(std::istream &is, + std::string &name, std::string &value, + const std::string &end, bool &end_found); + /* + * Reads a configuration object from stream (usually a single line) + * and adds it to dst. + * Preserves comments and empty lines. + * Setting names that were added to dst are also added to updated. + */ + void getUpdatedConfigObject(std::istream &is, + std::list<std::string> &dst, + std::set<std::string> &updated, + bool &changed); - void updateNoLock(const Settings &other) - { - m_settings.insert(other.m_settings.begin(), other.m_settings.end()); - m_defaults.insert(other.m_defaults.begin(), other.m_defaults.end()); - } - void clearNoLock() - { - m_settings.clear(); - m_defaults.clear(); - } + void updateNoLock(const Settings &other); + void clearNoLock(); std::map<std::string, std::string> m_settings; diff --git a/src/socket.cpp b/src/socket.cpp index 508d61a31..0e9183f18 100644 --- a/src/socket.cpp +++ b/src/socket.cpp @@ -19,6 +19,21 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "socket.h" +#include <stdio.h> +#include <iostream> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <sstream> +#include <iomanip> +#include "util/string.h" +#include "util/numeric.h" +#include "constants.h" +#include "debug.h" +#include "settings.h" +#include "log.h" +#include "main.h" // for g_settings + #ifdef _WIN32 #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN @@ -46,20 +61,6 @@ typedef int socklen_t; typedef int socket_t; #endif -#include "constants.h" -#include "debug.h" -#include "settings.h" -#include "main.h" // for g_settings -#include <stdio.h> -#include <iostream> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sstream> -#include <iomanip> -#include "util/string.h" -#include "util/numeric.h" - // Set to true to enable verbose debug output bool socket_enable_debug_output = false; diff --git a/src/test.cpp b/src/test.cpp index 8a080454b..956397f26 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -390,12 +390,14 @@ struct TestSettings: public TestBase { Settings s; // Test reading of settings - s.parseConfigLine("leet = 1337"); - s.parseConfigLine("leetleet = 13371337"); - s.parseConfigLine("leetleet_neg = -13371337"); - s.parseConfigLine("floaty_thing = 1.1"); - s.parseConfigLine("stringy_thing = asd /( ¤%&(/\" BLÖÄRP"); - s.parseConfigLine("coord = (1, 2, 4.5)"); + std::istringstream is( + "leet = 1337\n" + "leetleet = 13371337\n" + "leetleet_neg = -13371337\n" + "floaty_thing = 1.1\n" + "stringy_thing = asd /( ¤%&(/\" BLÖÄRP\n" + "coord = (1, 2, 4.5)"); + s.parseConfigLines(is); UASSERT(s.getS32("leet") == 1337); UASSERT(s.getS16("leetleet") == 32767); UASSERT(s.getS16("leetleet_neg") == -32768); diff --git a/src/tile.cpp b/src/tile.cpp index 06d89393c..ebef77fb9 100644 --- a/src/tile.cpp +++ b/src/tile.cpp @@ -18,19 +18,21 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "tile.h" + +#include <ICameraSceneNode.h> +#include "util/string.h" +#include "util/container.h" +#include "util/thread.h" +#include "util/numeric.h" #include "irrlichttypes_extrabloated.h" #include "debug.h" #include "main.h" // for g_settings #include "filesys.h" #include "settings.h" #include "mesh.h" -#include <ICameraSceneNode.h> #include "log.h" #include "gamedef.h" -#include "util/string.h" -#include "util/container.h" -#include "util/thread.h" -#include "util/numeric.h" +#include "strfnd.h" #ifdef __ANDROID__ #include <GLES/gl.h> |