diff --git a/.gitignore b/.gitignore index a32a01e07..d356db5fa 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ node_modules /package.json /.bsv /*.mkv +*.d diff --git a/.gitmodules b/.gitmodules index 55c17f666..b179b87d1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,11 +13,6 @@ url = https://github.com/ChaiScript/ChaiScript.git ignore = dirty branch = develop -[submodule "vendor/filesystem"] - path = vendor/filesystem - url = https://github.com/wjakob/filesystem.git - ignore = dirty - branch = master [submodule "vendor/SDL_tty"] path = vendor/SDL_tty url = https://github.com/Grumbel/SDL_tty.git diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c1f4f741..8293f9dd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to [ChaiLove](https://github.com/RobLoach/ChaiLove) will be The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## 0.29.1 - 2018-11-05 +### Chores +- Moved String Methods to [ChaiScript_Extras](https://github.com/ChaiScript/ChaiScript_Extras) +- Replaced use of `filesystem/path.h` with internal functions +- Updated ChaiScript/ChaiScript_Extras +- Updated libretro/libretro-common +- Updated effolkronium/random + ## 0.29.0 - 2018-10-13 ### Fixes - Fixed `/libretro/saves` mounting diff --git a/Makefile.common b/Makefile.common index 0be81b20a..1be6db8a7 100644 --- a/Makefile.common +++ b/Makefile.common @@ -17,9 +17,6 @@ SOURCES_C := $(CORE_DIR)/vendor/semver/semver.c # random FLAGS += -I$(CORE_DIR)/vendor/random/include -# filesystem -FLAGS += -I$(CORE_DIR)/vendor/filesystem - # libretro-common FLAGS += -I$(CORE_DIR)/vendor/libretro-common/include # Only compile libretro-common when not STATIC_LINKING @@ -49,7 +46,7 @@ ifneq ($(STATIC_LINKING), 1) ) # Ensure the sinc_resampler_neon is available for ARM NEON devices. OBJECTS += $(CORE_DIR)/vendor/libretro-common/audio/resampler/drivers/sinc_resampler_neon.o - + # MD5 FLAGS += -I$(CORE_DIR)/vendor/libretro-common/include SOURCES_C += $(CORE_DIR)/vendor/libretro-common/utils/md5.c @@ -190,6 +187,7 @@ ifeq ($(HAVE_CHAISCRIPT),) FLAGS += -I$(CORE_DIR)/vendor/ChaiScript_Extras/include FLAGS += -D__HAVE_CHAISCRIPT__ FLAGS += -DCHAISCRIPT_NO_THREADS -DCHAISCRIPT_NO_THREADS_WARNING -DCHAISCRIPT_NO_DYNLOAD + FLAGS += -DCHAISCRIPT_EXTRAS_MATH_SKIP_ADVANCED endif # SDL diff --git a/Makefile.libretro b/Makefile.libretro index c17a2a0a9..c13b9a4b3 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -277,19 +277,23 @@ else ifeq ($(platform), switch) # Nintendo Switch (libnx) else ifeq ($(platform), libnx) - include $(DEVKITPRO)/libnx/switch_rules - EXT=a - TARGET := $(TARGET_NAME)_libretro_$(platform).$(EXT) - DEFINES := -DSWITCH=1 -U__linux__ -U__linux -DRARCH_INTERNAL - CFLAGS := $(DEFINES) -g \ - -O2 \ + export DEPSDIR := $(CURDIR)/ + include $(DEVKITPRO)/libnx/switch_rules + EXT=a + TARGET := $(TARGET_NAME)_libretro_$(platform).$(EXT) + DEFINES := -DSWITCH=1 -U__linux__ -U__linux -DRARCH_INTERNAL + CFLAGS := $(DEFINES) -g \ + -O2 \ -fPIE -I$(LIBNX)/include/ -ffunction-sections -fdata-sections -ftls-model=local-exec -Wl,--allow-multiple-definition -specs=$(LIBNX)/switch.specs - CFLAGS += $(INCDIRS) - CFLAGS += $(INCLUDE) -D__SWITCH__ -DHAVE_LIBNX - CXXFLAGS := $(ASFLAGS) $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11 - CFLAGS += -std=gnu11 - PLATFORM_DEFINES += -DARM -march=armv8-a -mtune=cortex-a57 -mtp=soft - STATIC_LINKING = 1 + CFLAGS += $(INCDIRS) + CFLAGS += $(INCLUDE) -D__SWITCH__ -DHAVE_LIBNX + # Replaced -fno-rtti -fno-exceptions with -fexceptions, using C++14 + CXXFLAGS := $(ASFLAGS) $(CFLAGS) -fexceptions -std=c++14 + CFLAGS += -std=gnu11 + PLATFORM_DEFINES += -DARM -march=armv8-a -mtune=cortex-a57 -mtp=soft + STATIC_LINKING = 1 + #PLATFORM_DEFINES += -D_INCL_PHYSFS_PLATFORMS -DPHYSFS_PLATFORM_UNIX=1 -DPHYSFS_PLATFORM_POSIX=1 + #PLATFORM_DEFINES += -Dpthread_t=Thread -Dpthread_mutex_t=Mutex -Dpthread_mutexattr_t='void*' -Dpthread_attr_t=int -Dpthread_cond_t=CondVar -Dpthread_condattr_t='int' -D_SYS__PTHREADTYPES_H_ # ARM else ifneq (,$(findstring armv,$(platform))) diff --git a/docs/Doxyfile b/docs/Doxyfile index 1878557ee..73b362898 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -23,7 +23,7 @@ PROJECT_NAME = "ChaiLove API" # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = "0.29.0" +PROJECT_NUMBER = "0.29.1" # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. diff --git a/src/ChaiLove.h b/src/ChaiLove.h index a90fbf4a0..dbae5bec5 100644 --- a/src/ChaiLove.h +++ b/src/ChaiLove.h @@ -48,8 +48,8 @@ #define CHAILOVE_VERSION_MAJOR 0 #define CHAILOVE_VERSION_MINOR 29 -#define CHAILOVE_VERSION_PATCH 0 -#define CHAILOVE_VERSION_STRING "0.29.0" +#define CHAILOVE_VERSION_PATCH 1 +#define CHAILOVE_VERSION_STRING "0.29.1" #include "SDL.h" #include "libretro.h" diff --git a/src/love/Types/FileSystem/FileData.cpp b/src/love/Types/FileSystem/FileData.cpp index 3a57264f8..77c354f07 100644 --- a/src/love/Types/FileSystem/FileData.cpp +++ b/src/love/Types/FileSystem/FileData.cpp @@ -4,7 +4,6 @@ #include #include -#include "filesystem/path.h" #include "../../../ChaiLove.h" @@ -38,9 +37,8 @@ std::string FileData::getString() { } std::string FileData::getExtension() { - ::filesystem::path p(m_filepath.c_str()); - std::string extension(p.extension()); - return extension; + ChaiLove* app = ChaiLove::getInstance(); + return app->filesystem.getFileExtension(m_filepath); } } // namespace FileSystem diff --git a/src/love/audio.cpp b/src/love/audio.cpp index 2d65ef2e4..5cbfd817c 100644 --- a/src/love/audio.cpp +++ b/src/love/audio.cpp @@ -3,7 +3,6 @@ #include "Types/Audio/SoundData.h" #include "../ChaiLove.h" #include "sound.h" -#include "physfs.h" #include "audio/conversion/float_to_s16.h" using love::Types::Audio::SoundData; diff --git a/src/love/filesystem.cpp b/src/love/filesystem.cpp index 02e5df83b..65f32b709 100644 --- a/src/love/filesystem.cpp +++ b/src/love/filesystem.cpp @@ -5,7 +5,6 @@ #include "physfs.h" #include "filesystem.h" #include "physfsrwops.h" -#include "filesystem/path.h" #include "../ChaiLove.h" #include "Types/FileSystem/FileInfo.h" @@ -32,8 +31,7 @@ bool filesystem::init(const std::string& file, const void* data) { } // Find the parent and extension of the given file. - ::filesystem::path p(file.c_str()); - std::string extension(p.extension()); + std::string extension(getFileExtension(file)); // Allow loading from an Archive. if (extension == "chaigame" || extension == "chailove" || extension == "zip") { @@ -41,8 +39,7 @@ bool filesystem::init(const std::string& file, const void* data) { } // If we are just running the core, load the base path. - ::filesystem::path parent(p.parent_path()); - std::string parentPath(parent.str()); + std::string parentPath(getParentDirectory(file)); if (parentPath.empty()) { return mount(".", "/", false); } @@ -51,6 +48,36 @@ bool filesystem::init(const std::string& file, const void* data) { return mount(parentPath.c_str(), "/", false); } +std::string filesystem::getParentDirectory(const std::string& filepath) { + size_t last = filepath.find_last_of("/\\"); + if (last != std::string::npos) { + return filepath.substr(0, last); + } + return ""; +} + +std::string filesystem::getFileExtension(const std::string& filepath) { + size_t i = filepath.rfind('.', filepath.length()); + if (i != std::string::npos) { + return filepath.substr(i + 1, filepath.length() - i); + } + return ""; +} + +std::string filesystem::getBasename(const std::string& filepath) { + char sep = '/'; + if (filepath.find('\\') != std::string::npos) { + sep = '\\'; + } + + size_t i = filepath.rfind(sep, filepath.length()); + if (i != std::string::npos) { + return filepath.substr(i + 1, filepath.length() - i); + } + + return filepath; +} + void filesystem::mountlibretro() { // Mount some of the libretro directories. const char *system_dir = NULL; @@ -60,8 +87,8 @@ void filesystem::mountlibretro() { if (ChaiLove::environ_cb(RETRO_ENVIRONMENT_GET_LIBRETRO_PATH, &core_dir) && core_dir) { // Make sure to get the directory of the core. - ::filesystem::path p(core_dir); - mount(p.parent_path().str(), "/libretro/core", false); + std::string parentPath(getParentDirectory(core_dir)); + mount(parentPath, "/libretro/core", false); } if (ChaiLove::environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &system_dir) && system_dir) { mount(system_dir, "/libretro/system", false); diff --git a/src/love/filesystem.h b/src/love/filesystem.h index a848dccde..1018e299c 100644 --- a/src/love/filesystem.h +++ b/src/love/filesystem.h @@ -78,6 +78,10 @@ class filesystem { */ int getSize(const std::string& file); + std::string getFileExtension(const std::string& filepath); + std::string getBasename(const std::string& filepath); + std::string getParentDirectory(const std::string& filepath); + /** * Removes a file or empty directory. * diff --git a/src/love/script.cpp b/src/love/script.cpp index 9576853a5..e1ac536fc 100644 --- a/src/love/script.cpp +++ b/src/love/script.cpp @@ -1,10 +1,10 @@ #include "script.h" #include "../ChaiLove.h" -#include #include #ifdef __HAVE_CHAISCRIPT__ #include "chaiscript/extras/math.hpp" +#include "chaiscript/extras/string_methods.hpp" using namespace chaiscript; #endif @@ -35,7 +35,7 @@ bool script::loadModule(const std::string& moduleName) { // See if we are to append .chai. filename = filename + ".chai"; if (!app->filesystem.exists(filename)) { - std::cout << "[ChaiLove] [script] Module " << moduleName << " not found." << std::endl; + std::cout << "[ChaiLove] [script] Module " << filename << " not found." << std::endl; return false; } } @@ -45,7 +45,7 @@ bool script::loadModule(const std::string& moduleName) { // Make sure it was not empty. if (contents.empty()) { - std::cout << "[ChaiLove] [script] Module " << moduleName << " was loaded, but empty." << std::endl; + std::cout << "[ChaiLove] [script] Module " << filename << " was loaded, but empty." << std::endl; return false; } @@ -85,6 +85,7 @@ std::string script::evalString(const std::string& code, const std::string& filen script::script(const std::string& file) { #ifdef __HAVE_CHAISCRIPT__ + ChaiLove* app = ChaiLove::getInstance(); // ChaiScript Standard Library Additions // This adds some basic type definitions to ChaiScript. @@ -92,53 +93,8 @@ script::script(const std::string& file) { chai.add(bootstrap::standard_library::vector_type>("StringVector")); chai.add(bootstrap::standard_library::map_type>("StringBoolMap")); - // Global Helpers - // string::replace(std::string search, std::string replace) - chai.add(fun([](const std::string& subject, const std::string& search, const std::string& replace) { - std::string newSubject(subject); - size_t pos = 0; - while ((pos = newSubject.find(search, pos)) != std::string::npos) { - newSubject.replace(pos, search.length(), replace); - pos += replace.length(); - } - return newSubject; - }), "replace"); - - // string::replace(char search, char replace) - chai.add(fun([](const std::string& subject, char search, char replace) { - std::string newSubject(subject); - std::replace(newSubject.begin(), newSubject.end(), search, replace); - return newSubject; - }), "replace"); - - // string::trim() - chai.add(fun([](const std::string& subject) { - std::string result(subject); - std::string chars = "\t\n\v\f\r "; - result.erase(0, result.find_first_not_of(chars)); - result.erase(0, result.find_last_not_of(chars)); - return result; - }), "trim"); - - // string::split() - chai.add(fun([](const std::string& subject, const std::string& token) { - std::string str(subject); - std::vector result; - while (str.size()) { - int index = str.find(token); - if (index != std::string::npos) { - result.push_back(str.substr(0, index)); - str = str.substr(index + token.size()); - if (str.size() == 0) { - result.push_back(str); - } - } else { - result.push_back(str); - str = ""; - } - } - return result; - }), "split"); + auto stringmethods = chaiscript::extras::string_methods::bootstrap(); + chai.add(stringmethods); // List auto listModule = std::make_shared(); @@ -355,6 +311,9 @@ script::script(const std::string& file) { chai.add(fun, filesystem, const std::string&, const std::string&>(&filesystem::lines), "lines"); chai.add(fun(&filesystem::load), "load"); chai.add(fun(&script::loadModuleRequire, this), "require"); + chai.add(fun(&filesystem::getFileExtension), "getFileExtension"); + chai.add(fun(&filesystem::getBasename), "getBasename"); + chai.add(fun(&filesystem::getParentDirectory), "getParentDirectory"); // System chai.add(fun(&system::getOS), "getOS"); @@ -432,18 +391,18 @@ script::script(const std::string& file) { // Load the desired main.chai file. if (file.empty()) { // When no content is provided, display a No Game demo. - eval(ChaiLove::getInstance()->demo(), "demo.chai"); + eval(app->demo(), "demo.chai"); mainLoaded = true; } else { // Load the main.chai file. - ::filesystem::path p(file.c_str()); - std::string extension(p.extension()); loadModuleRequire("conf"); + + std::string extension(app->filesystem.getFileExtension(file)); if (extension == "chailove" || extension == "chaigame") { mainLoaded = loadModuleRequire("main"); } else { // Otherwise, load the actual file. - std::string filename(p.filename()); + std::string filename(app->filesystem.getBasename(file)); mainLoaded = loadModuleRequire(filename); } } diff --git a/test/unittests/filesystem.chai b/test/unittests/filesystem.chai index 9cd6c81ea..2e3a2154c 100644 --- a/test/unittests/filesystem.chai +++ b/test/unittests/filesystem.chai @@ -102,3 +102,15 @@ requiretestFileLoaded = false requireReturn = require("assets.requiretest") assert(requireReturn, " double call") assert_not(requiretestFileLoaded, " not loaded twice") + +// getFileExtension() +assert_equal(love.filesystem.getFileExtension("/opt/var/something.txt"), "txt", "love.filesystem.getFileExtension()") +assert_equal(love.filesystem.getFileExtension("/opt/var/something.tar.gz"), "gz", "love.filesystem.getFileExtension()") + +// getBasename +assert_equal(love.filesystem.getBasename("/opt/var/something.txt"), "something.txt", "love.filesystem.getBasename()") +assert_equal(love.filesystem.getBasename("something.txt"), "something.txt", "love.filesystem.getBasename()") + +// getParentDirectory +assert_equal(love.filesystem.getParentDirectory("/opt/var/something.txt"), "/opt/var", "love.filesystem.getParentDirectory()") +assert_equal(love.filesystem.getParentDirectory("something.txt"), "", "love.filesystem.getParentDirectory()") diff --git a/vendor/ChaiScript_Extras b/vendor/ChaiScript_Extras index 7043c1210..4f3ee0219 160000 --- a/vendor/ChaiScript_Extras +++ b/vendor/ChaiScript_Extras @@ -1 +1 @@ -Subproject commit 7043c12105f20baec7655e62563796ca43535557 +Subproject commit 4f3ee02194411edc5b7aa80d109e400d3b94c15d diff --git a/vendor/cppcodec b/vendor/cppcodec index 302dc28f8..82d011756 160000 --- a/vendor/cppcodec +++ b/vendor/cppcodec @@ -1 +1 @@ -Subproject commit 302dc28f8fd5c8bf2ea8d7212aed3be884d5d166 +Subproject commit 82d011756adfece7506728b4fa9e7354cbe58641 diff --git a/vendor/didstopia-physfs b/vendor/didstopia-physfs index fe12df085..3ae84ee5d 160000 --- a/vendor/didstopia-physfs +++ b/vendor/didstopia-physfs @@ -1 +1 @@ -Subproject commit fe12df08508044287aba2317e13cd91596af5af1 +Subproject commit 3ae84ee5d0a0af72a6a808a32b63e1ea0076f2be diff --git a/vendor/filesystem b/vendor/filesystem deleted file mode 160000 index 0a539a6c9..000000000 --- a/vendor/filesystem +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0a539a6c988dc8691af317e077893e831dee2908 diff --git a/vendor/libretro-common b/vendor/libretro-common index 29905d94e..4f99997d9 160000 --- a/vendor/libretro-common +++ b/vendor/libretro-common @@ -1 +1 @@ -Subproject commit 29905d94e39090dbde5f9e6d726eb2510618704a +Subproject commit 4f99997d94bbfed63d957153976dd9a43c73aced diff --git a/vendor/random b/vendor/random index 2cdf5dc1b..985de84de 160000 --- a/vendor/random +++ b/vendor/random @@ -1 +1 @@ -Subproject commit 2cdf5dc1b22a390f1a09008a98c56a7604d27597 +Subproject commit 985de84de4ec891ce060c4c6579cf70d3c1c86e2