summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2020-03-25 22:36:06 +0800
committerruki <[email protected]>2020-03-25 09:36:38 +0800
commit6cea9b08790ce55bc278c0567ac0b1d00f896707 (patch)
treee44623cbcd93b04943446c7d86f22d1d65cb678e
parentff2e3546b8622c64889418e077ee1a1038b1d059 (diff)
fix and improve os.args
-rw-r--r--core/src/xmake/machine.c2
-rw-r--r--core/src/xmake/makefile1
-rw-r--r--core/src/xmake/os/args.c126
-rw-r--r--core/src/xmake/os/argv.c2
-rw-r--r--tests/modules/os/test.lua6
-rw-r--r--xmake/core/base/os.lua29
-rw-r--r--xmake/core/sandbox/modules/os.lua1
7 files changed, 136 insertions, 31 deletions
diff --git a/core/src/xmake/machine.c b/core/src/xmake/machine.c
index 625f60f63..70ab72d61 100644
--- a/core/src/xmake/machine.c
+++ b/core/src/xmake/machine.c
@@ -58,6 +58,7 @@ typedef struct __xm_machine_t
// the os functions
tb_int_t xm_os_argv(lua_State* lua);
+tb_int_t xm_os_args(lua_State* lua);
tb_int_t xm_os_find(lua_State* lua);
tb_int_t xm_os_link(lua_State* lua);
tb_int_t xm_os_isdir(lua_State* lua);
@@ -209,6 +210,7 @@ tb_int_t xm_curses_register(lua_State* lua);
static luaL_Reg const g_os_functions[] =
{
{ "argv", xm_os_argv }
+, { "args", xm_os_args }
, { "find", xm_os_find }
, { "link", xm_os_link }
, { "isdir", xm_os_isdir }
diff --git a/core/src/xmake/makefile b/core/src/xmake/makefile
index 6def8df5b..f5fa74257 100644
--- a/core/src/xmake/makefile
+++ b/core/src/xmake/makefile
@@ -15,6 +15,7 @@ xmake_C_FILES += \
xmake \
machine \
os/argv \
+ os/args \
os/find \
os/link \
os/isdir \
diff --git a/core/src/xmake/os/args.c b/core/src/xmake/os/args.c
new file mode 100644
index 000000000..419e6db54
--- /dev/null
+++ b/core/src/xmake/os/args.c
@@ -0,0 +1,126 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015-2020, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file args.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "os.args"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * private implementation
+ */
+static tb_void_t tb_os_args_append(tb_string_ref_t result, tb_char_t const* cstr, tb_size_t size)
+{
+ // check
+ tb_assert_and_check_return(size < TB_PATH_MAXN);
+
+ // wrap and escape characters
+ tb_char_t ch;
+ tb_size_t n = 0;
+ tb_char_t const* p = cstr;
+ tb_bool_t wrap_quote = tb_false;
+ tb_char_t buff[TB_PATH_MAXN];
+ tb_size_t m = tb_arrayn(buff);
+ while ((ch = *p) && n < m)
+ {
+ if (ch == '\"')
+ {
+ if (n < m) buff[n++] = '\\';
+ wrap_quote = tb_true;
+ }
+ else if (ch == ' ' || ch == '(' || ch == ')') wrap_quote = tb_true;
+ if (n < m) buff[n++] = ch;
+ p++;
+ }
+ tb_assert_and_check_return(n < m);
+ buff[n] = '\0';
+
+ // wrap "" and escape '\\' if exists escape characters and spaces?
+ if (wrap_quote)
+ {
+ tb_string_chrcat(result, '\"');
+ tb_size_t i = 0;
+ tb_char_t ch;
+ for (i = 0; i < n; i++)
+ {
+ ch = buff[i];
+ if (ch == '\\') // escape the '\\' characters in ""
+ tb_string_chrcat(result, '\\');
+ tb_string_chrcat(result, ch);
+ }
+ tb_string_chrcat(result, '\"');
+ }
+ else if (n) tb_string_cstrncat(result, buff, n);
+}
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+tb_int_t xm_os_args(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // init result
+ tb_string_t result;
+ tb_string_init(&result);
+
+ // make string from arguments list
+ if (lua_istable(lua, 1))
+ {
+ tb_size_t i = 0;
+ tb_size_t n = lua_objlen(lua, 1);
+ for (i = 1; i <= n; i++)
+ {
+ // add space
+ if (i != 1) tb_string_chrcat(&result, ' ');
+
+ // add argument
+ lua_pushnumber(lua, (tb_int_t)i);
+ lua_rawget(lua, 1);
+ size_t size = 0;
+ tb_char_t const* cstr = luaL_checklstring(lua, -1, &size);
+ if (cstr && size)
+ tb_os_args_append(&result, cstr, size);
+ lua_pop(lua, 1);
+ }
+ }
+ else
+ {
+ size_t size = 0;
+ tb_char_t const* cstr = luaL_checklstring(lua, 1, &size);
+ if (cstr && size)
+ tb_os_args_append(&result, cstr, size);
+ }
+
+ // return result
+ tb_size_t size = tb_string_size(&result);
+ if (size) lua_pushlstring(lua, tb_string_cstr(&result), size);
+ else lua_pushnil(lua);
+ tb_string_exit(&result);
+ return 1;
+}
diff --git a/core/src/xmake/os/argv.c b/core/src/xmake/os/argv.c
index d1c74d4d9..db7b6ced2 100644
--- a/core/src/xmake/os/argv.c
+++ b/core/src/xmake/os/argv.c
@@ -22,7 +22,7 @@
/* //////////////////////////////////////////////////////////////////////////////////////
* trace
*/
-#define TB_TRACE_MODULE_NAME "argv"
+#define TB_TRACE_MODULE_NAME "os.argv"
#define TB_TRACE_MODULE_DEBUG (0)
/* //////////////////////////////////////////////////////////////////////////////////////
diff --git a/tests/modules/os/test.lua b/tests/modules/os/test.lua
index 763ca8cd2..02be4778b 100644
--- a/tests/modules/os/test.lua
+++ b/tests/modules/os/test.lua
@@ -65,14 +65,18 @@ function test_argv(t)
t:are_equal(os.argv("aa bb cc"), {"aa", "bb", "cc"})
t:are_equal(os.argv("aa --bb=bbb -c"), {"aa", "--bb=bbb", "-c"})
t:are_equal(os.argv("\"aa bb cc\" dd"), {"aa bb cc", "dd"})
+ t:are_equal(os.argv("\"aa(bb)cc\" dd"), {"aa(bb)cc", "dd"})
t:are_equal(os.argv("aa\\bb/cc dd"), {"aa\\bb/cc", "dd"})
t:are_equal(os.argv("\"aa\\\\bb/cc dd\" ee"), {"aa\\bb/cc dd", "ee"})
+ t:are_equal(os.argv("\"aa\\\\bb/cc (dd)\" ee"), {"aa\\bb/cc (dd)", "ee"})
end
function test_args(t)
t:are_equal(os.args({"aa", "bb", "cc"}), "aa bb cc")
t:are_equal(os.args({"aa", "--bb=bbb", "-c"}), "aa --bb=bbb -c")
t:are_equal(os.args({"aa bb cc", "dd"}), "\"aa bb cc\" dd")
--- t:are_equal(os.args({"aa\\bb/cc", "dd"}), "aa\\bb/cc dd")
+ t:are_equal(os.args({"aa(bb)cc", "dd"}), "\"aa(bb)cc\" dd")
+ t:are_equal(os.args({"aa\\bb/cc", "dd"}), "aa\\bb/cc dd")
t:are_equal(os.args({"aa\\bb/cc dd", "ee"}), "\"aa\\\\bb/cc dd\" ee")
+ t:are_equal(os.args({"aa\\bb/cc (dd)", "ee"}), "\"aa\\\\bb/cc (dd)\" ee")
end
diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua
index d2ccd070b..b6334a922 100644
--- a/xmake/core/base/os.lua
+++ b/xmake/core/base/os.lua
@@ -225,35 +225,6 @@ function os._match_wildcard_pathes(v)
return v
end
--- make string from arguments list
-function os.args(argv)
-
- -- make it
- local args = nil
- for _, arg in ipairs(table.wrap(argv)) do
- arg = arg:trim()
- if #arg > 0 then
- arg = arg:gsub("([\"\\])", "\\%1")
- if arg:find("[%s%(%)]") then
- if args then
- args = args .. " \"" .. arg .. "\""
- else
- args = "\"" .. arg .. "\""
- end
- else
- if args then
- args = args .. " " .. arg
- else
- args = arg
- end
- end
- end
- end
-
- -- ok?
- return args or ""
-end
-
-- match files or directories
--
-- @param pattern the search pattern
diff --git a/xmake/core/sandbox/modules/os.lua b/xmake/core/sandbox/modules/os.lua
index e0acaaeba..43899a536 100644
--- a/xmake/core/sandbox/modules/os.lua
+++ b/xmake/core/sandbox/modules/os.lua
@@ -43,6 +43,7 @@ sandbox_os.exit = os.exit
sandbox_os.date = os.date
sandbox_os.time = os.time
sandbox_os.args = os.args
+sandbox_os.args = os.args
sandbox_os.argv = os.argv
sandbox_os.mtime = os.mtime
sandbox_os.raise = os.raise