diff options
| author | ruki <[email protected]> | 2017-02-08 10:30:48 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2017-02-08 10:30:48 +0800 |
| commit | 0dd09d0248bb07ca897d666ff13feaae19a3d93e (patch) | |
| tree | 96cb83fb812b0e995a34cbf0ed562e8f3c5b471a | |
| parent | 495724f2c5c22501520de05715f6ef18f2bd484d (diff) | |
add os.argv
| -rwxr-xr-x | core/src/xmake/machine.c | 4 | ||||
| -rwxr-xr-x | core/src/xmake/makefile | 1 | ||||
| -rwxr-xr-x | core/src/xmake/os/argv.c | 144 | ||||
| -rw-r--r-- | xmake/core/base/os.lua | 93 | ||||
| -rw-r--r-- | xmake/core/base/table.lua | 111 |
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 |
