summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-09-28 16:00:54 +0800
committerGitHub <[email protected]>2025-09-28 16:00:54 +0800
commit75ab14b8834ec6d721ee0f96a694edaf9f6caa48 (patch)
treea6534016b03623c1545dddbb66f18fa49d052e87
parent35be907e221342b45091baae81c17929e0c85bc3 (diff)
parent21b740673ab4b53d7baea2c890ddad31e32524a5 (diff)
Merge pull request #6866 from xmake-io/opti
improve os.getenvs
-rw-r--r--core/src/xmake/hash/md5.c5
-rw-r--r--core/src/xmake/hash/prefix.h19
-rw-r--r--core/src/xmake/hash/sha.c7
-rw-r--r--core/src/xmake/hash/xxhash.c10
-rw-r--r--core/src/xmake/os/getenvs.c89
-rw-r--r--xmake/core/base/os.lua23
6 files changed, 99 insertions, 54 deletions
diff --git a/core/src/xmake/hash/md5.c b/core/src/xmake/hash/md5.c
index f9b125364..1ca594941 100644
--- a/core/src/xmake/hash/md5.c
+++ b/core/src/xmake/hash/md5.c
@@ -56,9 +56,8 @@ tb_int_t xm_hash_md5(lua_State* lua)
tb_md5_make(data, size, buffer, sizeof(buffer));
// make md5 string
- tb_size_t i = 0;
- tb_char_t s[256] = {0};
- for (i = 0; i < 16; ++i) tb_snprintf(s + (i << 1), 3, "%02x", buffer[i]);
+ tb_char_t s[256];
+ xm_hash_make_cstr(s, buffer, 16);
// save result
lua_pushstring(lua, s);
diff --git a/core/src/xmake/hash/prefix.h b/core/src/xmake/hash/prefix.h
index 6141c99aa..f5374a2d1 100644
--- a/core/src/xmake/hash/prefix.h
+++ b/core/src/xmake/hash/prefix.h
@@ -26,6 +26,25 @@
*/
#include "../prefix.h"
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * helper implementation
+ */
+
+static __tb_inline__ tb_void_t xm_hash_make_cstr(tb_char_t hash[256], tb_byte_t const* data, tb_size_t size)
+{
+ static tb_char_t const* digits_table = "0123456789abcdef";
+ tb_size_t i = 0;
+ tb_byte_t value;
+ tb_char_t* s = hash;
+ for (i = 0; i < size; ++i)
+ {
+ value = data[i];
+ s[0] = digits_table[(value >> 4) & 15];
+ s[1] = digits_table[value & 15];
+ s += 2;
+ }
+ *s = '\0';
+}
#endif
diff --git a/core/src/xmake/hash/sha.c b/core/src/xmake/hash/sha.c
index db51a93fd..4ffc2651e 100644
--- a/core/src/xmake/hash/sha.c
+++ b/core/src/xmake/hash/sha.c
@@ -116,15 +116,12 @@ tb_int_t xm_hash_sha(lua_State* lua)
tb_sha_exit(&sha, buffer, sizeof(buffer));
// make sha string
- tb_size_t i = 0;
+ tb_char_t s[256];
tb_size_t n = sha.digest_len << 2;
- tb_char_t s[256] = {0};
- for (i = 0; i < n; ++i) tb_snprintf(s + (i << 1), 3, "%02x", buffer[i]);
+ xm_hash_make_cstr(s, buffer, n);
// save result
lua_pushstring(lua, s);
-
- // ok
ok = tb_true;
}
diff --git a/core/src/xmake/hash/xxhash.c b/core/src/xmake/hash/xxhash.c
index 1804e9b74..8f2cc630c 100644
--- a/core/src/xmake/hash/xxhash.c
+++ b/core/src/xmake/hash/xxhash.c
@@ -86,10 +86,9 @@ tb_int_t xm_hash_xxhash(lua_State* lua)
}
// make xxhash string
- tb_size_t i = 0;
+ tb_char_t s[256];
tb_size_t n = mode >> 3;
- tb_char_t s[256] = {0};
- for (i = 0; i < n; ++i) tb_snprintf(s + (i << 1), 3, "%02x", buffer[i]);
+ xm_hash_make_cstr(s, buffer, n);
// save result
lua_pushstring(lua, s);
@@ -156,10 +155,9 @@ tb_int_t xm_hash_xxhash(lua_State* lua)
}
// make xxhash string
- tb_size_t i = 0;
+ tb_char_t s[256];
tb_size_t n = mode >> 3;
- tb_char_t s[256] = {0};
- for (i = 0; i < n; ++i) tb_snprintf(s + (i << 1), 3, "%02x", buffer[i]);
+ xm_hash_make_cstr(s, buffer, n);
// save result
lua_pushstring(lua, s);
diff --git a/core/src/xmake/os/getenvs.c b/core/src/xmake/os/getenvs.c
index 5b8f0ba41..23fdf677e 100644
--- a/core/src/xmake/os/getenvs.c
+++ b/core/src/xmake/os/getenvs.c
@@ -56,6 +56,75 @@ extern tb_char_t** environ;
/* //////////////////////////////////////////////////////////////////////////////////////
* implementation
*/
+static tb_void_t xm_os_getenvs_trim(tb_char_t const** sstr, tb_char_t const** estr)
+{
+ // check
+ tb_assert(sstr && estr && *sstr && *estr);
+
+ tb_char_t const* p = *sstr;
+ tb_char_t const* e = *estr;
+
+ // trim left
+ while (p < e && tb_isspace(*p))
+ p++;
+
+ // trim right
+ while (e > p && tb_isspace(*(e - 1)))
+ e--;
+
+ // save trimmed string
+ *sstr = p;
+ *estr = e;
+}
+
+static tb_void_t xm_os_getenvs_process_line(lua_State* lua, tb_char_t const* line)
+{
+ // check
+ tb_assert_and_check_return(lua && line);
+
+ tb_size_t n = tb_strlen(line);
+ tb_check_return(n > 0);
+
+ // find '=' separator
+ tb_char_t const* p = tb_strchr(line, '=');
+ tb_check_return(p);
+
+ // get key and value parts
+ tb_char_t const* key_start = line;
+ tb_char_t const* key_end = p;
+ tb_char_t const* value_start = p + 1;
+ tb_char_t const* value_end = line + n;
+
+ // trim key
+ xm_os_getenvs_trim(&key_start, &key_end);
+ if (key_start >= key_end) return;
+
+ // trim value
+ xm_os_getenvs_trim(&value_start, &value_end);
+
+ // get key and value lengths
+ tb_size_t key_len = key_end - key_start;
+ tb_size_t value_len = value_end > value_start ? value_end - value_start : 0;
+
+ // handle Windows-specific PATH conversion
+ tb_char_t const* final_key_start = key_start;
+ tb_size_t final_key_len = key_len;
+#if defined(TB_CONFIG_OS_WINDOWS) && !defined(TB_COMPILER_LIKE_UNIX)
+ if (key_len == 4 && tb_strnicmp(key_start, "path", 4) == 0)
+ {
+ // use "PATH" instead of "path"
+ static tb_char_t const PATH_UPPER[] = "PATH";
+ final_key_start = PATH_UPPER;
+ final_key_len = 4;
+ }
+#endif
+
+ // set key-value pair in Lua table using pushlstring to avoid length limits
+ lua_pushlstring(lua, final_key_start, final_key_len);
+ lua_pushlstring(lua, value_start, value_len);
+ lua_rawset(lua, -3);
+}
+
tb_int_t xm_os_getenvs(lua_State* lua)
{
// check
@@ -68,7 +137,6 @@ tb_int_t xm_os_getenvs(lua_State* lua)
tb_wchar_t const* p = (tb_wchar_t const*)GetEnvironmentStringsW();
if (p)
{
- tb_int_t i = 1;
tb_char_t* data = tb_null;
tb_size_t maxn = 0;
tb_char_t line[TB_PATH_MAXN];
@@ -79,10 +147,7 @@ tb_int_t xm_os_getenvs(lua_State* lua)
if (n + 1 < tb_arrayn(line))
{
if (tb_wtoa(line, p, tb_arrayn(line)) >= 0)
- {
- lua_pushstring(lua, line);
- lua_rawseti(lua, -2, i++);
- }
+ xm_os_getenvs_process_line(lua, line);
}
else
{
@@ -99,10 +164,7 @@ tb_int_t xm_os_getenvs(lua_State* lua)
tb_assert_and_check_break(data);
if (tb_wtoa(data, p, maxn) >= 0)
- {
- lua_pushstring(lua, data);
- lua_rawseti(lua, -2, i++);
- }
+ xm_os_getenvs_process_line(lua, data);
}
p += n + 1;
}
@@ -113,16 +175,9 @@ tb_int_t xm_os_getenvs(lua_State* lua)
tb_char_t const** p = (tb_char_t const**)environ;
if (p)
{
- tb_int_t i = 1;
- tb_size_t n = 0;
while (*p)
{
- n = tb_strlen(*p);
- if (n)
- {
- lua_pushstring(lua, *p);
- lua_rawseti(lua, -2, i++);
- }
+ xm_os_getenvs_process_line(lua, *p);
p++;
}
}
diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua
index 57046813e..41fe07d22 100644
--- a/xmake/core/base/os.lua
+++ b/xmake/core/base/os.lua
@@ -42,7 +42,6 @@ os._tmpdir = os._tmpdir or os.tmpdir
os._curdir = os._curdir or os.curdir
os._fscase = os._fscase or os.fscase
os._setenv = os._setenv or os.setenv
-os._getenvs = os._getenvs or os.getenvs
os._cpuinfo = os._cpuinfo or os.cpuinfo
os._meminfo = os._meminfo or os.meminfo
os._readlink = os._readlink or os.readlink
@@ -1300,28 +1299,6 @@ function os.term()
return require("base/tty").term()
end
--- get all current environment variables
--- e.g. envs["PATH"] = "/xxx:/yyy/foo"
-function os.getenvs()
- local envs = {}
- for _, line in ipairs(os._getenvs()) do
- local p = line:find('=', 1, true)
- if p then
- local key = line:sub(1, p - 1):trim()
- -- only translate Path to PATH on windows
- -- @see https://github.com/xmake-io/xmake/issues/3752
- if os.host() == "windows" and key:lower() == "path" then
- key = key:upper()
- end
- local values = line:sub(p + 1):trim()
- if #key > 0 then
- envs[key] = values
- end
- end
- end
- return envs
-end
-
-- set all current environment variables
-- e.g. envs["PATH"] = "/xxx:/yyy/foo"
function os.setenvs(envs)