summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2017-02-08 10:30:48 +0800
committerruki <[email protected]>2017-02-08 10:30:48 +0800
commit0dd09d0248bb07ca897d666ff13feaae19a3d93e (patch)
tree96cb83fb812b0e995a34cbf0ed562e8f3c5b471a
parent495724f2c5c22501520de05715f6ef18f2bd484d (diff)
add os.argv
-rwxr-xr-xcore/src/xmake/machine.c4
-rwxr-xr-xcore/src/xmake/makefile1
-rwxr-xr-xcore/src/xmake/os/argv.c144
-rw-r--r--xmake/core/base/os.lua93
-rw-r--r--xmake/core/base/table.lua111
5 files changed, 229 insertions, 124 deletions
diff --git a/core/src/xmake/machine.c b/core/src/xmake/machine.c
index 4dfa028d4..a5ab7968e 100755
--- a/core/src/xmake/machine.c
+++ b/core/src/xmake/machine.c
@@ -55,6 +55,7 @@ typedef struct __xm_machine_impl_t
*/
// the os functions
+tb_int_t xm_os_argv(lua_State* lua);
tb_int_t xm_os_find(lua_State* lua);
tb_int_t xm_os_uuid(lua_State* lua);
tb_int_t xm_os_isdir(lua_State* lua);
@@ -101,7 +102,8 @@ tb_int_t xm_process_close(lua_State* lua);
// the os functions
static luaL_Reg const g_os_functions[] =
{
- { "find", xm_os_find }
+ { "argv", xm_os_argv }
+, { "find", xm_os_find }
, { "uuid", xm_os_uuid }
, { "isdir", xm_os_isdir }
, { "rmdir", xm_os_rmdir }
diff --git a/core/src/xmake/makefile b/core/src/xmake/makefile
index 09d0767e1..6e4b25031 100755
--- a/core/src/xmake/makefile
+++ b/core/src/xmake/makefile
@@ -14,6 +14,7 @@ xmake_CONFIG = y
xmake_C_FILES += \
xmake \
machine \
+ os/argv \
os/find \
os/uuid \
os/isdir \
diff --git a/core/src/xmake/os/argv.c b/core/src/xmake/os/argv.c
new file mode 100755
index 000000000..233b55d0b
--- /dev/null
+++ b/core/src/xmake/os/argv.c
@@ -0,0 +1,144 @@
+/*!The Make-like Build Utility based on Lua
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 - 2017, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file argv.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "argv"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+tb_int_t xm_os_argv(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ // get the argument string
+ tb_char_t const* args = luaL_checkstring(lua, 1);
+ tb_check_return_val(args, 0);
+
+ // done
+ tb_char_t* buffer = tb_null;
+ do
+ {
+ // make buffer
+ tb_size_t maxn = TB_PATH_MAXN;
+ buffer = (tb_char_t*)tb_malloc(maxn);
+ tb_assert_and_check_break(buffer);
+
+ // copy and translate command
+ tb_char_t ch;
+ tb_size_t i = 0;
+ tb_size_t j = 0;
+ for (i = 0; j <= maxn && (ch = args[i]); i++)
+ {
+ // not enough? grow it
+ if (j == maxn)
+ {
+ // grow it
+ maxn += TB_PATH_MAXN;
+ buffer = (tb_char_t*)tb_ralloc(buffer, maxn);
+ tb_assert_and_check_break(buffer);
+ }
+
+ // translate "\"", "\'", "\\"
+ tb_char_t next = args[i + 1];
+ if (ch == '\\' && (next == '\"' || next == '\'' || next == '\\')) /* skip it */ ;
+ // copy it
+ else buffer[j++] = ch;
+ }
+ tb_assert_and_check_break(j < maxn);
+ buffer[j] = '\0';
+
+ // reset index
+ i = 1;
+
+ // init table
+ lua_newtable(lua);
+
+ // parse command to the arguments
+ tb_bool_t s = 0;
+ tb_char_t* p = buffer;
+ tb_char_t* b = tb_null;
+ while ((ch = *p))
+ {
+ // enter double quote?
+ if (!s && ch == '\"') s = 2;
+ // enter single quote?
+ else if (!s && ch == '\'') s = 1;
+ // leave quote?
+ else if ((s == 2 && ch == '\"') || (s == 1 && ch == '\'')) s = 0;
+ // is argument end with ' '?
+ else if (!s && tb_isspace(ch))
+ {
+ // fill zero
+ *p = '\0';
+
+ // save this argument
+ if (b)
+ {
+ // save argument
+ lua_pushstring(lua, b);
+ lua_rawseti(lua, -2, i++);
+
+ // clear it
+ b = tb_null;
+ }
+ }
+
+ // get the argument pointer
+ if ((s || !tb_isspace(ch)) && !b) b = p;
+
+ // next
+ p++;
+ }
+
+ // save this argument
+ if (b)
+ {
+ // save argument
+ lua_pushstring(lua, b);
+ lua_rawseti(lua, -2, i++);
+
+ // clear it
+ b = tb_null;
+ }
+
+ } while (0);
+
+ // exit buffer
+ if (buffer) tb_free(buffer);
+ buffer = tb_null;
+
+ // ok
+ return 1;
+}
diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua
index 1b5c31736..f49346d55 100644
--- a/xmake/core/base/os.lua
+++ b/xmake/core/base/os.lua
@@ -28,6 +28,7 @@ local os = os or {}
-- load modules
local io = require("base/io")
local path = require("base/path")
+local table = require("base/table")
local utils = require("base/utils")
local string = require("base/string")
@@ -265,28 +266,14 @@ end
-- run shell
function os.run(cmd)
- -- make temporary log file
- local log = os.tmpfile()
-
- -- execute it
- local ok = os.exec(cmd, log, log)
- if ok ~= 0 then
-
- -- make errors
- local errors = io.readall(log)
-
- -- remove the temporary log file
- os.rm(log)
-
- -- failed
- return false, errors
+ -- parse arguments
+ local argv = os.argv(cmd)
+ if not argv or #argv <= 0 then
+ return false, string.format("invalid command: %s", cmd)
end
- -- remove the temporary log file
- os.rm(log)
-
- -- ok
- return true
+ -- run it
+ return os.runv(argv[1], table.slice(argv, 2))
end
-- run shell with arguments list
@@ -319,45 +306,14 @@ end
-- execute shell
function os.exec(cmd, outfile, errfile)
- -- open command
- local ok = -1
- local proc = process.open(cmd, outfile, errfile)
- if proc ~= nil then
-
- -- wait process
- local waitok = -1
- local status = -1
- if coroutine.running() then
-
- -- save the current directory
- local curdir = os.curdir()
-
- -- wait it
- repeat
- -- poll it
- waitok, status = process.wait(proc, 0)
- if waitok == 0 then
- waitok, status = coroutine.yield(proc)
- end
- until waitok ~= 0
-
- -- resume the current directory
- os.cd(curdir)
- else
- waitok, status = process.wait(proc, -1)
- end
-
- -- get status
- if waitok > 0 then
- ok = status
- end
-
- -- close process
- process.close(proc)
+ -- parse arguments
+ local argv = os.argv(cmd)
+ if not argv or #argv <= 0 then
+ return -1
end
- -- ok?
- return ok
+ -- run it
+ return os.execv(argv[1], table.slice(argv, 2), outfile, errfile)
end
-- execute shell with arguments list
@@ -407,23 +363,14 @@ end
-- run shell and return output and error data
function os.iorun(cmd)
- -- make temporary output and error file
- local outfile = os.tmpfile()
- local errfile = os.tmpfile()
-
- -- run command
- local ok = os.exec(cmd, outfile, errfile)
-
- -- get output and error data
- local outdata = io.readall(outfile)
- local errdata = io.readall(errfile)
-
- -- remove the temporary output and error file
- os.rm(outfile)
- os.rm(errfile)
+ -- parse arguments
+ local argv = os.argv(cmd)
+ if not argv or #argv <= 0 then
+ return false, string.format("invalid command: %s", cmd)
+ end
- -- ok?
- return ok == 0, outdata, errdata
+ -- run it
+ return os.iorunv(argv[1], table.slice(argv, 2))
end
-- run shell with arguments and return output and error data
diff --git a/xmake/core/base/table.lua b/xmake/core/base/table.lua
index 6c37ae219..3767fc1c4 100644
--- a/xmake/core/base/table.lua
+++ b/xmake/core/base/table.lua
@@ -25,6 +25,18 @@
-- define module: table
local table = table or {}
+-- clear the table
+function table.clear(self)
+
+ -- check
+ assert(self and type(self) == "table")
+
+ -- clear it
+ for k in next, self do
+ rawset(self, k, nil)
+ end
+end
+
-- join all objects and tables
function table.join(...)
@@ -69,18 +81,6 @@ function table.join2(self, ...)
return self
end
--- clear the table
-function table.clear(self)
-
- -- check
- assert(self and type(self) == "table")
-
- -- clear it
- for k in next, self do
- rawset(self, k, nil)
- end
-end
-
-- copy the table to self
function table.copy(copied)
@@ -116,6 +116,55 @@ function table.copy2(self, copied)
end
+-- inherit interfaces and create a new instance
+function table.inherit(...)
+
+ -- init instance
+ local classes = {...}
+ local instance = {}
+ for _, clasz in ipairs(classes) do
+ for k, v in pairs(clasz) do
+ if type(v) == "function" then
+ instance[k] = v
+ end
+ end
+ end
+
+ -- ok?
+ return instance
+end
+
+-- inherit interfaces from the given class
+function table.inherit2(self, ...)
+
+ -- check
+ assert(self)
+
+ -- init instance
+ local classes = {...}
+ for _, clasz in ipairs(classes) do
+ for k, v in pairs(clasz) do
+ if type(v) == "function" and self[k] == nil then
+ self[k] = v
+ end
+ end
+ end
+
+ -- ok?
+ return self
+end
+
+-- slice table array
+function table.slice(self, first, last, step)
+
+ -- slice it
+ local sliced = {}
+ for i = first or 1, last or #self, step or 1 do
+ sliced[#sliced + 1] = self[i]
+ end
+ return sliced
+end
+
-- is array?
function table.is_array(self)
@@ -321,43 +370,5 @@ function table.unique(array)
return array
end
--- inherit interfaces and create a new instance
-function table.inherit(...)
-
- -- init instance
- local classes = {...}
- local instance = {}
- for _, clasz in ipairs(classes) do
- for k, v in pairs(clasz) do
- if type(v) == "function" then
- instance[k] = v
- end
- end
- end
-
- -- ok?
- return instance
-end
-
--- inherit interfaces from the given class
-function table.inherit2(self, ...)
-
- -- check
- assert(self)
-
- -- init instance
- local classes = {...}
- for _, clasz in ipairs(classes) do
- for k, v in pairs(clasz) do
- if type(v) == "function" and self[k] == nil then
- self[k] = v
- end
- end
- end
-
- -- ok?
- return self
-end
-
-- return module: table
return table