Add Lua callbacks that will walk a directory tree and return values as a table

This commit is contained in:
Alexander Bock
2017-06-02 11:50:55 -04:00
parent b3cb3794ef
commit bb3256d9e4
3 changed files with 183 additions and 52 deletions
+30
View File
@@ -428,6 +428,36 @@ void ScriptEngine::addBaseLibrary() {
"string, string",
"Registers a new path token provided by the first argument to the path "
"provided in the second argument"
},
{
"walkDirectory",
&luascriptfunctions::walkDirectory,
"string [bool, bool]",
"Walks a directory and returns all contents (files and directories) of "
"the directory as absolute paths. The first argument is the path of the "
"directory that should be walked, the second argument determines if the "
"walk is recursive and will continue in contained directories. The third "
"argument determines whether the table that is returned is sorted."
},
{
"walkDirectoryFiles",
&luascriptfunctions::walkDirectoryFiles,
"string [bool, bool]",
"Walks a directory and returns the files of the directory as absolute "
"paths. The first argument is the path of the directory that should be "
"walked, the second argument determines if the walk is recursive and "
"will continue in contained directories. The third argument determines "
"whether the table that is returned is sorted."
},
{
"walkDirectoryFolder",
&luascriptfunctions::walkDirectoryFolder,
"string [bool, bool]",
"Walks a directory and returns the subfolders of the directory as "
"absolute paths. The first argument is the path of the directory that "
"should be walked, the second argument determines if the walk is "
"recursive and will continue in contained directories. The third "
"argument determines whether the table that is returned is sorted."
}
}
};
+152 -51
View File
@@ -22,15 +22,75 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#include <ghoul/filesystem/directory.h>
namespace openspace {
namespace luascriptfunctions {
namespace {
using walkFunc = std::vector<std::string>(ghoul::filesystem::Directory::*)(
ghoul::filesystem::Directory::Recursive, ghoul::filesystem::Directory::Sort) const;
// Defining a common walk function that works off a pointer-to-member function (defined
// above) allows us to easily reuse this code
int walkCommon(lua_State* L, walkFunc func) {
// @CPP17 Replace with std::invoke
#define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember))
using namespace ghoul::filesystem;
const int nArguments = lua_gettop(L);
if (nArguments < 1 || nArguments > 3) {
return luaL_error(L, "Expected %i-%i arguments, got %i", 1, 3, nArguments);
}
std::vector<std::string> result;
if (nArguments == 1) {
// Only the path was passed
const std::string path = luaL_checkstring(L, -1);
result = CALL_MEMBER_FN(Directory(path), func)(
ghoul::filesystem::Directory::Recursive::No,
ghoul::filesystem::Directory::Sort::No
);
}
else if (nArguments == 2) {
// The path and the recursive value were passed
const std::string path = luaL_checkstring(L, -2);
const bool recursive = lua_toboolean(L, -1) != 0;
result = CALL_MEMBER_FN(Directory(path), func)(
ghoul::filesystem::Directory::Recursive(recursive),
ghoul::filesystem::Directory::Sort::No
);
}
else if (nArguments == 3) {
// All three arguments were passed
const std::string path = luaL_checkstring(L, -3);
const bool recursive = lua_toboolean(L, -2) != 0;
const bool sorted = lua_toboolean(L, -1) != 0;
result = CALL_MEMBER_FN(Directory(path), func)(
ghoul::filesystem::Directory::Recursive(recursive),
ghoul::filesystem::Directory::Sort(sorted)
);
}
// Copy values into the lua_State
lua_newtable(L);
for (int i = 0; i < result.size(); ++i) {
lua_pushstring(L, result[i].c_str());
lua_rawseti(L, -2, i + 1);
}
return 1;
}
} // namespace
int printInternal(ghoul::logging::LogLevel level, lua_State* L) {
using ghoul::lua::luaTypeToString;
const std::string _loggerCat = "print";
int nArguments = lua_gettop(L);
const int nArguments = lua_gettop(L);
if (nArguments != 1) {
return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments);
}
@@ -61,79 +121,79 @@ int printInternal(ghoul::logging::LogLevel level, lua_State* L) {
}
/**
* \ingroup LuaScripts
* printTrace(*):
* Logs the passed value to the installed LogManager with a LogLevel of 'Trace'.
* For Boolean, numbers, and strings, the internal values are printed, for all other
* types, the type is printed instead
*/
* \ingroup LuaScripts
* printTrace(*):
* Logs the passed value to the installed LogManager with a LogLevel of 'Trace'.
* For Boolean, numbers, and strings, the internal values are printed, for all other
* types, the type is printed instead
*/
int printTrace(lua_State* L) {
return printInternal(ghoul::logging::LogLevel::Trace, L);
}
/**
* \ingroup LuaScripts
* printDebug(*):
* Logs the passed value to the installed LogManager with a LogLevel of 'Debug'.
* For Boolean, numbers, and strings, the internal values are printed, for all other
* types, the type is printed instead
*/
* \ingroup LuaScripts
* printDebug(*):
* Logs the passed value to the installed LogManager with a LogLevel of 'Debug'.
* For Boolean, numbers, and strings, the internal values are printed, for all other
* types, the type is printed instead
*/
int printDebug(lua_State* L) {
return printInternal(ghoul::logging::LogLevel::Debug, L);
}
/**
* \ingroup LuaScripts
* printInfo(*):
* Logs the passed value to the installed LogManager with a LogLevel of 'Info'.
* For Boolean, numbers, and strings, the internal values are printed, for all other
* types, the type is printed instead
*/
* \ingroup LuaScripts
* printInfo(*):
* Logs the passed value to the installed LogManager with a LogLevel of 'Info'.
* For Boolean, numbers, and strings, the internal values are printed, for all other
* types, the type is printed instead
*/
int printInfo(lua_State* L) {
return printInternal(ghoul::logging::LogLevel::Info, L);
}
/**
* \ingroup LuaScripts
* printWarning(*):
* Logs the passed value to the installed LogManager with a LogLevel of 'Warning'.
* For Boolean, numbers, and strings, the internal values are printed, for all other
* types, the type is printed instead
*/
* \ingroup LuaScripts
* printWarning(*):
* Logs the passed value to the installed LogManager with a LogLevel of 'Warning'.
* For Boolean, numbers, and strings, the internal values are printed, for all other
* types, the type is printed instead
*/
int printWarning(lua_State* L) {
return printInternal(ghoul::logging::LogLevel::Warning, L);
}
/**
* \ingroup LuaScripts
* printError(*):
* Logs the passed value to the installed LogManager with a LogLevel of 'Error'.
* For Boolean, numbers, and strings, the internal values are printed, for all other
* types, the type is printed instead
*/
* \ingroup LuaScripts
* printError(*):
* Logs the passed value to the installed LogManager with a LogLevel of 'Error'.
* For Boolean, numbers, and strings, the internal values are printed, for all other
* types, the type is printed instead
*/
int printError(lua_State* L) {
return printInternal(ghoul::logging::LogLevel::Error, L);
}
/**
* \ingroup LuaScripts
* printFatal(*):
* Logs the passed value to the installed LogManager with a LogLevel of 'Fatal'.
* For Boolean, numbers, and strings, the internal values are printed, for all other
* types, the type is printed instead
*/
* \ingroup LuaScripts
* printFatal(*):
* Logs the passed value to the installed LogManager with a LogLevel of 'Fatal'.
* For Boolean, numbers, and strings, the internal values are printed, for all other
* types, the type is printed instead
*/
int printFatal(lua_State* L) {
return printInternal(ghoul::logging::LogLevel::Fatal, L);
}
/**
* \ingroup LuaScripts
* absPath(string):
* Passes the argument to FileSystem::absolutePath, which resolves occuring path
* tokens and returns the absolute path.
*/
* \ingroup LuaScripts
* absPath(string):
* Passes the argument to FileSystem::absolutePath, which resolves occuring path
* tokens and returns the absolute path.
*/
int absolutePath(lua_State* L) {
int nArguments = lua_gettop(L);
const int nArguments = lua_gettop(L);
if (nArguments != 1) {
return luaL_error(L, "Expected %d arguments, got %d", 1, nArguments);
}
@@ -145,19 +205,19 @@ int absolutePath(lua_State* L) {
}
/**
* \ingroup LuaScripts
* setPathToken(string, string):
* Registers the path token provided by the first argument to the path in the second
* argument. If the path token already exists, it will be silently overridden.
*/
* \ingroup LuaScripts
* setPathToken(string, string):
* Registers the path token provided by the first argument to the path in the second
* argument. If the path token already exists, it will be silently overridden.
*/
int setPathToken(lua_State* L) {
int nArguments = lua_gettop(L);
const int nArguments = lua_gettop(L);
if (nArguments != 2) {
return luaL_error(L, "Expected %i arguments, got %i", 2, nArguments);
}
std::string path = luaL_checkstring(L, -1);
std::string pathToken = luaL_checkstring(L, -2);
const std::string path = luaL_checkstring(L, -1);
const std::string pathToken = luaL_checkstring(L, -2);
FileSys.registerPathToken(
pathToken,
path,
@@ -166,6 +226,47 @@ int setPathToken(lua_State* L) {
return 0;
}
/**
* \ingroup LuaScripts
* walkDirectory(string, bool, bool):
* Walks a directory and returns the contents of the directory as absolute paths. The
* first argument is the path of the directory that should be walked, the second argument
* determines if the walk is recursive and will continue in contained directories. The
* default value for this parameter is "false". The third argument determines whether the
* table that is returned is sorted. The default value for this parameter is "false".
*/
int walkDirectory(lua_State* L) {
return walkCommon(L, &ghoul::filesystem::Directory::read);
}
/**
* \ingroup LuaScripts
* walkDirectoryFiles(string, bool, bool):
* Walks a directory and returns the files of the directory as absolute paths. The first
* argument is the path of the directory that should be walked, the second argument
* determines if the walk is recursive and will continue in contained directories. The
* default value for this parameter is "false". The third argument determines whether the
* table that is returned is sorted. The default value for this parameter is "false".
*/
int walkDirectoryFiles(lua_State* L) {
return walkCommon(L, &ghoul::filesystem::Directory::readFiles);
}
/**
* \ingroup LuaScripts
* walkDirectory(string, bool, bool):
* Walks a directory and returns the subfolders of the directory as absolute paths. The
* first argument is the path of the directory that should be walked, the second argument
* determines if the walk is recursive and will continue in contained directories. The
* default value for this parameter is "false". The third argument determines whether the
* table that is returned is sorted. The default value for this parameter is "false".
*/
int walkDirectoryFolder(lua_State* L) {
return walkCommon(L, &ghoul::filesystem::Directory::readDirectories);
}
} // namespace luascriptfunctions
} // namespace openspace