Merge remote-tracking branches 'lethosor/patch-12' and 'lethosor/fs-expansion' into develop

Conflicts:
	NEWS
develop
expwnent 2015-01-31 20:25:01 -05:00
commit aa5d7c11bc
13 changed files with 319 additions and 165 deletions

@ -106,10 +106,10 @@ If you are building on 10.6, please read the subsection below titled "Snow Leopa
Option 2: Using Homebrew:
* `Install Homebrew <http://brew.sh/>`_ and run:
* ``brew tap lethosor/gcc``
* ``brew tap homebrew/versions``
* ``brew install git``
* ``brew install cmake``
* ``brew install lethosor/gcc/gcc45 --enable-multilib``
* ``brew install gcc45 --enable-multilib``
5. Install perl dependencies

@ -137,3 +137,29 @@ 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.
--------------------------------------------------------------------------
Parts of dfhack are based on luafilesystem:
Copyright (c) 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.

@ -1765,6 +1765,66 @@ Supported callbacks and fields are:
``dfhack.gui.getSelected...`` function.
Filesystem module
-----------------
Most of these functions return ``true`` on success and ``false`` on failure,
unless otherwise noted.
* ``dfhack.filesystem.exists(path)``
Returns ``true`` if ``path`` exists.
* ``dfhack.filesystem.isfile(path)``
Returns ``true`` if ``path`` exists and is a file.
* ``dfhack.filesystem.isdir(path)``
Returns ``true`` if ``path`` exists and is a directory.
* ``dfhack.filesystem.getcwd()``
Returns the current working directory. To retrieve the DF path, use ``dfhack.getDFPath()`` instead.
* ``dfhack.filesystem.chdir(path)``
Changes the current directory to ``path``. Use with caution.
* ``dfhack.filesystem.mkdir(path)``
Creates a new directory. Returns ``false`` if unsuccessful, including if ``path`` already exists.
* ``dfhack.filesystem.rmdir(path)``
Removes a directory. Only works if the directory is already empty.
* ``dfhack.filesystem.mtime(path)``
Returns the modification time (in seconds) of the file or directory specified by ``path``,
or -1 if ``path`` does not exist. This depends on the system clock and should only be used locally.
* ``dfhack.filesystem.atime(path)``
* ``dfhack.filesystem.ctime(path)``
Return values vary across operating systems - return the ``st_atime`` and ``st_ctime``
fields of a C++ stat struct, respectively.
* ``dfhack.filesystem.listdir(path)``
Lists files/directories in a directory. Returns ``{}`` if ``path`` does not exist.
* ``dfhack.filesystem.listdir_recursive(path [, depth = 10])``
Lists all files/directories in a directory and its subdirectories. All directories
are listed before their contents. Returns a table with subtables of the format::
{path: 'path to file', isdir: true|false}
Note that ``listdir()`` returns only the base name of each directory entry, while
``listdir_recursive()`` returns the initial path and all components following it
for each entry.
Internal API
------------
@ -1846,8 +1906,8 @@ and are only documented here for completeness:
* ``dfhack.internal.getDir(path)``
List files in a directory.
Returns: *file_names* or empty table if not found.
Lists files/directories in a directory.
Returns: *file_names* or empty table if not found. Identical to ``dfhack.filesystem.listdir(path)``.
Core interpreter context
========================
@ -3181,7 +3241,7 @@ These events are straight from EventManager module. Each of them first needs to
9. ``onInventoryChange(unit_id,item_id,old_equip,new_equip)``
Gets called when someone picks up an item, puts one down, or changes the way they are holding it. If an item is picked up, old_equip will be null. If an item is dropped, new_equip will be null. If an item is re-equipped in a new way, then neither will be null. You absolutely must NOT alter either old_equip or new_equip or you might break other plugins.
Gets called when someone picks up an item, puts one down, or changes the way they are holding it. If an item is picked up, old_equip will be null. If an item is dropped, new_equip will be null. If an item is re-equipped in a new way, then neither will be null. You absolutely must NOT alter either old_equip or new_equip or you might break other plugins.
10. ``onReport(reportId)``
@ -3220,9 +3280,9 @@ Functions
5. ``registerSidebar(shop_name,callback)``
Enable callback when sidebar for ``shop_name`` is drawn. Usefull for custom workshop views e.g. using gui.dwarfmode lib. Also accepts a ``class`` instead of function
Enable callback when sidebar for ``shop_name`` is drawn. Usefull for custom workshop views e.g. using gui.dwarfmode lib. Also accepts a ``class`` instead of function
as callback. Best used with ``gui.dwarfmode`` class ``WorkshopOverlay``.
Examples
--------
Spawn dragon breath on each item attempt to contaminate wound::
@ -3249,14 +3309,14 @@ Grenade example::
b=require "plugins.eventful"
b.onProjItemCheckImpact.one=function(projectile)
-- you can check if projectile.item e.g. has correct material
dfhack.maps.spawnFlow(projectile.cur_pos,6,0,0,50000)
dfhack.maps.spawnFlow(projectile.cur_pos,6,0,0,50000)
end
Integrated tannery::
b=require "plugins.eventful"
b.addReactionToShop("TAN_A_HIDE","LEATHERWORKS")
Building-hacks
==============
@ -3270,7 +3330,7 @@ Functions
1. name -- custom workshop id e.g. ``SOAPMAKER``
2. fix_impassible -- if true make impassible tiles impassible to liquids too
3. consume -- how much machine power is needed to work. Disables reactions if not supplied enough
4. produce -- how much machine power is produced. Use discouraged as there is no way to change this at runtime
4. produce -- how much machine power is produced. Use discouraged as there is no way to change this at runtime
5. gears -- a table or ``{x=?,y=?}`` of connection points for machines
6. action -- a table of number (how much ticks to skip) and a function which gets called on shop update
7. animate -- a table of frames which can be a table of:
@ -3279,7 +3339,7 @@ Functions
b. empty table (tile not modified) OR
c. ``{x=<number> y=<number> + 4 numbers like in first case}``, this generates full frame useful for animations that change little (1-2 tiles)
8. canBeRoomSubset -- a flag if this building can be counted in room. 1 means it can, 0 means it can't and -1 default building behaviour
Animate table also might contain:
1. frameLenght -- how many ticks does one frame take OR
2. isMechanical -- a bool that says to try to match to mechanical system (i.e. how gears are turning)
@ -3288,13 +3348,13 @@ Examples
--------
Simple mechanical workshop::
require('plugins.building-hacks').registerBuilding{name="BONE_GRINDER",
consume=15,
gears={x=0,y=0}, --connection point
animate={
isMechanical=true, --animate the same connection point as vanilla gear
frames={
frames={
{{x=0,y=0,42,7,0,0}}, --first frame, 1 changed tile
{{x=0,y=0,15,7,0,0}} -- second frame, same
}

@ -2,11 +2,13 @@ DFHack Future
Internals
Lua scripts can set environment variables of each other with dfhack.run_script_with_env.
eventful Lua reactions no longer require LUA_HOOK as a prefix: you can register a callback for the completion of any reaction with a name
Filesystem module now provides file access/modification times and can list directories (normally and recursively)
Fixes
dfhack.run_script should correctly find save-specific scripts now.
Updated add-thought to properly affect stress.
hfs-pit should work now
Autobutcher takes gelding into account
init.lua existence checks should be more reliable (notably when using non-English locales)
New Plugins
New Scripts
New Tweaks

@ -2228,6 +2228,7 @@ directory.
Load and save stockpile settings from the 'q' menu.
Usage:
gui/stockpiles -save to save the current stockpile
gui/stockpiles -load to load settings into the current stockpile
gui/stockpiles -dir <path> set the default directory to save settings into
@ -2357,11 +2358,11 @@ fortplan
========
Usage: fortplan [filename]
Designates furniture for building according to a .csv file with
Designates furniture for building according to a .csv file with
quickfort-style syntax. Companion to digfort.
The first line of the file must contain the following:
#build start(X; Y; <start location description>)
...where X and Y are the offset from the top-left corner of the file's area
@ -2378,7 +2379,7 @@ are supported. All other characters are ignored. For example:
`,f,`,t,`
`,s,b,c,`
This section of a file would designate for construction a door and some
This section of a file would designate for construction a door and some
furniture inside a bedroom: specifically, clockwise from top left, a cabinet,
a table, a chair, a bed, and a statue.

@ -45,6 +45,7 @@ using namespace std;
#include "PluginManager.h"
#include "ModuleFactory.h"
#include "modules/EventManager.h"
#include "modules/Filesystem.h"
#include "modules/Gui.h"
#include "modules/World.h"
#include "modules/Graphic.h"
@ -252,7 +253,7 @@ static std::string getScriptHelp(std::string path, std::string helpprefix)
static void listScripts(PluginManager *plug_mgr, std::map<string,string> &pset, std::string path, bool all, std::string prefix = "")
{
std::vector<string> files;
getdir(path, files);
Filesystem::listdir(path, files);
for (size_t i = 0; i < files.size(); i++)
{

@ -1985,9 +1985,65 @@ static const LuaWrapper::FunctionReg dfhack_filesystem_module[] = {
WRAPM(Filesystem, exists),
WRAPM(Filesystem, isfile),
WRAPM(Filesystem, isdir),
WRAPM(Filesystem, atime),
WRAPM(Filesystem, ctime),
WRAPM(Filesystem, mtime),
{NULL, NULL}
};
static int filesystem_listdir(lua_State *L)
{
luaL_checktype(L,1,LUA_TSTRING);
std::string dir=lua_tostring(L,1);
std::vector<std::string> files;
DFHack::Filesystem::listdir(dir, files);
lua_newtable(L);
for(int i=0;i<files.size();i++)
{
lua_pushinteger(L,i+1);
lua_pushstring(L,files[i].c_str());
lua_settable(L,-3);
}
return 1;
}
static int filesystem_listdir_recursive(lua_State *L)
{
luaL_checktype(L,1,LUA_TSTRING);
std::string dir=lua_tostring(L,1);
int depth = 10;
if (lua_type(L, 2) == LUA_TNUMBER)
depth = lua_tounsigned(L, 2);
std::map<std::string, bool> files;
int err = DFHack::Filesystem::listdir_recursive(dir, files, depth);
if (err)
{
lua_pushnil(L);
lua_pushinteger(L, err);
return 2;
}
lua_newtable(L);
int i = 1;
for (auto it = files.begin(); it != files.end(); ++it)
{
lua_pushinteger(L, i++);
lua_newtable(L);
lua_pushstring(L, "path");
lua_pushstring(L, (it->first).c_str());
lua_settable(L, -3);
lua_pushstring(L, "isdir");
lua_pushboolean(L, it->second);
lua_settable(L, -3);
lua_settable(L, -3);
}
return 1;
}
static const luaL_Reg dfhack_filesystem_funcs[] = {
{"listdir", filesystem_listdir},
{"listdir_recursive", filesystem_listdir_recursive},
{NULL, NULL}
};
/***** Internal module *****/
@ -2280,21 +2336,6 @@ static int internal_diffscan(lua_State *L)
lua_pushnil(L);
return 1;
}
static int internal_getDir(lua_State *L)
{
luaL_checktype(L,1,LUA_TSTRING);
std::string dir=lua_tostring(L,1);
std::vector<std::string> files;
DFHack::getdir(dir,files);
lua_newtable(L);
for(int i=0;i<files.size();i++)
{
lua_pushinteger(L,i+1);
lua_pushstring(L,files[i].c_str());
lua_settable(L,-3);
}
return 1;
}
static int internal_runCommand(lua_State *L)
{
@ -2381,7 +2422,7 @@ static const luaL_Reg dfhack_internal_funcs[] = {
{ "memcmp", internal_memcmp },
{ "memscan", internal_memscan },
{ "diffscan", internal_diffscan },
{ "getDir", internal_getDir },
{ "getDir", filesystem_listdir },
{ "runCommand", internal_runCommand },
{ "getModifiers", internal_getModifiers },
{ NULL, NULL }
@ -2409,6 +2450,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, "filesystem", dfhack_filesystem_module, dfhack_filesystem_funcs);
OpenModule(state, "internal", dfhack_internal_module, dfhack_internal_funcs);
}

@ -23,6 +23,7 @@ distribution.
*/
#include "modules/EventManager.h"
#include "modules/Filesystem.h"
#include "Internal.h"
#include "Core.h"
#include "MemAccess.h"
@ -727,7 +728,7 @@ void PluginManager::init(Core * core)
const string searchstr = ".plug.dll";
#endif
vector <string> filez;
getdir(path, filez);
Filesystem::listdir(path, filez);
for(size_t i = 0; i < filez.size();i++)
{
if(hasEnding(filez[i],searchstr))
@ -757,7 +758,7 @@ Plugin *PluginManager::getPluginByCommand(const std::string &command)
if (iter != belongs.end())
return iter->second;
else
return NULL;
return NULL;
}
// FIXME: handle name collisions...

@ -28,6 +28,8 @@ distribution.
#include "Error.h"
#include "Types.h"
#include "modules/Filesystem.h"
#ifndef LINUX_BUILD
#include <Windows.h>
#include "wdirent.h"
@ -47,17 +49,7 @@ distribution.
int DFHack::getdir(std::string dir, std::vector<std::string> &files)
{
DIR *dp;
struct dirent *dirp;
if((dp = opendir(dir.c_str())) == NULL)
{
return errno;
}
while ((dirp = readdir(dp)) != NULL) {
files.push_back(std::string(dirp->d_name));
}
closedir(dp);
return 0;
return DFHack::Filesystem::listdir(dir, files);
}
bool DFHack::hasEnding (std::string const &fullString, std::string const &ending)

@ -121,4 +121,4 @@ namespace DFHack
DFHACK_EXPORT df::specific_ref *findRef(std::vector<df::specific_ref*> &vec, df::specific_ref_type type);
DFHACK_EXPORT bool removeRef(std::vector<df::specific_ref*> &vec, df::specific_ref_type type, void *ptr);
}// namespace DFHack
}// namespace DFHack

@ -47,19 +47,23 @@ SOFTWARE.
#pragma once
#include "Export.h"
#include <map>
#include <vector>
#ifndef _WIN32
#ifndef _AIX
#define _FILE_OFFSET_BITS 64 /* Linux, Solaris and HP-UX */
#else
#define _LARGE_FILES 1 /* AIX */
#endif
#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
#define _LARGEFILE64_SOURCE
#endif
#include <cstdio>
#include <cstdint>
#include <errno.h>
#include <stdio.h>
#include <string.h>
@ -68,104 +72,64 @@ SOFTWARE.
#include <sys/stat.h>
#ifdef _WIN32
#include <direct.h>
#define NOMINMAX
#include <windows.h>
#include <io.h>
#include <sys/locking.h>
#ifdef __BORLANDC__
#include <utime.h>
#else
#include <sys/utime.h>
#endif
#include <fcntl.h>
#else
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#include <sys/types.h>
#include <utime.h>
#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 <sys/param.h>
#define LFS_MAXPATHLEN MAXPATHLEN
#endif
#endif
typedef struct dir_data {
int closed;
#ifdef _WIN32
intptr_t hFile;
char pattern[MAX_PATH+1];
#include <direct.h>
#define NOMINMAX
#include <windows.h>
#include <io.h>
#include <sys/locking.h>
#ifdef __BORLANDC__
#include <utime.h>
#else
#include <sys/utime.h>
#endif
#include <fcntl.h>
#include "wdirent.h"
#else
DIR *dir;
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#include <sys/types.h>
#include <utime.h>
#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
#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
#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
#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_ISCHR
#define S_ISCHR(mode) (mode&_S_IFCHR)
#endif
#ifndef S_ISBLK
#define S_ISBLK(mode) (0)
#endif
#endif
enum _filetype {
@ -191,5 +155,11 @@ namespace DFHack {
DFHACK_EXPORT _filetype filetype (std::string path);
DFHACK_EXPORT bool isfile (std::string path);
DFHACK_EXPORT bool isdir (std::string path);
DFHACK_EXPORT int64_t atime (std::string path);
DFHACK_EXPORT int64_t ctime (std::string path);
DFHACK_EXPORT int64_t mtime (std::string path);
DFHACK_EXPORT int listdir (std::string dir, std::vector<std::string> &files);
DFHACK_EXPORT int listdir_recursive (std::string dir, std::map<std::string, bool> &files,
int depth = 10, std::string prefix = "");
}
}

@ -484,7 +484,7 @@ if dfhack.is_core_context then
local env = setmetatable({ SAVE_PATH = path }, { __index = base_env })
local f,perr = loadfile(name, 't', env)
if f == nil then
if not string.match(perr, 'No such file or directory') then
if dfhack.filesystem.exists(name) then
dfhack.printerr(perr)
end
elseif safecall(f) then

@ -49,26 +49,28 @@ SOFTWARE.
#include "modules/Filesystem.h"
bool DFHack::Filesystem::chdir (std::string path)
using namespace DFHack;
bool Filesystem::chdir (std::string path)
{
return !(bool)::chdir(path.c_str());
}
std::string DFHack::Filesystem::getcwd ()
std::string Filesystem::getcwd ()
{
char *path;
char buf[LFS_MAXPATHLEN];
char buf[FILENAME_MAX];
std::string result = "";
#ifdef _WIN32
if ((path = ::_getcwd(buf, LFS_MAXPATHLEN)) != NULL)
if ((path = ::_getcwd(buf, FILENAME_MAX)) != NULL)
#else
if ((path = ::getcwd(buf, LFS_MAXPATHLEN)) != NULL)
if ((path = ::getcwd(buf, FILENAME_MAX)) != NULL)
#endif
result = buf;
result = buf;
return result;
}
bool DFHack::Filesystem::mkdir (std::string path)
bool Filesystem::mkdir (std::string path)
{
int fail;
#ifdef _WIN32
@ -80,7 +82,7 @@ bool DFHack::Filesystem::mkdir (std::string path)
return !(bool)fail;
}
bool DFHack::Filesystem::rmdir (std::string path)
bool Filesystem::rmdir (std::string path)
{
int fail;
#ifdef _WIN32
@ -104,8 +106,6 @@ _filetype mode2type (mode_t 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))
@ -114,31 +114,91 @@ _filetype mode2type (mode_t mode) {
return FILETYPE_UNKNOWN;
}
bool DFHack::Filesystem::stat (std::string path, STAT_STRUCT &info)
bool Filesystem::stat (std::string path, STAT_STRUCT &info)
{
return !(bool)(STAT_FUNC(path.c_str(), &info));
}
bool DFHack::Filesystem::exists (std::string path)
bool Filesystem::exists (std::string path)
{
STAT_STRUCT info;
return (bool)DFHack::Filesystem::stat(path.c_str(), info);
return (bool)Filesystem::stat(path, info);
}
#include <iostream>
_filetype DFHack::Filesystem::filetype (std::string path)
_filetype Filesystem::filetype (std::string path)
{
STAT_STRUCT info;
DFHack::Filesystem::stat(path, info);
Filesystem::stat(path, info);
return mode2type(info.st_mode);
}
bool DFHack::Filesystem::isfile (std::string path)
bool Filesystem::isfile (std::string path)
{
return Filesystem::filetype(path) == FILETYPE_FILE;
}
bool Filesystem::isdir (std::string path)
{
return Filesystem::filetype(path) == FILETYPE_DIRECTORY;
}
#define DEFINE_STAT_TIME_WRAPPER(attr) \
int64_t Filesystem::attr (std::string path) \
{ \
STAT_STRUCT info; \
if (!Filesystem::stat(path, info)) \
return -1; \
return (int64_t)info.st_##attr; \
}
DEFINE_STAT_TIME_WRAPPER(atime)
DEFINE_STAT_TIME_WRAPPER(ctime)
DEFINE_STAT_TIME_WRAPPER(mtime)
#undef DEFINE_STAT_TIME_WRAPPER
int Filesystem::listdir (std::string dir, std::vector<std::string> &files)
{
return DFHack::Filesystem::filetype(path) == FILETYPE_FILE;
DIR *dp;
struct dirent *dirp;
if((dp = opendir(dir.c_str())) == NULL)
{
return errno;
}
while ((dirp = readdir(dp)) != NULL) {
files.push_back(std::string(dirp->d_name));
}
closedir(dp);
return 0;
}
bool DFHack::Filesystem::isdir (std::string path)
int Filesystem::listdir_recursive (std::string dir, std::map<std::string, bool> &files,
int depth /* = 10 */, std::string prefix /* = "" */)
{
return DFHack::Filesystem::filetype(path) == FILETYPE_DIRECTORY;
int err;
if (depth < 0)
return -1;
if (prefix == "")
prefix = dir;
std::vector<std::string> tmp;
err = listdir(dir, tmp);
if (err)
return err;
for (auto file = tmp.begin(); file != tmp.end(); ++file)
{
if (*file == "." || *file == "..")
continue;
std::string rel_path = prefix + "/" + *file;
if (isdir(rel_path))
{
files.insert(std::pair<std::string, bool>(rel_path, true));
err = listdir_recursive(dir + "/" + *file, files, depth - 1, rel_path);
if (err)
return err;
}
else
{
files.insert(std::pair<std::string, bool>(rel_path, false));
}
}
}