diff options
| author | ruki <[email protected]> | 2026-01-21 00:32:48 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2026-01-21 00:32:48 +0800 |
| commit | 443fc30ae713b14623ac20bd5f1e8fdb12740783 (patch) | |
| tree | 3ec726af7f2c4452726bd825fa240341ad01fb0a /core/src | |
| parent | 91843ffb82564d29ce9a9e386f2c9292620a5ba9 (diff) | |
improve lastof
Diffstat (limited to 'core/src')
| -rw-r--r-- | core/src/xmake/string/lastof.c | 42 | ||||
| -rw-r--r-- | core/src/xmake/utf8/lastof.c | 38 | ||||
| -rw-r--r-- | core/src/xmake/utf8/utf8.c | 22 | ||||
| -rw-r--r-- | core/src/xmake/utf8/utf8.h | 4 |
4 files changed, 44 insertions, 62 deletions
diff --git a/core/src/xmake/string/lastof.c b/core/src/xmake/string/lastof.c index 9ac6c6784..912647a9c 100644 --- a/core/src/xmake/string/lastof.c +++ b/core/src/xmake/string/lastof.c @@ -29,39 +29,7 @@ * includes */ #include "prefix.h" - -/* ////////////////////////////////////////////////////////////////////////////////////// - * private implementation - */ -static tb_void_t xm_string_lastof_str( - lua_State *lua, tb_char_t const *cstr, tb_size_t nstr, tb_char_t const *csubstr, tb_size_t nsubstr) { - // find it - tb_char_t const *curr = tb_null; - tb_char_t const *next = cstr; - do { - next = tb_strstr(next, csubstr); // faster than tb_strnstr() - if (next) { - curr = next; - next += nsubstr; - } - - } while (!next); - - // found? - if (curr) { - lua_pushinteger(lua, curr - cstr + 1); - } else { - lua_pushnil(lua); - } -} -static tb_void_t xm_string_lastof_chr(lua_State *lua, tb_char_t const *cstr, tb_size_t nstr, tb_char_t ch) { - tb_char_t const *pos = tb_strrchr(cstr, ch); // faster than tb_strnrchr() - if (pos) { - lua_pushinteger(lua, pos - cstr + 1); - } else { - lua_pushnil(lua); - } -} +#include "../utf8/utf8.h" /* ////////////////////////////////////////////////////////////////////////////////////// * implementation @@ -84,11 +52,11 @@ tb_int_t xm_string_lastof(lua_State *lua) { tb_char_t const *csubstr = luaL_checklstring(lua, 2, &nsubstr); // lastof it - lua_newtable(lua); - if (nsubstr == 1) { - xm_string_lastof_chr(lua, cstr, (tb_size_t)nstr, csubstr[0]); + tb_long_t char_pos = xm_utf8_lastof_impl(cstr, nstr, csubstr, nsubstr); + if (char_pos > 0) { + lua_pushinteger(lua, char_pos); } else { - xm_string_lastof_str(lua, cstr, (tb_size_t)nstr, csubstr, nsubstr); + lua_pushnil(lua); } return 1; } diff --git a/core/src/xmake/utf8/lastof.c b/core/src/xmake/utf8/lastof.c index 8e22b16ba..165da3b69 100644 --- a/core/src/xmake/utf8/lastof.c +++ b/core/src/xmake/utf8/lastof.c @@ -36,42 +36,30 @@ tb_int_t xm_utf8_lastof(lua_State *lua) { size_t sublen; tb_char_t const* sub = luaL_checklstring(lua, 2, &sublen); tb_int_t plain = lua_toboolean(lua, 3); + tb_long_t byte_pos = 0; if (plain) { - tb_long_t char_pos = xm_utf8_lastof_impl(s, len, sub, sublen); - if (char_pos > 0) { - lua_pushinteger(lua, char_pos); - } else { - lua_pushnil(lua); - } - return 1; + byte_pos = xm_utf8_lastof_impl(s, len, sub, sublen); } else { lua_getglobal(lua, "string"); lua_getfield(lua, -1, "lastof"); lua_pushvalue(lua, 1); // s lua_pushvalue(lua, 2); // pattern lua_pushboolean(lua, 0); // plain = false - lua_call(lua, 3, 1); - - // Stack: [args, string_table, result] - if (lua_isnil(lua, -1)) { - return 1; + if (!lua_isnil(lua, -1)) { + byte_pos = (tb_long_t)lua_tointeger(lua, -1); } + } - lua_Integer byte_pos = lua_tointeger(lua, -1); - if (byte_pos > 0) { - tb_long_t count = xm_utf8_len_impl(s, len, 1, byte_pos - 1, tb_true, tb_null); - if (count >= 0) { - if (xm_utf8_iscont(s[byte_pos - 1])) { - lua_pushinteger(lua, count); - } else { - lua_pushinteger(lua, count + 1); - } - return 1; - } + if (byte_pos > 0) { + tb_long_t char_pos = xm_utf8_charpos(s, len, byte_pos); + if (char_pos > 0) { + lua_pushinteger(lua, char_pos); + return 1; } - lua_pushnil(lua); - return 1; } + + lua_pushnil(lua); + return 1; } diff --git a/core/src/xmake/utf8/utf8.c b/core/src/xmake/utf8/utf8.c index 3b23532c5..3748e0975 100644 --- a/core/src/xmake/utf8/utf8.c +++ b/core/src/xmake/utf8/utf8.c @@ -105,6 +105,27 @@ tb_size_t xm_utf8_encode(tb_char_t* s, xm_utf8_int_t val) { return 0; } +tb_long_t xm_utf8_charpos(tb_char_t const* s, tb_size_t len, tb_long_t byte_pos) { + if (byte_pos <= 0) return 0; + if (byte_pos > len + 1) byte_pos = len + 1; + + // adjust byte_pos to the start of the character + // + // performance: + // 0(1) complexity, because utf8 sequence is max 4 bytes + while (byte_pos > 1 && xm_utf8_iscont(s[byte_pos - 1])) { + byte_pos--; + } + + // get character position + tb_long_t count = xm_utf8_len_impl(s, len, 1, byte_pos - 1, tb_true, tb_null); + return count >= 0? count + 1 : -1; +} + +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation interfaces + */ + tb_long_t xm_utf8_len_impl(tb_char_t const* s, tb_size_t len, tb_long_t posi, tb_long_t posj, tb_bool_t strict, tb_size_t* errpos) { tb_assert_and_check_return_val(s, -1); @@ -313,3 +334,4 @@ tb_char_t const* xm_utf8_sub_impl(tb_char_t const* s, tb_size_t len, tb_long_t i *psublen = end_byte - start_byte; return s + start_byte - 1; } + diff --git a/core/src/xmake/utf8/utf8.h b/core/src/xmake/utf8/utf8.h index f50b21e44..f1d374af3 100644 --- a/core/src/xmake/utf8/utf8.h +++ b/core/src/xmake/utf8/utf8.h @@ -41,7 +41,11 @@ static __tb_inline__ tb_long_t xm_utf8_posrelat(tb_long_t pos, tb_size_t len) { tb_char_t const* xm_utf8_decode(tb_char_t const* s, xm_utf8_int_t* val, tb_bool_t strict); tb_size_t xm_utf8_encode(tb_char_t* s, xm_utf8_int_t val); +tb_long_t xm_utf8_charpos(tb_char_t const* s, tb_size_t len, tb_long_t byte_pos); +/* ////////////////////////////////////////////////////////////////////////////////////// + * implementation interfaces + */ tb_long_t xm_utf8_len_impl(tb_char_t const* s, tb_size_t len, tb_long_t posi, tb_long_t posj, tb_bool_t strict, tb_size_t* errpos); tb_long_t xm_utf8_offset_impl(tb_char_t const* s, tb_size_t len, tb_long_t n, tb_long_t posi); tb_bool_t xm_utf8_codepoint_impl(tb_char_t const* s, tb_size_t len, tb_long_t posi, tb_long_t posj, tb_bool_t strict, xm_utf8_codepoint_func_t func, tb_cpointer_t udata); |
