Implement a function to list directories recursively

develop
lethosor 2015-01-30 17:29:17 -05:00
parent 3ab558c72d
commit 066adfdf95
3 changed files with 66 additions and 0 deletions

@ -2007,8 +2007,41 @@ static int filesystem_listdir(lua_State *L)
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}
};

@ -47,6 +47,7 @@ SOFTWARE.
#pragma once
#include "Export.h"
#include <map>
#include <vector>
#ifndef _WIN32
@ -158,5 +159,7 @@ namespace DFHack {
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 = "");
}
}

@ -172,3 +172,33 @@ int Filesystem::listdir (std::string dir, std::vector<std::string> &files)
return 0;
}
int Filesystem::listdir_recursive (std::string dir, std::map<std::string, bool> &files,
int depth /* = 10 */, std::string prefix /* = "" */)
{
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));
}
}
}