Split settings into seperate source and header files
authorShadowNinja <shadowninja@minetest.net>
Thu, 11 Sep 2014 22:22:05 +0000 (18:22 -0400)
committerShadowNinja <shadowninja@minetest.net>
Sun, 21 Sep 2014 18:39:35 +0000 (14:39 -0400)
This also cleans up settings a bit

27 files changed:
build/android/jni/Android.mk
src/CMakeLists.txt
src/client.cpp
src/clientiface.cpp
src/clientmedia.cpp
src/content_cao.cpp
src/content_mapblock.cpp
src/content_sao.cpp
src/database-leveldb.cpp
src/database-sqlite3.cpp
src/emerge.cpp
src/environment.cpp
src/guiEngine.cpp
src/inventorymanager.cpp
src/keycode.cpp
src/map.cpp
src/mapgen.cpp
src/mapgen.h
src/nodedef.cpp
src/player.cpp
src/script/lua_api/l_mapgen.cpp
src/script/lua_api/l_util.cpp
src/settings.cpp [new file with mode: 0644]
src/settings.h
src/socket.cpp
src/test.cpp
src/tile.cpp

index 9b2057781cd740339a80bb34061354502e5686b4..96693fa4d64f318c0dc376abf6d97660c9f6b9a7 100644 (file)
@@ -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 +=                                \
index de1ea2c28eaf0e0936df1127f62649eae4b5cd3c..4c1522fac73ba02df60fe225e738e3315db2e281 100644 (file)
@@ -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)
index accff4b01c024d69567adaae08425ce771b26f80..5a276e3060b747d0be9a46cb1391e5f04e636a1c 100644 (file)
@@ -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"
 
index ebbbc65bcf9a5f31c54a0bdfa41abe641a299aa4..cd2e2d4d95af68343bc1ce1ab9642f583a771ecc 100644 (file)
@@ -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",
index e2679ed46301e4902d36b997a7274d5f15750a7c..434eeb2488369c0ad6a11ae9bbf7c78533802289 100644 (file)
@@ -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()
 {
index 02622f5b48b113754be2bb9225fe12bb934c3968..d1de23d2a492e2c527dc8c8c58d34a9d40c82245 100644 (file)
@@ -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;
index b7a48d57ec53830f5b83f2d481d849ae75f59a79..c94ff590e47b66ae20172dfbd09b7905adb901a1 100644 (file)
@@ -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
index 4ee92f4d34255408e83f1159cfadb73f359fb26b..40313f7a57c587a85de4e58e76b8f1ecb5b7b607 100644 (file)
@@ -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;
 
index d57462be948b73f60f4cd0b6c2de33341cf6a9db..1681b0195bab69e91739138108711ce1194ed53c 100644 (file)
@@ -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()) { \
index 4d48796fc7d38995eea86da92d46ab474981a96a..8e1501786b84294da68a6f1feb79015f2c7a18dd 100644 (file)
@@ -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)
 {
index a2b26548630956d6a3ac61056de6159195b44d17..b6e2080a6efa97d2d43a080e96e8e4305738aa2c 100644 (file)
@@ -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;
 }
index c8af72f6b96c23ff8fa5edaf8bdc876816bebd8a..66898f012f3573fe032201b8fcf53ba8d08bb29b 100644 (file)
@@ -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;
        }
index e2f1a0aad516a0567c38300f097aab5b5c230a89..41a522cafffa780526777c12ca48f0561886d1aa 100644 (file)
@@ -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                                                         */
index 1c511e9cbe69f7659e70e8a7a1d5e172285af73b..1ffcc3460a1c77cba33a41666a02bcacd9e12ebd 100644 (file)
@@ -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<<")"
 
index 890c97cc27a875e123a60b6c6bb9b9e1c0722406..c5f102b4441a129f616e2e40460a42e259701eea 100644 (file)
@@ -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
 {
index 236972ae98a08751889f437e567e60709a2466f6..1fe0ca9adf018aa05c8d20f82cac3ab21e3d9088 100644 (file)
@@ -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(&params);
 
-       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)
index 1a31a8bcb0d728f35c74266a12aaf6490bbf1476..176c8a8a36c46b4178baa70cf91f44b28dd752e1 100644 (file)
@@ -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[] = {
index 3c897e02315a58c58b3ea5d42d2e4d826070fb22..b272b5cb215424a21d9a0646034bd60b3ff6b135 100644 (file)
@@ -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;
index 93751c70e3160e3355e7042ec3f47ee2c3ebea08..f14311fc35ea16d56fde0889c8355af52eef52e3 100644 (file)
@@ -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
index 40d403952bbbeac0b0c5822d8ef1803212dffc60..8e5f56199b1978ba803a536d6ecce0317ac621b8 100644 (file)
@@ -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
index c6d41050be13d77c4ef5f05a2999dfd9a2bf2ff5..d31e84b3d374f2e50eb413afa3c727eb5aba12ab 100644 (file)
@@ -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[] =
index dda5b5abfca4c1ffbd0efbce57c3c611066de817..eb6c1835d80acd18e3ffa545c55eecf78c6ad4eb 100644 (file)
@@ -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 (file)
index 0000000..760f07e
--- /dev/null
@@ -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();
+}
+
index bfe7dd5a455487fef1cd92f7932df2f73d6e474c..f0ef9f6b28a243bff65ea0a2e55d779dcaff6a33 100644 (file)
@@ -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;
index 508d61a3126bf26aa36acd8dad96cdffe9056882..0e9183f18058c11cc645cd892a16347f1d01d462 100644 (file)
@@ -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;
 
index 8a080454b6bf7f447bc66727360c6f3dd8d37b2b..956397f26eda33eca4e3bafe739604583c8d889e 100644 (file)
@@ -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);
index 06d89393c65426e4f9608f9a7a6dc5ee707d95c4..ebef77fb9cbe148010b2688a3ff98a04c5023e38 100644 (file)
@@ -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>