summaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
Diffstat (limited to 'core/src')
-rw-r--r--core/src/cli/xmake.lua6
-rwxr-xr-xcore/src/cli/xmake.sh3
m---------core/src/tbox/tbox0
-rw-r--r--core/src/xmake/binutils/ar/extractlib.c2
-rw-r--r--core/src/xmake/binutils/extractlib.c2
-rw-r--r--core/src/xmake/engine.c6
-rw-r--r--core/src/xmake/engine_pool.c21
-rw-r--r--core/src/xmake/io/file_close.c2
-rw-r--r--core/src/xmake/io/file_write.c2
-rw-r--r--core/src/xmake/os/cpuinfo.c4
-rw-r--r--core/src/xmake/os/meminfo.c5
-rw-r--r--core/src/xmake/process/open.c14
-rw-r--r--core/src/xmake/semver/select.c120
-rw-r--r--core/src/xmake/utf8/width.c6
14 files changed, 145 insertions, 48 deletions
diff --git a/core/src/cli/xmake.lua b/core/src/cli/xmake.lua
index 7cd50cb2c..54b78806d 100644
--- a/core/src/cli/xmake.lua
+++ b/core/src/cli/xmake.lua
@@ -58,7 +58,8 @@ target("cli")
add_installfiles("$(projectdir)/../NOTICE.md")
add_installfiles("$(projectdir)/../xmake/(**.lua)")
add_installfiles("$(projectdir)/../xmake/(scripts/**)")
- add_installfiles("$(projectdir)/../xmake/(repository/templates/**)")
+ add_installfiles("$(projectdir)/../xmake/(templates/**)")
+ add_installfiles("$(projectdir)/../xmake/(repository/**)")
add_installfiles("$(projectdir)/../scripts/xrepo.bat")
add_installfiles("$(projectdir)/../scripts/xrepo.ps1")
set_prefixdir("/", {bindir = "/"})
@@ -68,7 +69,8 @@ target("cli")
else
add_installfiles("$(projectdir)/../(xmake/**.lua)", {prefixdir = "share"})
add_installfiles("$(projectdir)/../(xmake/scripts/**)", {prefixdir = "share"})
- add_installfiles("$(projectdir)/../(xmake/repository/templates/**)", {prefixdir = "share"})
+ add_installfiles("$(projectdir)/../(xmake/templates/**)", {prefixdir = "share"})
+ add_installfiles("$(projectdir)/../(xmake/repository/**)", {prefixdir = "share"})
add_installfiles("$(projectdir)/../scripts/xrepo.sh", {prefixdir = "bin", filename = "xrepo"})
end
diff --git a/core/src/cli/xmake.sh b/core/src/cli/xmake.sh
index af4e8ba36..a7ef02601 100755
--- a/core/src/cli/xmake.sh
+++ b/core/src/cli/xmake.sh
@@ -32,7 +32,8 @@ target "cli"
add_installfiles "${projectdir}/(xmake/scripts/virtualenvs/**)" "share"
add_installfiles "${projectdir}/(xmake/scripts/conan/**)" "share"
add_installfiles "${projectdir}/(xmake/scripts/module/**)" "share"
- add_installfiles "${projectdir}/(xmake/repository/templates/**)" "share"
+ add_installfiles "${projectdir}/(xmake/templates/**)" "share"
+ add_installfiles "${projectdir}/(xmake/repository/**)" "share"
add_installfiles "${projectdir}/scripts/xrepo.sh" "bin" "xrepo"
# fix os.exec() call incorrect program from /mingw64/bin. e.g. python, ..
diff --git a/core/src/tbox/tbox b/core/src/tbox/tbox
-Subproject 870b2b9e4337694bb381d55338364c8b9711b82
+Subproject 14f9089e1e4a9b8b01f5789f4c5d6a04e6652b3
diff --git a/core/src/xmake/binutils/ar/extractlib.c b/core/src/xmake/binutils/ar/extractlib.c
index d9629394a..830eb3275 100644
--- a/core/src/xmake/binutils/ar/extractlib.c
+++ b/core/src/xmake/binutils/ar/extractlib.c
@@ -212,7 +212,7 @@ tb_bool_t xm_binutils_ar_extract(tb_stream_ref_t istream, tb_char_t const *outpu
ok = tb_false;
}
- tb_stream_clos(ostream);
+ tb_stream_close(ostream);
tb_stream_exit(ostream);
tb_check_break(ok);
diff --git a/core/src/xmake/binutils/extractlib.c b/core/src/xmake/binutils/extractlib.c
index fbfbacfef..735859ade 100644
--- a/core/src/xmake/binutils/extractlib.c
+++ b/core/src/xmake/binutils/extractlib.c
@@ -129,7 +129,7 @@ tb_int_t xm_binutils_extractlib(lua_State *lua) {
} while (0);
if (istream) {
- tb_stream_clos(istream);
+ tb_stream_close(istream);
tb_stream_exit(istream);
}
diff --git a/core/src/xmake/engine.c b/core/src/xmake/engine.c
index b93b29bb0..b37817cc9 100644
--- a/core/src/xmake/engine.c
+++ b/core/src/xmake/engine.c
@@ -814,6 +814,10 @@ static tb_bool_t xm_engine_save_arguments(xm_engine_t *engine, tb_int_t argc, tb
lua_rawseti(engine->lua, -2, (int)lua_objlen(engine->lua, -2) + 1);
}
+#if defined(TB_CONFIG_OS_WINDOWS) && !defined(TB_COMPILER_LIKE_UNIX)
+ LocalFree(argvw);
+#endif
+
// _ARGV = table_new
lua_setglobal(engine->lua, "_ARGV");
return tb_true;
@@ -1445,8 +1449,8 @@ static tb_bool_t xm_engine_extract_programfiles_impl(xm_engine_t *engine,
if (tb_stream_open(stream)) {
tb_stream_bwrit(stream, p, n);
- tb_stream_exit(stream);
}
+ tb_stream_exit(stream);
p += n;
}
diff --git a/core/src/xmake/engine_pool.c b/core/src/xmake/engine_pool.c
index 39bdb1339..b9df842eb 100644
--- a/core/src/xmake/engine_pool.c
+++ b/core/src/xmake/engine_pool.c
@@ -43,6 +43,18 @@
#define XM_ENGINE_POOL (TB_SINGLETON_TYPE_USER + 4)
/* //////////////////////////////////////////////////////////////////////////////////////
+ * globals
+ */
+
+/* the engine pool lock
+ *
+ * the pool is a singleton shared by all worker threads, which may alloc/free engines
+ * concurrently (e.g. parallel batchcmds:lua/vlua jobs run in native threads), so we must
+ * protect the underlying list against data races, otherwise it will be corrupted and crash.
+ */
+static tb_spinlock_t g_engine_pool_lock = TB_SPINLOCK_INIT;
+
+/* //////////////////////////////////////////////////////////////////////////////////////
* private implementation
*/
static tb_handle_t xm_engine_pool_instance_init(tb_cpointer_t *ppriv) {
@@ -83,17 +95,22 @@ tb_void_t xm_engine_pool_exit(xm_engine_pool_ref_t engine_pool) {
xm_engine_ref_t xm_engine_pool_alloc(xm_engine_pool_ref_t engine_pool) {
xm_engine_ref_t engine = tb_null;
+ tb_spinlock_enter(&g_engine_pool_lock);
if (tb_single_list_size(engine_pool) > 0) {
engine = (xm_engine_ref_t)tb_single_list_head(engine_pool);
tb_single_list_remove_head(engine_pool);
}
+ tb_spinlock_leave(&g_engine_pool_lock);
return engine;
}
tb_bool_t xm_engine_pool_free(xm_engine_pool_ref_t engine_pool, xm_engine_ref_t engine) {
+ tb_bool_t ok = tb_false;
+ tb_spinlock_enter(&g_engine_pool_lock);
if (tb_single_list_size(engine_pool) < XM_ENGINE_POOL_MAXN) {
tb_single_list_insert_tail(engine_pool, engine);
- return tb_true;
+ ok = tb_true;
}
- return tb_false;
+ tb_spinlock_leave(&g_engine_pool_lock);
+ return ok;
}
diff --git a/core/src/xmake/io/file_close.c b/core/src/xmake/io/file_close.c
index bb5cf1060..303f9f002 100644
--- a/core/src/xmake/io/file_close.c
+++ b/core/src/xmake/io/file_close.c
@@ -68,7 +68,7 @@ tb_int_t xm_io_file_close(lua_State *lua) {
}
// close file
- tb_stream_clos(file->u.file_ref);
+ tb_stream_close(file->u.file_ref);
file->u.file_ref = tb_null;
// exit fstream
diff --git a/core/src/xmake/io/file_write.c b/core/src/xmake/io/file_write.c
index fdfd5afe7..5f860d641 100644
--- a/core/src/xmake/io/file_write.c
+++ b/core/src/xmake/io/file_write.c
@@ -110,7 +110,7 @@ static tb_void_t xm_io_file_write_std(xm_io_file_t *file, tb_byte_t const *data,
tb_check_return(type != XM_IO_FILE_TYPE_STDIN);
// write data to stdout/stderr
- tb_stdfile_writ(file->u.std_ref, data, size);
+ tb_stdfile_write(file->u.std_ref, data, size);
}
/* //////////////////////////////////////////////////////////////////////////////////////
diff --git a/core/src/xmake/os/cpuinfo.c b/core/src/xmake/os/cpuinfo.c
index 47542a4b4..e931f7912 100644
--- a/core/src/xmake/os/cpuinfo.c
+++ b/core/src/xmake/os/cpuinfo.c
@@ -70,8 +70,9 @@ static tb_float_t xm_os_cpuinfo_usagerate() {
processor_info_array_t cpuinfo;
mach_msg_type_number_t cpuinfo_count;
static tb_hong_t s_time = 0;
+ host_t host = mach_host_self();
if (tb_mclock() - s_time > 1000 &&
- host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &cpu_count, &cpuinfo, &cpuinfo_count) ==
+ host_processor_info(host, PROCESSOR_CPU_LOAD_INFO, &cpu_count, &cpuinfo, &cpuinfo_count) ==
KERN_SUCCESS) {
static processor_info_array_t s_cpuinfo_prev = tb_null;
static mach_msg_type_number_t s_cpuinfo_count_prev = 0;
@@ -100,6 +101,7 @@ static tb_float_t xm_os_cpuinfo_usagerate() {
s_cpuinfo_prev = cpuinfo;
s_cpuinfo_count_prev = cpuinfo_count;
}
+ mach_port_deallocate(mach_task_self(), host);
return cpu_count > 0 ? usagerate / cpu_count : 0;
#elif defined(TB_CONFIG_OS_WINDOWS)
// kernel include idle_time
diff --git a/core/src/xmake/os/meminfo.c b/core/src/xmake/os/meminfo.c
index 96db76f0d..0671d5311 100644
--- a/core/src/xmake/os/meminfo.c
+++ b/core/src/xmake/os/meminfo.c
@@ -61,7 +61,10 @@ static tb_bool_t xm_os_meminfo_stats(tb_int_t *ptotalsize, tb_int_t *pavailsize)
#if defined(TB_CONFIG_OS_MACOSX)
vm_statistics64_data_t vmstat;
mach_msg_type_number_t count = HOST_VM_INFO64_COUNT;
- if (host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info_t)&vmstat, &count) == KERN_SUCCESS) {
+ host_t host = mach_host_self();
+ kern_return_t result = host_statistics64(host, HOST_VM_INFO64, (host_info_t)&vmstat, &count);
+ mach_port_deallocate(mach_task_self(), host);
+ if (result == KERN_SUCCESS) {
tb_int_t pagesize = (tb_int_t)tb_page_size();
tb_int64_t totalsize = (tb_int64_t)(vmstat.inactive_count + vmstat.free_count + vmstat.active_count +
vmstat.wire_count
diff --git a/core/src/xmake/process/open.c b/core/src/xmake/process/open.c
index b6cf272b2..5ae958f8d 100644
--- a/core/src/xmake/process/open.c
+++ b/core/src/xmake/process/open.c
@@ -75,7 +75,7 @@ tb_int_t xm_process_open(lua_State *lua) {
// get curdir
lua_pushstring(lua, "curdir");
- lua_gettable(lua, 3);
+ lua_gettable(lua, 2);
attr.curdir = lua_tostring(lua, -1);
lua_pop(lua, 1);
@@ -100,7 +100,7 @@ tb_int_t xm_process_open(lua_State *lua) {
// get infile
if (!inpath) {
lua_pushstring(lua, "infile");
- lua_gettable(lua, 3);
+ lua_gettable(lua, 2);
infile = (xm_io_file_t *)lua_touserdata(lua, -1);
lua_pop(lua, 1);
}
@@ -108,7 +108,7 @@ tb_int_t xm_process_open(lua_State *lua) {
// get outfile
if (!outpath) {
lua_pushstring(lua, "outfile");
- lua_gettable(lua, 3);
+ lua_gettable(lua, 2);
outfile = (xm_io_file_t *)lua_touserdata(lua, -1);
lua_pop(lua, 1);
}
@@ -116,7 +116,7 @@ tb_int_t xm_process_open(lua_State *lua) {
// get errfile
if (!errpath) {
lua_pushstring(lua, "errfile");
- lua_gettable(lua, 3);
+ lua_gettable(lua, 2);
errfile = (xm_io_file_t *)lua_touserdata(lua, -1);
lua_pop(lua, 1);
}
@@ -124,7 +124,7 @@ tb_int_t xm_process_open(lua_State *lua) {
// get inpipe
if (!inpath && !infile) {
lua_pushstring(lua, "inpipe");
- lua_gettable(lua, 3);
+ lua_gettable(lua, 2);
inpipe = (tb_pipe_file_ref_t)lua_touserdata(lua, -1);
lua_pop(lua, 1);
}
@@ -132,7 +132,7 @@ tb_int_t xm_process_open(lua_State *lua) {
// get outpipe
if (!outpath && !outfile) {
lua_pushstring(lua, "outpipe");
- lua_gettable(lua, 3);
+ lua_gettable(lua, 2);
outpipe = (tb_pipe_file_ref_t)lua_touserdata(lua, -1);
lua_pop(lua, 1);
}
@@ -140,7 +140,7 @@ tb_int_t xm_process_open(lua_State *lua) {
// get errpipe
if (!errpath && !errfile) {
lua_pushstring(lua, "errpipe");
- lua_gettable(lua, 3);
+ lua_gettable(lua, 2);
errpipe = (tb_pipe_file_ref_t)lua_touserdata(lua, -1);
lua_pop(lua, 1);
}
diff --git a/core/src/xmake/semver/select.c b/core/src/xmake/semver/select.c
index 283afb050..e95840eab 100644
--- a/core/src/xmake/semver/select.c
+++ b/core/src/xmake/semver/select.c
@@ -33,6 +33,69 @@
/* //////////////////////////////////////////////////////////////////////////////////////
* private implementation
*/
+static tb_char_t const *xm_semver_skip_version_prefix(tb_char_t const *version_str, tb_size_t *version_len) {
+ if (*version_len && (version_str[0] == 'v' || version_str[0] == '=')) {
+ ++version_str;
+ --*version_len;
+ }
+ return version_str;
+}
+static tb_bool_t xm_semver_is_exact_version(
+ tb_char_t const *version_str, tb_size_t version_len, tb_bool_t *is_exact_with_build) {
+ *is_exact_with_build = tb_false;
+ version_str = xm_semver_skip_version_prefix(version_str, &version_len);
+ semver_t version = { 0 };
+ if (!semvern(&version, version_str, version_len)) {
+ *is_exact_with_build = version.build.len > 0;
+ semver_dtor(&version);
+ return tb_true;
+ }
+ return tb_false;
+}
+static tb_long_t xm_semver_compare_build(semver_id_t const *left, semver_id_t const *right) {
+ while (left && right && left->len && right->len) {
+ if (left->numeric && right->numeric) {
+ if (left->num != right->num) {
+ return left->num > right->num ? 1 : -1;
+ }
+ } else {
+ tb_size_t size = left->len < right->len ? left->len : right->len;
+ tb_long_t result = tb_memcmp(left->raw, right->raw, size);
+ if (result) {
+ return result;
+ }
+ if (left->len != right->len) {
+ return left->len > right->len ? 1 : -1;
+ }
+ }
+ left = left->next;
+ right = right->next;
+ }
+ if (left && left->len) {
+ return 1;
+ }
+ if (right && right->len) {
+ return -1;
+ }
+ return 0;
+}
+static tb_long_t xm_semver_compare_with_build(semver_t const *left, semver_t const *right) {
+ tb_long_t result = semver_pcmp(left, right);
+ // xmake-repo orders build metadata as package revisions
+ return result ? result : xm_semver_compare_build(&left->build, &right->build);
+}
+static semver_t const *xm_semvers_find_newest(semvers_t const *versions) {
+ tb_assert_and_check_return_val(versions && versions->length, tb_null);
+
+ semver_t const *newest = &versions->data[0];
+ tb_size_t i = 0;
+ for (i = 1; i < versions->length; ++i) {
+ if (xm_semver_compare_with_build(&versions->data[i], newest) > 0) {
+ newest = &versions->data[i];
+ }
+ }
+ return newest;
+}
static tb_bool_t xm_semver_select_from_versions_tags1(
lua_State *lua, tb_int_t fromidx, semver_t *semver, semver_range_t const *range, semvers_t *matches) {
// clear matches
@@ -59,27 +122,24 @@ static tb_bool_t xm_semver_select_from_versions_tags1(
// no matches?
tb_check_return_val(matches->length, tb_false);
- // sort matches
- semvers_psort(matches);
-
// get the newest version
- semver_t top = semvers_ppop(matches);
+ semver_t const *top = xm_semvers_find_newest(matches);
lua_createtable(lua, 0, 2);
// return results
- lua_pushstring(lua, top.raw);
+ lua_pushstring(lua, top->raw);
lua_setfield(lua, -2, "version");
lua_pushstring(lua, fromidx == 2 ? "version" : "tag");
lua_setfield(lua, -2, "source");
- // exit the popped semver
- semver_dtor(&top);
-
return tb_true;
}
static tb_bool_t xm_semver_select_from_versions_tags2(
- lua_State *lua, tb_int_t fromidx, semver_t *semver, tb_char_t const *version_str, tb_size_t version_len) {
+ lua_State *lua, tb_int_t fromidx, tb_char_t const *version_str, tb_size_t version_len, tb_bool_t is_exact) {
+ if (is_exact) {
+ version_str = xm_semver_skip_version_prefix(version_str, &version_len);
+ }
lua_Integer i = 0;
luaL_checktype(lua, fromidx, LUA_TTABLE);
for (i = lua_objlen(lua, fromidx); i > 0; --i) {
@@ -88,8 +148,14 @@ static tb_bool_t xm_semver_select_from_versions_tags2(
tb_char_t const *source_str = luaL_checkstring(lua, -1);
tb_size_t source_len = tb_strlen(source_str);
+ tb_size_t source_version_len = source_len;
+ tb_char_t const *source_version_str = source_str;
+ // ignore a leading v/= prefix when comparing exact versions
+ if (is_exact) {
+ source_version_str = xm_semver_skip_version_prefix(source_str, &source_version_len);
+ }
lua_pop(lua, 1);
- if (source_len == version_len && tb_strncmp(source_str, version_str, version_len) == 0) {
+ if (source_version_len == version_len && tb_strncmp(source_version_str, version_str, version_len) == 0) {
lua_createtable(lua, 0, 2);
lua_pushlstring(lua, source_str, source_len);
lua_setfield(lua, -2, "version");
@@ -147,21 +213,17 @@ static tb_bool_t xm_semver_select_latest_from_versions_tags(lua_State *lua,
}
tb_check_return_val(matches->length, tb_false);
- // sort matches
- semvers_psort(matches);
-
// get the newest match
- semver_t top = semvers_ppop(matches);
+ semver_t const *top = xm_semvers_find_newest(matches);
lua_createtable(lua, 0, 2);
// return results
- lua_pushstring(lua, top.raw);
+ lua_pushstring(lua, top->raw);
lua_setfield(lua, -2, "version");
lua_pushstring(lua, fromidx == 2 ? "version" : "tag");
lua_setfield(lua, -2, "source");
- semver_dtor(&top);
return tb_true;
}
@@ -179,6 +241,8 @@ tb_int_t xm_semver_select(lua_State *lua) {
// select version
tb_bool_t ok = tb_false;
tb_bool_t is_range = tb_false;
+ tb_bool_t is_exact = tb_false;
+ tb_bool_t is_exact_with_build = tb_false;
tb_char_t const *range_str = tb_null;
semver_t semver = { 0 };
semvers_t matches = { 0 };
@@ -193,27 +257,27 @@ tb_int_t xm_semver_select(lua_State *lua) {
// parse the version range string
is_range = semver_rangen(&range, range_str, range_len) == 0;
- if (is_range) {
- // attempt to select version from the versions list first
- if (xm_semver_select_from_versions_tags1(lua, 2, &semver, &range, &matches)) {
+ is_exact = xm_semver_is_exact_version(range_str, range_len, &is_exact_with_build);
+
+ // matching order: versions exact -> tags exact -> versions range -> tags range
+ if (is_exact || !is_range) {
+ if (xm_semver_select_from_versions_tags2(lua, 2, range_str, range_len, is_exact)) {
ok = tb_true;
break;
}
-
- // attempt to select version from the tags list
- if (xm_semver_select_from_versions_tags1(lua, 3, &semver, &range, &matches)) {
+ if (xm_semver_select_from_versions_tags2(lua, 3, range_str, range_len, is_exact)) {
ok = tb_true;
break;
}
- } else {
- // attempt to select version from the versions list first
- if (xm_semver_select_from_versions_tags2(lua, 2, &semver, range_str, range_len)) {
+ }
+
+ // a build-qualified exact version identifies a specific package revision
+ if (is_range && !is_exact_with_build) {
+ if (xm_semver_select_from_versions_tags1(lua, 2, &semver, &range, &matches)) {
ok = tb_true;
break;
}
-
- // attempt to select version from the tags list
- if (xm_semver_select_from_versions_tags2(lua, 3, &semver, range_str, range_len)) {
+ if (xm_semver_select_from_versions_tags1(lua, 3, &semver, &range, &matches)) {
ok = tb_true;
break;
}
diff --git a/core/src/xmake/utf8/width.c b/core/src/xmake/utf8/width.c
index 615572462..fb79ee198 100644
--- a/core/src/xmake/utf8/width.c
+++ b/core/src/xmake/utf8/width.c
@@ -33,7 +33,11 @@
* utf8.width(codepoint)
*/
tb_int_t xm_utf8_width(lua_State* lua) {
- if (lua_isnumber(lua, 1)) {
+ /* we must not use lua_isnumber() here: it also accepts a numeric string,
+ * so utf8.width("9") would return the width of the code point 9 (a tab)
+ * instead of the width of the string "9"
+ */
+ if (lua_type(lua, 1) == LUA_TNUMBER) {
xm_utf8_int_t val = (xm_utf8_int_t)lua_tointeger(lua, 1);
lua_pushinteger(lua, xm_utf8_charwidth(val));
} else {