From bfd8d023db7b6be9dff11a781372c382a27e053b Mon Sep 17 00:00:00 2001 From: Rafaël Carré Date: Fri, 18 Jun 2010 13:10:14 +0000 Subject: FS#11347 by me: *dir LUA functions: luadir module mkdir and rmdir are now in this module and not in the rockbox API implements the 'dir' iterator to browse directories Based on LuaFileSystem : http://www.keplerproject.org/luafilesystem git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26913 a1c6a512-1295-4272-9138-f99709370657 --- apps/plugins/lua/SOURCES | 1 + apps/plugins/lua/luadir.c | 138 ++++++++++++++++++++++++++++++++++++++++ apps/plugins/lua/luadir.h | 9 +++ apps/plugins/lua/rocklib_aux.pl | 2 + apps/plugins/lua/rocklua.c | 2 + 5 files changed, 152 insertions(+) create mode 100644 apps/plugins/lua/luadir.c create mode 100644 apps/plugins/lua/luadir.h diff --git a/apps/plugins/lua/SOURCES b/apps/plugins/lua/SOURCES index 7354fdc821..048999d2d1 100644 --- a/apps/plugins/lua/SOURCES +++ b/apps/plugins/lua/SOURCES @@ -39,3 +39,4 @@ strtoul.c strtol.c strstr.c rocklua.c +luadir.c diff --git a/apps/plugins/lua/luadir.c b/apps/plugins/lua/luadir.c new file mode 100644 index 0000000000..730c40ce22 --- /dev/null +++ b/apps/plugins/lua/luadir.c @@ -0,0 +1,138 @@ +/* + * Based on LuaFileSystem : http://www.keplerproject.org/luafilesystem + * + * Copyright © 2003 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 "plugin.h" +#include "rocklibc.h" + +#include "lauxlib.h" +#include "luadir.h" + +#define DIR_METATABLE "directory metatable" +typedef struct dir_data { + int closed; + DIR *dir; +} dir_data; + +static int make_dir (lua_State *L) { + const char *path = luaL_checkstring (L, 1); + lua_pushboolean (L, !rb->mkdir(path)); + return 1; +} + +static int remove_dir (lua_State *L) { + const char *path = luaL_checkstring (L, 1); + lua_pushboolean (L, !rb->rmdir (path)); + return 1; +} + +/* +** Directory iterator +*/ +static int dir_iter (lua_State *L) { + struct dirent *entry; + dir_data *d = (dir_data *)luaL_checkudata (L, 1, DIR_METATABLE); + luaL_argcheck (L, !d->closed, 1, "closed directory"); + + if ((entry = rb->readdir (d->dir)) != NULL) { + lua_pushstring (L, entry->d_name); + lua_pushboolean (L, entry->attribute & ATTR_DIRECTORY); + return 2; + } else { + /* no more entries => close directory */ + rb->closedir (d->dir); + d->closed = 1; + return 0; + } +} + + +/* +** Closes directory iterators +*/ +static int dir_close (lua_State *L) { + dir_data *d = (dir_data *)lua_touserdata (L, 1); + + if (!d->closed && d->dir) { + rb->closedir (d->dir); + d->closed = 1; + } + + return 0; +} + + +/* +** Factory of directory iterators +*/ +static int dir_iter_factory (lua_State *L) { + const char *path = luaL_checkstring (L, 1); + dir_data *d; + lua_pushcfunction (L, dir_iter); + d = (dir_data *) lua_newuserdata (L, sizeof(dir_data)); + d->closed = 0; + + luaL_getmetatable (L, DIR_METATABLE); + lua_setmetatable (L, -2); + d->dir = rb->opendir (path); + if (d->dir == NULL) + luaL_error (L, "cannot open %s: %d", path, errno); + + return 2; +} + + +/* +** Creates directory metatable. +*/ +static int dir_create_meta (lua_State *L) { + luaL_newmetatable (L, DIR_METATABLE); + /* set its __gc field */ + lua_pushstring (L, "__index"); + lua_newtable(L); + lua_pushstring (L, "next"); + lua_pushcfunction (L, dir_iter); + lua_settable(L, -3); + lua_pushstring (L, "close"); + lua_pushcfunction (L, dir_close); + lua_settable(L, -3); + lua_settable (L, -3); + lua_pushstring (L, "__gc"); + lua_pushcfunction (L, dir_close); + lua_settable (L, -3); + return 1; +} + +static const struct luaL_reg fslib[] = { + {"dir", dir_iter_factory}, + {"mkdir", make_dir}, + {"rmdir", remove_dir}, + {NULL, NULL}, +}; + +int luaopen_luadir (lua_State *L) { + dir_create_meta (L); + luaL_register (L, LUA_DIRLIBNAME, fslib); + return 1; +} diff --git a/apps/plugins/lua/luadir.h b/apps/plugins/lua/luadir.h new file mode 100644 index 0000000000..80c3c3b92f --- /dev/null +++ b/apps/plugins/lua/luadir.h @@ -0,0 +1,9 @@ +/* +** LuaFileSystem +** Copyright Kepler Project 2003 (http://www.keplerproject.org/luafilesystem) +** +** $Id: lfs.h,v 1.5 2008/02/19 20:08:23 mascarenhas Exp $ +*/ + +int luaopen_luadir (lua_State *L); +#define LUA_DIRLIBNAME "luadir" diff --git a/apps/plugins/lua/rocklib_aux.pl b/apps/plugins/lua/rocklib_aux.pl index 77fd08b119..9103fccbda 100755 --- a/apps/plugins/lua/rocklib_aux.pl +++ b/apps/plugins/lua/rocklib_aux.pl @@ -54,6 +54,8 @@ my @forbidden_functions = ('^open$', '^close$', '^read$', '^write$', + '^mkdir$', + '^rmdir$', '^lseek$', '^ftruncate$', '^filesize$', diff --git a/apps/plugins/lua/rocklua.c b/apps/plugins/lua/rocklua.c index 395cde8d9d..b92c274fb0 100644 --- a/apps/plugins/lua/rocklua.c +++ b/apps/plugins/lua/rocklua.c @@ -26,6 +26,7 @@ #include "lualib.h" #include "rocklib.h" #include "rockmalloc.h" +#include "luadir.h" PLUGIN_HEADER @@ -39,6 +40,7 @@ static const luaL_Reg lualibs[] = { {LUA_IOLIBNAME, luaopen_io}, {LUA_LOADLIBNAME, luaopen_package}, {LUA_MATHLIBNAME, luaopen_math}, + {LUA_DIRLIBNAME, luaopen_luadir}, {NULL, NULL} }; -- cgit v1.2.3