summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2015-05-19 11:42:14 +0800
committerruki <[email protected]>2015-05-19 11:42:14 +0800
commit050d1882cf578ca81f92666d42bc005b7c0eb914 (patch)
tree3da2dadd83c155ab2e07811d703172918e03159f
parentf1de3034b9afbb88f83501730bf27c31078818ed (diff)
find and match files or directories
-rw-r--r--core/pkg/tbox.pkg/inc/mac/x64/tbox.config.h2
-rwxr-xr-xcore/pkg/tbox.pkg/inc/tbox/platform/directory.h12
-rwxr-xr-xcore/src/xmake/machine.c4
-rwxr-xr-xcore/src/xmake/makefile1
-rwxr-xr-xcore/src/xmake/os/find.c131
-rw-r--r--xmake/scripts/action/_config.lua2
-rw-r--r--xmake/scripts/base/os.lua45
7 files changed, 192 insertions, 5 deletions
diff --git a/core/pkg/tbox.pkg/inc/mac/x64/tbox.config.h b/core/pkg/tbox.pkg/inc/mac/x64/tbox.config.h
index 7c2999bb0..6779345a4 100644
--- a/core/pkg/tbox.pkg/inc/mac/x64/tbox.config.h
+++ b/core/pkg/tbox.pkg/inc/mac/x64/tbox.config.h
@@ -14,7 +14,7 @@
#define TB_CONFIG_VERSION_ALTER 8
// build version
-#define TB_CONFIG_VERSION_BUILD 201505181139
+#define TB_CONFIG_VERSION_BUILD 201505190824
// small
#define TB_CONFIG_SMALL (0)
diff --git a/core/pkg/tbox.pkg/inc/tbox/platform/directory.h b/core/pkg/tbox.pkg/inc/tbox/platform/directory.h
index ea474114e..23df0b329 100755
--- a/core/pkg/tbox.pkg/inc/tbox/platform/directory.h
+++ b/core/pkg/tbox.pkg/inc/tbox/platform/directory.h
@@ -38,8 +38,16 @@ __tb_extern_c_enter__
/* //////////////////////////////////////////////////////////////////////////////////////
* types
*/
-/// the directory walk func type
-typedef tb_void_t (*tb_directory_walk_func_t)(tb_char_t const* path, tb_file_info_t const* info, tb_cpointer_t priv);
+
+/*! the directory walk func type
+ *
+ * @param path the file path
+ * @param info the file info
+ * @param priv the user private data
+ *
+ * @return continue: tb_true, break: tb_false
+ */
+typedef tb_bool_t (*tb_directory_walk_func_t)(tb_char_t const* path, tb_file_info_t const* info, tb_cpointer_t priv);
/* //////////////////////////////////////////////////////////////////////////////////////
* interfaces
diff --git a/core/src/xmake/machine.c b/core/src/xmake/machine.c
index 3fc303002..476a6a7eb 100755
--- a/core/src/xmake/machine.c
+++ b/core/src/xmake/machine.c
@@ -50,6 +50,7 @@ typedef struct __xm_machine_impl_t
*/
// the os functions
+tb_int_t xm_os_find(lua_State* lua);
tb_int_t xm_os_isdir(lua_State* lua);
tb_int_t xm_os_rmdir(lua_State* lua);
tb_int_t xm_os_mkdir(lua_State* lua);
@@ -82,7 +83,8 @@ tb_int_t xm_preprocessor_loadx(lua_State* lua);
// the os functions
static luaL_Reg const g_os_functions[] =
{
- { "isdir", xm_os_isdir }
+ { "find", xm_os_find }
+, { "isdir", xm_os_isdir }
, { "rmdir", xm_os_rmdir }
, { "mkdir", xm_os_mkdir }
, { "cpdir", xm_os_cpdir }
diff --git a/core/src/xmake/makefile b/core/src/xmake/makefile
index 8d848e904..dc4c1cee5 100755
--- a/core/src/xmake/makefile
+++ b/core/src/xmake/makefile
@@ -14,6 +14,7 @@ xmake_CONFIG = y
xmake_C_FILES += \
xmake \
machine \
+ os/find \
os/isdir \
os/rmdir \
os/mkdir \
diff --git a/core/src/xmake/os/find.c b/core/src/xmake/os/find.c
new file mode 100755
index 000000000..c891b9146
--- /dev/null
+++ b/core/src/xmake/os/find.c
@@ -0,0 +1,131 @@
+/*!The Automatic Cross-platform Build Tool
+ *
+ * XMake is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * XMake is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with XMake;
+ * If not, see <a href="http://www.gnu.org/licenses/"> http://www.gnu.org/licenses/</a>
+ *
+ * Copyright (C) 2009 - 2015, ruki All rights reserved.
+ *
+ * @author ruki
+ * @file find.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "find"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * private implementation
+ */
+static tb_bool_t xm_os_find_walk(tb_char_t const* path, tb_file_info_t const* info, tb_cpointer_t priv)
+{
+ // check
+ tb_value_ref_t tuple = (tb_value_ref_t)priv;
+ tb_assert_and_check_return_val(path && info && tuple, tb_false);
+
+ // the lua
+ lua_State* lua = (lua_State*)tuple[0].ptr;
+ tb_assert_and_check_return_val(lua, tb_false);
+
+ // the pattern
+ tb_char_t const* pattern = (tb_char_t const*)tuple[1].cstr;
+ tb_assert_and_check_return_val(pattern, tb_false);
+
+ // find directory?
+ tb_bool_t findir = tuple[2].b;
+
+ // the count
+ tb_size_t* pcount = &(tuple[3].ul);
+
+ // trace
+ tb_trace_d("path[%c]: %s", info->type == TB_FILE_TYPE_DIRECTORY? 'd' : 'f', path);
+
+ // find file or directory?
+ if ((findir && info->type == TB_FILE_TYPE_DIRECTORY) || (!findir && info->type == TB_FILE_TYPE_FILE))
+ {
+ // done string.match(pattern)
+ lua_getfield(lua, -1, "match");
+ lua_pushstring(lua, path);
+ lua_pushstring(lua, pattern);
+ if (lua_pcall(lua, 2, 1, 0))
+ {
+ // trace
+ tb_printf("error: call string.match(%s, %s) failed: %s!\n", path, pattern, lua_tostring(lua, -1));
+
+ // failed
+ return tb_false;
+ }
+
+ // match ok? save this path
+ if (lua_isstring(lua, -1) && !tb_strcmp(path, lua_tostring(lua, -1)))
+ lua_rawseti(lua, -3, ++*pcount);
+ // pop this return value
+ else lua_pop(lua, 1);
+ }
+
+ // continue
+ return tb_true;
+}
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+tb_int_t xm_os_find(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // get the root directory
+ tb_char_t const* rootdir = luaL_checkstring(lua, 1);
+ tb_check_return_val(rootdir, 0);
+
+ // get the pattern
+ tb_char_t const* pattern = luaL_checkstring(lua, 2);
+ tb_check_return_val(pattern, 0);
+
+ // is recurse?
+ tb_bool_t recurse = lua_toboolean(lua, 3);
+
+ // find directory?
+ tb_bool_t findir = lua_toboolean(lua, 4);
+
+ // init table
+ lua_newtable(lua);
+
+ // get string package
+ lua_getglobal(lua, "string");
+
+ // done os.find(root, name)
+ tb_value_t tuple[4];
+ tuple[0].ptr = lua;
+ tuple[1].cstr = pattern;
+ tuple[2].b = findir;
+ tuple[3].ul = 0;
+ tb_directory_walk(rootdir, recurse, tb_true, xm_os_find_walk, tuple);
+
+ // pop string package
+ lua_pop(lua, 1);
+
+ // return count
+ lua_pushinteger(lua, tuple[3].ul);
+
+ // ok
+ return 2;
+}
diff --git a/xmake/scripts/action/_config.lua b/xmake/scripts/action/_config.lua
index 1af22d27e..46e123800 100644
--- a/xmake/scripts/action/_config.lua
+++ b/xmake/scripts/action/_config.lua
@@ -27,7 +27,7 @@ local _config = _config or {}
local utils = require("base/utils")
local config = require("base/config")
local makefile = require("base/makefile")
-
+
-- done the given config
function _config.done()
diff --git a/xmake/scripts/base/os.lua b/xmake/scripts/base/os.lua
index 7da3d9dcd..31434f37c 100644
--- a/xmake/scripts/base/os.lua
+++ b/xmake/scripts/base/os.lua
@@ -23,6 +23,10 @@
-- define module: os
local os = os or {}
+-- load modules
+local path = require("base/path")
+local utils = require("base/utils")
+
-- copy file or directory
function os.cp(src, dst)
@@ -139,5 +143,46 @@ function os.cd(path)
return true
end
+-- match files or directories
+--
+-- @param pattern the search pattern
+-- uses "*" to match any part of a file or directory name,
+-- uses "**" to recurse into subdirectories.
+--
+-- @param findir true: find directory, false: find file
+-- @return the result array and count
+--
+-- @code
+-- local dirs, count = os.match("./src/*", true)
+-- local files, count = os.match("./src/**.c")
+-- @endcode
+--
+function os.match(pattern, findir)
+
+ -- translate path and remove some repeat separators
+ pattern = path.translate(pattern)
+
+ -- get the root directory
+ local rootdir = pattern
+ local starpos = pattern:find("%*")
+ if starpos then
+ rootdir = rootdir:sub(1, starpos - 1)
+ end
+ rootdir = path.directory(rootdir)
+
+ -- is recurse?
+ local recurse = pattern:find("**", nil, true)
+
+ -- convert pattern to a lua pattern
+ pattern = pattern:gsub("([%+%.%-%^%$%(%)%%])", "%%%1")
+ pattern = pattern:gsub("%*%*", "\001")
+ pattern = pattern:gsub("%*", "\002")
+ pattern = pattern:gsub("\001", ".*")
+ pattern = pattern:gsub("\002", "[^/]*")
+
+ -- find it
+ return os.find(rootdir, pattern, recurse, findir)
+end
+
-- return module: os
return os