summaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
authorOpportunityLiu <[email protected]>2019-07-23 19:36:36 +0800
committerOpportunityLiu <[email protected]>2019-07-23 19:36:36 +0800
commit929f1255d95d10e85803053e08bd6c5e3f595439 (patch)
treecb04a2be7c683b280fd93ff5615fd98bc6b44f82 /core/src
parentd7a716d699bd36045df0e18e5ba6cc9baf7b7ce6 (diff)
use c impl
Diffstat (limited to 'core/src')
-rw-r--r--core/src/xmake/global/loadfile.c198
-rw-r--r--core/src/xmake/global/prefix.h32
-rw-r--r--core/src/xmake/machine.c51
-rw-r--r--core/src/xmake/makefile1
4 files changed, 280 insertions, 2 deletions
diff --git a/core/src/xmake/global/loadfile.c b/core/src/xmake/global/loadfile.c
new file mode 100644
index 000000000..5f5bdc2f6
--- /dev/null
+++ b/core/src/xmake/global/loadfile.c
@@ -0,0 +1,198 @@
+/*!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 - 2019, TBOOX Open Source Group.
+ *
+ * @author OpportunityLiu
+ * @file loadfile.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * trace
+ */
+#define TB_TRACE_MODULE_NAME "loadfile"
+#define TB_TRACE_MODULE_DEBUG (0)
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "prefix.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * private implementation
+ */
+
+typedef struct _xm_global_filereader
+{
+ tb_char_t buffer[8192];
+ tb_file_ref_t file;
+} xm_global_filereader;
+
+static tb_char_t const* xm_global_readxmakefile(lua_State* lua, xm_global_filereader* data, size_t* size)
+{
+ tb_long_t readsize = tb_file_read(data->file, (tb_byte_t*)data->buffer, tb_arrayn(data->buffer));
+ if (readsize <= 0) return tb_null;
+ *size = (size_t)readsize;
+ return data->buffer;
+}
+
+static tb_int_t xm_global_loadxmakefile(lua_State* lua, tb_char_t const* filepath, tb_char_t const* disppath,
+ tb_char_t const* mode)
+{
+ tb_file_ref_t file = tb_file_init(filepath, TB_FILE_MODE_RO);
+ if(!file)
+ {
+ lua_pushnil(lua);
+ lua_pushfstring(lua, "failed to open %s", disppath + 1);
+ return 2;
+ }
+ xm_global_filereader* reader = tb_malloc0_type(xm_global_filereader);
+ tb_assert_and_check_return_val(reader, 0);
+ reader->file = file;
+ tb_int_t loadresult = lua_loadx(lua, (lua_Reader)xm_global_readxmakefile, (tb_void_t*)reader, disppath, mode);
+
+ tb_bool_t status = tb_file_exit(file);
+ tb_assert_and_check_return_val(status, 0);
+ tb_free(reader);
+ file = tb_null;
+ reader = tb_null;
+
+ if (loadresult == LUA_OK)
+ {
+ return 1;
+ }
+ else
+ {
+ lua_pushnil(lua);
+ lua_pushvalue(lua, 1);
+ return 2;
+ }
+}
+
+static tb_int_t xm_global_loaduserfile(lua_State* lua, tb_char_t const* filepath, tb_char_t const* disppath,
+ tb_char_t const* mode)
+{
+ lua_getglobal(lua, "io");
+ lua_getfield(lua, 1, "file");
+ lua_getfield(lua, 1, "open");
+ // io, file, open, filepath
+ lua_pushstring(lua, filepath);
+ // io, file, ffile, ferr
+ lua_call(lua, 1, 2);
+ if (lua_type(lua, -2) == LUA_TNIL) return 2;
+ // io, file, ffile
+ lua_pop(lua, 1);
+ // io, file, ffile, read
+ lua_getfield(lua, 2, "read");
+ lua_pushvalue(lua, 3);
+ // io, file, ffile, read, ffile, "a"
+ lua_pushliteral(lua, "a");
+ // io, file, ffile, rdata, rerr
+ lua_call(lua, 2, 2);
+ lua_getfield(lua, 2, "close");
+ // io, file, ffile, rdata, rerr, close, ffile
+ lua_pushvalue(lua, 3);
+ // io, file, ffile, rdata, rerr
+ lua_call(lua, 1, 0);
+ if (lua_type(lua, -2) == LUA_TNIL) return 2;
+ // io, file, ffile, rdata
+ lua_pop(lua, 1);
+
+ lua_getglobal(lua, "load");
+ lua_pushvalue(lua, -2);
+ lua_pushstring(lua, disppath);
+ lua_pushstring(lua, mode);
+ lua_call(lua, 3, 2);
+
+ return 2;
+}
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+tb_int_t xm_global_loadfile(lua_State* lua)
+{
+ // check
+ tb_assert_and_check_return_val(lua, 0);
+
+ tb_char_t const* filepath = luaL_checkstring(lua, 1);
+ tb_char_t const* mode = luaL_optstring(lua, 2, "bt");
+
+ tb_char_t disppath[TB_PATH_MAXN] = {0};
+ tb_char_t const* prefix = "@";
+ tb_size_t prefixlen = tb_arrayn("@") - 1;
+ tb_char_t const* root = tb_null;
+
+ tb_bool_t isxmakefile = tb_false;
+
+ do
+ {
+ size_t path_len;
+ tb_char_t const* path;
+
+ lua_settop(lua, 0);
+ lua_getglobal(lua, "xmake");
+ lua_getfield(lua, 1, "_WORKING_DIR");
+ path = luaL_checklstring(lua, 2, &path_len);
+ if (!tb_strncmp(filepath, path, (tb_size_t)path_len))
+ {
+ prefix = "@./";
+ prefixlen = tb_arrayn("@./") - 1;
+ root = path;
+ break;
+ }
+
+ lua_settop(lua, 1);
+ lua_getfield(lua, 1, "_PROGRAM_DIR");
+ path = luaL_checklstring(lua, 2, &path_len);
+ if (!tb_strncmp(filepath, path, (tb_size_t)path_len))
+ {
+ prefix = "@$(programdir)/";
+ prefixlen = tb_arrayn("@$(programdir)/") - 1;
+ root = path;
+ isxmakefile = tb_true;
+ break;
+ }
+
+ lua_settop(lua, 1);
+ lua_getfield(lua, 1, "_PROJECT_DIR");
+ path = luaL_checklstring(lua, 2, &path_len);
+ if (!tb_strncmp(filepath, path, (tb_size_t)path_len))
+ {
+ prefix = "@$(projectdir)/";
+ prefixlen = tb_arrayn("@$(projectdir)/") - 1;
+ root = path;
+ break;
+ }
+ } while (0);
+ lua_settop(lua, 0);
+
+ if(root)
+ {
+ tb_strncpy(disppath, prefix, TB_PATH_MAXN);
+ tb_path_relative_to(root, filepath, disppath + prefixlen, TB_PATH_MAXN - prefixlen);
+ }
+ else
+ {
+ disppath[0] = '@';
+ tb_strncpy(disppath + 1, filepath, TB_PATH_MAXN - 1);
+ }
+ tb_path_translate(disppath + 1, tb_strlen(disppath + 1), TB_PATH_MAXN - 1);
+
+ if (isxmakefile)
+ return xm_global_loadxmakefile(lua, filepath, disppath, mode);
+ else
+ return xm_global_loaduserfile(lua, filepath, disppath, mode);
+}
diff --git a/core/src/xmake/global/prefix.h b/core/src/xmake/global/prefix.h
new file mode 100644
index 000000000..d48a81b1c
--- /dev/null
+++ b/core/src/xmake/global/prefix.h
@@ -0,0 +1,32 @@
+/*!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 - 2019, TBOOX Open Source Group.
+ *
+ * @author ruki
+ * @file prefix.h
+ *
+ */
+#ifndef XM_GLOBAL_PREFIX_H
+#define XM_GLOBAL_PREFIX_H
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "../prefix.h"
+
+
+#endif
+
+
diff --git a/core/src/xmake/machine.c b/core/src/xmake/machine.c
index ff0758882..de5e3738b 100644
--- a/core/src/xmake/machine.c
+++ b/core/src/xmake/machine.c
@@ -46,7 +46,7 @@
// the machine type
typedef struct __xm_machine_t
{
- // the lua
+ // the lua
lua_State* lua;
}xm_machine_t;
@@ -56,6 +56,7 @@ typedef struct __xm_machine_t
*/
// the global functions
+tb_int_t xm_global_loadfile(lua_State* lua);
// the os functions
tb_int_t xm_os_argv(lua_State* lua);
@@ -167,6 +168,13 @@ tb_int_t xm_curses_register(lua_State* lua);
* globals
*/
+// the global functions
+static luaL_Reg const g_global_functions[] =
+{
+ { "loadfile", xm_global_loadfile }
+, { tb_null, tb_null }
+};
+
// the os functions
static luaL_Reg const g_os_functions[] =
{
@@ -491,7 +499,6 @@ static tb_bool_t xm_machine_get_project_directory(xm_machine_t* machine, tb_char
// save the directory to the global variable: _PROJECT_DIR
lua_pushstring(machine->lua, path);
lua_setglobal(machine->lua, "_PROJECT_DIR");
-
// ok
ok = tb_true;
@@ -503,6 +510,36 @@ static tb_bool_t xm_machine_get_project_directory(xm_machine_t* machine, tb_char
// ok?
return ok;
}
+static tb_bool_t xm_machine_get_working_directory(xm_machine_t* machine, tb_char_t* path, tb_size_t maxn)
+{
+ // check
+ tb_assert_and_check_return_val(machine && path && maxn, tb_false);
+
+ // done
+ tb_bool_t ok = tb_false;
+ do
+ {
+ // get it from the current directory
+ if (!tb_directory_current(path, maxn)) break;
+
+ // trace
+ tb_trace_d("working: %s", path);
+
+ // save the directory to the global variable: _WORKING_DIR
+ lua_pushstring(machine->lua, path);
+ lua_setglobal(machine->lua, "_WORKING_DIR");
+
+ // ok
+ ok = tb_true;
+
+ } while (0);
+
+ // failed?
+ if (!ok) tb_printf("error: can't get the working directory!\n");
+
+ // ok?
+ return ok;
+}
static tb_void_t xm_machine_init_arch(xm_machine_t* machine)
{
// check
@@ -572,6 +609,13 @@ xm_machine_ref_t xm_machine_init()
// open lua libraries
luaL_openlibs(machine->lua);
+ // bind global functions
+ for (tb_size_t i = 0; g_global_functions[i].func; i++)
+ {
+ lua_pushcfunction(machine->lua, g_global_functions[i].func);
+ lua_setglobal(machine->lua, g_global_functions[i].name);
+ }
+
// bind os functions
luaL_register(machine->lua, "os", g_os_functions);
@@ -732,6 +776,9 @@ tb_int_t xm_machine_main(xm_machine_ref_t self, tb_int_t argc, tb_char_t** argv)
tb_char_t path[TB_PATH_MAXN] = {0};
if (!xm_machine_get_project_directory(machine, path, sizeof(path))) return -1;
+ // get the working directory
+ if (!xm_machine_get_working_directory(machine, path, sizeof(path))) return -1;
+
// get the program file
if (!xm_machine_get_program_file(machine, path, sizeof(path))) return -1;
diff --git a/core/src/xmake/makefile b/core/src/xmake/makefile
index 7232e0fd9..9e3c069dc 100644
--- a/core/src/xmake/makefile
+++ b/core/src/xmake/makefile
@@ -14,6 +14,7 @@ xmake_CONFIG = y
xmake_C_FILES += \
xmake \
machine \
+ global/loadfile \
os/argv \
os/find \
os/link \