From 6fa478de224ccf4a54a073275c30a09a0e61899f Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 14 Jun 2014 21:25:17 -0400 Subject: [PATCH] Filesystem module Implements a handful of filesystem-related functions (e.g. chdir, mkdir) in C++ and Lua. --- library/CMakeLists.txt | 2 + library/LuaApi.cpp | 16 +++ library/include/modules/Filesystem.h | 194 +++++++++++++++++++++++++++ library/modules/Filesystem.cpp | 141 +++++++++++++++++++ 4 files changed, 353 insertions(+) create mode 100644 library/include/modules/Filesystem.h create mode 100644 library/modules/Filesystem.cpp diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 578ce9264..4121ff9e3 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -127,6 +127,7 @@ include/modules/Vermin.h include/modules/World.h include/modules/Graphic.h include/modules/Once.h +include/modules/Filesystem.h ) SET( MODULE_SOURCES @@ -152,6 +153,7 @@ modules/World.cpp modules/Graphic.cpp modules/Windows.cpp modules/Once.cpp +modules/Filesystem.cpp ) IF(WIN32) diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 3a374445f..f81e9274c 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -52,6 +52,7 @@ distribution. #include "modules/Buildings.h" #include "modules/Constructions.h" #include "modules/Random.h" +#include "modules/Filesystem.h" #include "LuaWrapper.h" #include "LuaTools.h" @@ -1923,6 +1924,20 @@ static const luaL_Reg dfhack_screen_funcs[] = { { NULL, NULL } }; +/***** Filesystem module *****/ + +static const LuaWrapper::FunctionReg dfhack_filesystem_module[] = { + WRAPM(Filesystem, getcwd), + WRAPM(Filesystem, chdir), + WRAPM(Filesystem, mkdir), + WRAPM(Filesystem, rmdir), + WRAPM(Filesystem, exists), + WRAPM(Filesystem, isfile), + WRAPM(Filesystem, isdir), + {NULL, NULL} +}; + + /***** Internal module *****/ static void *checkaddr(lua_State *L, int idx, bool allow_null = false) @@ -2265,5 +2280,6 @@ void OpenDFHackApi(lua_State *state) OpenModule(state, "buildings", dfhack_buildings_module, dfhack_buildings_funcs); OpenModule(state, "constructions", dfhack_constructions_module); OpenModule(state, "screen", dfhack_screen_module, dfhack_screen_funcs); + OpenModule(state, "filesystem", dfhack_filesystem_module); OpenModule(state, "internal", dfhack_internal_module, dfhack_internal_funcs); } diff --git a/library/include/modules/Filesystem.h b/library/include/modules/Filesystem.h new file mode 100644 index 000000000..d40fd910e --- /dev/null +++ b/library/include/modules/Filesystem.h @@ -0,0 +1,194 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2012 Petr Mrázek (peterix@gmail.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ +/* Based on luafilesystem +Copyright © 2003-2014 Kepler Project. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, copy, +modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#pragma once +#include "Export.h" + +#ifndef _WIN32 +#ifndef _AIX +#define _FILE_OFFSET_BITS 64 /* Linux, Solaris and HP-UX */ +#else +#define _LARGE_FILES 1 /* AIX */ +#endif +#endif + +#ifndef _LARGEFILE64_SOURCE +#define _LARGEFILE64_SOURCE +#endif + +#include +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#include +#include +#include +#include +#ifdef __BORLANDC__ + #include +#else + #include +#endif +#include +#else +#include +#include +#include +#include +#include +#endif + +#define LFS_VERSION "1.6.2" +#define LFS_LIBNAME "lfs" + +#if LUA_VERSION_NUM < 502 +# define luaL_newlib(L,l) (lua_newtable(L), luaL_register(L,NULL,l)) +#endif + +/* Define 'strerror' for systems that do not implement it */ +#ifdef NO_STRERROR +#define strerror(_) "System unable to describe the error" +#endif + +/* Define 'getcwd' for systems that do not implement it */ +#ifdef NO_GETCWD +#define getcwd(p,s) NULL +#define getcwd_error "Function 'getcwd' not provided by system" +#else +#define getcwd_error strerror(errno) + #ifdef _WIN32 + /* MAX_PATH seems to be 260. Seems kind of small. Is there a better one? */ + #define LFS_MAXPATHLEN MAX_PATH + #else + /* For MAXPATHLEN: */ + #include + #define LFS_MAXPATHLEN MAXPATHLEN + #endif +#endif + +typedef struct dir_data { + int closed; +#ifdef _WIN32 + intptr_t hFile; + char pattern[MAX_PATH+1]; +#else + DIR *dir; +#endif +} dir_data; + +#ifdef _WIN32 + #ifdef __BORLANDC__ + #define lfs_setmode(L,file,m) ((void)L, setmode(_fileno(file), m)) + #define STAT_STRUCT struct stati64 + #else + #define lfs_setmode(L,file,m) ((void)L, _setmode(_fileno(file), m)) + #define STAT_STRUCT struct _stati64 + #endif +#define STAT_FUNC _stati64 +#define LSTAT_FUNC STAT_FUNC +#else +#define _O_TEXT 0 +#define _O_BINARY 0 +#define lfs_setmode(L,file,m) ((void)L, (void)file, (void)m, 0) +#define STAT_STRUCT struct stat +#define STAT_FUNC stat +#define LSTAT_FUNC lstat +#endif + +#ifdef _WIN32 + #ifndef S_ISDIR + #define S_ISDIR(mode) (mode&_S_IFDIR) + #endif + #ifndef S_ISREG + #define S_ISREG(mode) (mode&_S_IFREG) + #endif + #ifndef S_ISLNK + #define S_ISLNK(mode) (0) + #endif + #ifndef S_ISSOCK + #define S_ISSOCK(mode) (0) + #endif + #ifndef S_ISFIFO + #define S_ISFIFO(mode) (0) + #endif + #ifndef S_ISCHR + #define S_ISCHR(mode) (mode&_S_IFCHR) + #endif + #ifndef S_ISBLK + #define S_ISBLK(mode) (0) + #endif +#endif + +enum _filetype { + FILETYPE_NONE = -2, + FILETYPE_UNKNOWN = -1, + FILETYPE_FILE = 1, + FILETYPE_DIRECTORY, + FILETYPE_LINK, + FILETYPE_SOCKET, + FILETYPE_NAMEDPIPE, + FILETYPE_CHAR_DEVICE, + FILETYPE_BLOCK_DEVICE +}; + +namespace DFHack { + namespace Filesystem { + DFHACK_EXPORT bool chdir (std::string path); + DFHACK_EXPORT char * getcwd (); + DFHACK_EXPORT bool mkdir (std::string path); + DFHACK_EXPORT bool rmdir (std::string path); + DFHACK_EXPORT bool stat (std::string path, STAT_STRUCT &info); + DFHACK_EXPORT bool exists (std::string path); + DFHACK_EXPORT _filetype filetype (std::string path); + DFHACK_EXPORT bool isfile (std::string path); + DFHACK_EXPORT bool isdir (std::string path); + } +} diff --git a/library/modules/Filesystem.cpp b/library/modules/Filesystem.cpp new file mode 100644 index 000000000..9f0df3097 --- /dev/null +++ b/library/modules/Filesystem.cpp @@ -0,0 +1,141 @@ +/* +https://github.com/peterix/dfhack +Copyright (c) 2009-2012 Petr Mrázek (peterix@gmail.com) + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ +/* Based on luafilesystem +Copyright © 2003-2014 Kepler Project. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, copy, +modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include + +#include "modules/Filesystem.h" + +bool DFHack::Filesystem::chdir (std::string path) +{ + return !(bool)::chdir(path.c_str()); +} + +char * DFHack::Filesystem::getcwd () +{ + char *path; + char buf[LFS_MAXPATHLEN]; + if ((path = ::getcwd(buf, LFS_MAXPATHLEN)) == NULL) + return NULL; + else + return path; +} + +bool DFHack::Filesystem::mkdir (std::string path) +{ + int fail; +#ifdef _WIN32 + fail = ::_mkdir(path.c_str()); +#else + fail = ::mkdir(path.c_str(), S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | + S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH); +#endif + return !(bool)fail; +} + +bool DFHack::Filesystem::rmdir (std::string path) +{ + int fail; +#ifdef _WIN32 + fail = ::_rmdir(path.c_str()); +#else + fail = ::rmdir(path.c_str()); +#endif + return !(bool)fail; +} + +#ifdef _WIN32 +_filetype *mode2type (unsigned short mode) { +#else +_filetype mode2type (mode_t mode) { +#endif + if (S_ISREG(mode)) + return FILETYPE_FILE; + else if (S_ISDIR(mode)) + return FILETYPE_DIRECTORY; + else if (S_ISLNK(mode)) + return FILETYPE_LINK; + else if (S_ISSOCK(mode)) + return FILETYPE_SOCKET; + else if (S_ISFIFO(mode)) + return FILETYPE_NAMEDPIPE; + else if (S_ISCHR(mode)) + return FILETYPE_CHAR_DEVICE; + else if (S_ISBLK(mode)) + return FILETYPE_BLOCK_DEVICE; + else + return FILETYPE_UNKNOWN; +} + +bool DFHack::Filesystem::stat (std::string path, STAT_STRUCT &info) +{ + return !(bool)(STAT_FUNC(path.c_str(), &info)); +} + +bool DFHack::Filesystem::exists (std::string path) +{ + STAT_STRUCT info; + return (bool)DFHack::Filesystem::stat(path.c_str(), info); +} + +#include +_filetype DFHack::Filesystem::filetype (std::string path) +{ + STAT_STRUCT info; + DFHack::Filesystem::stat(path, info); + std::cout << info.st_mode << std::endl; + return mode2type(info.st_mode); +} + +bool DFHack::Filesystem::isfile (std::string path) +{ + return DFHack::Filesystem::filetype(path) == FILETYPE_FILE; +} + +bool DFHack::Filesystem::isdir (std::string path) +{ + return DFHack::Filesystem::filetype(path) == FILETYPE_DIRECTORY; +}