From 7f51f9e0f1ec49cb56b3205608046505903d312d Mon Sep 17 00:00:00 2001 From: OpportunityLiu Date: Wed, 17 Jul 2019 11:04:23 +0800 Subject: custom trim --- core/src/xmake/string/trim.c | 105 ++++++++++++++++++++++++++++--------------- xmake/core/base/string.lua | 12 ++--- 2 files changed, 76 insertions(+), 41 deletions(-) diff --git a/core/src/xmake/string/trim.c b/core/src/xmake/string/trim.c index c7cce0168..1a0738206 100644 --- a/core/src/xmake/string/trim.c +++ b/core/src/xmake/string/trim.c @@ -11,10 +11,10 @@ * 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 + * @author OpportunityLiu * @file trim.c * */ @@ -22,57 +22,92 @@ /* ////////////////////////////////////////////////////////////////////////////////////// * trace */ -#define TB_TRACE_MODULE_NAME "trim" -#define TB_TRACE_MODULE_DEBUG (0) +#define TB_TRACE_MODULE_NAME "trim" +#define TB_TRACE_MODULE_DEBUG (0) /* ////////////////////////////////////////////////////////////////////////////////////// * includes */ #include "prefix.h" +/* ////////////////////////////////////////////////////////////////////////////////////// + * privates + */ + +static tb_char_t const* xm_string_ltrim(tb_char_t const* strstart, tb_char_t const* strend, tb_char_t const* trimchars, + size_t ntrimchars) +{ + // check + tb_assert_and_check_return_val(strstart && strend && trimchars, tb_null); + + // done + tb_char_t const* p = strstart; + while (p < strend && tb_strnchr(trimchars, ntrimchars, *p)) + p++; + + return p; +} + +static tb_char_t const* xm_string_rtrim(tb_char_t const* strstart, tb_char_t const* strend, tb_char_t const* trimchars, + size_t ntrimchars) +{ + // check + tb_assert_and_check_return_val(strstart && strend && trimchars, tb_null); + + // done + tb_char_t const* p = strend - 1; + while (p >= strstart && tb_strnchr(trimchars, ntrimchars, *p)) + p--; + + return p + 1; +} + /* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ -/* trim string +/* trim string + * + * @param str the string + * @param trimchars the chars to trim + * @param trimtype 0 to trim left and right, -1 to trim left, 1 to trim right * - * @param cstr the c-string - * @param mode the trim mode, all: 0, left: -1, right: 1 + * @code + * local result = string.trim(str, "\r\n \v\t", 0) + * local result = string.trim(str, "(", -1) + * @endcode */ tb_int_t xm_string_trim(lua_State* lua) { // check tb_assert_and_check_return_val(lua, 0); - // get the string and trim mode - size_t size = 0; - tb_char_t const* cstr = luaL_checklstring(lua, 1, &size); - ptrdiff_t mode = luaL_optinteger(lua, 2, 0); - tb_check_return_val(cstr, 0); - - // empty string? - if (!size) lua_pushstring(lua, ""); - else - { - tb_char_t const* p = cstr; - tb_char_t const* e = cstr + size; - - // trim left? - if (mode <= 0) while (p < e && tb_isspace(*p)) p++; - - // trim right - if (mode >= 0) - { - e--; - while (e >= cstr && tb_isspace(*e)) e--; - e++; - } - - // save trimed string - if (e > p) lua_pushlstring(lua, p, e - p); - else lua_pushstring(lua, ""); - } + size_t lstr, ltrim; + tb_char_t const* sstr = luaL_checklstring(lua, 1, &lstr); + tb_char_t const* estr = sstr + lstr; + tb_char_t const* trimchars = luaL_optlstring(lua, 2, "\r\n\t \f\v", <rim); + tb_int64_t const trimtype = (tb_int64_t)luaL_optinteger(lua, 3, 0); + + tb_char_t const* const rsstr = sstr; + tb_char_t const* const restr = estr; + + tb_assert_and_check_goto(sstr && trimchars, failed); + // empty string or empty tmim chars + tb_check_goto(ltrim != 0 && lstr != 0, failed); + + // trim chars + if (trimtype <= 0) sstr = xm_string_ltrim(sstr, estr, trimchars, ltrim); + if (trimtype >= 0) estr = xm_string_rtrim(sstr, estr, trimchars, ltrim); + + // no trimed chars + tb_check_goto(sstr != rsstr || estr != restr, failed); // ok + lua_pushlstring(lua, sstr, estr - sstr); + return 1; + +failed: + // return orignal value + lua_settop(lua, 1); return 1; } diff --git a/xmake/core/base/string.lua b/xmake/core/base/string.lua index 77cb36e68..b59706a6d 100644 --- a/xmake/core/base/string.lua +++ b/xmake/core/base/string.lua @@ -190,18 +190,18 @@ function string:split(delimiter, opt) end -- trim the spaces -function string:trim() - return self:_trim(0) +function string:trim(trimchars) + return string._trim(self, trimchars, 0) end -- trim the left spaces -function string:ltrim() - return self:_trim(-1) +function string:ltrim(trimchars) + return string._trim(self, trimchars, -1) end -- trim the right spaces -function string:rtrim() - return self:_trim(1) +function string:rtrim(trimchars) + return string._trim(self, trimchars, 1) end -- encode: ' ', '=', '\"', '<' -- cgit v1.3.1 From 510d25885f96a790951e6ba106461571bb421003 Mon Sep 17 00:00:00 2001 From: OpportunityLiu Date: Wed, 17 Jul 2019 11:06:04 +0800 Subject: no return --- core/src/xmake/string/trim.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/xmake/string/trim.c b/core/src/xmake/string/trim.c index 1a0738206..eab503ce0 100644 --- a/core/src/xmake/string/trim.c +++ b/core/src/xmake/string/trim.c @@ -38,7 +38,7 @@ static tb_char_t const* xm_string_ltrim(tb_char_t const* strstart, tb_char_t con size_t ntrimchars) { // check - tb_assert_and_check_return_val(strstart && strend && trimchars, tb_null); + tb_assert(strstart && strend && trimchars); // done tb_char_t const* p = strstart; @@ -52,7 +52,7 @@ static tb_char_t const* xm_string_rtrim(tb_char_t const* strstart, tb_char_t con size_t ntrimchars) { // check - tb_assert_and_check_return_val(strstart && strend && trimchars, tb_null); + tb_assert(strstart && strend && trimchars); // done tb_char_t const* p = strend - 1; -- cgit v1.3.1 From aaa64a03788b8403c4e7b223ae3682d8d048280e Mon Sep 17 00:00:00 2001 From: OpportunityLiu Date: Wed, 17 Jul 2019 11:38:20 +0800 Subject: add trim_space --- core/src/xmake/string/trim.c | 91 +++++++++++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 30 deletions(-) diff --git a/core/src/xmake/string/trim.c b/core/src/xmake/string/trim.c index eab503ce0..b2e1fa4f5 100644 --- a/core/src/xmake/string/trim.c +++ b/core/src/xmake/string/trim.c @@ -34,29 +34,54 @@ * privates */ -static tb_char_t const* xm_string_ltrim(tb_char_t const* strstart, tb_char_t const* strend, tb_char_t const* trimchars, - size_t ntrimchars) +static tb_void_t xm_string_trim_space(tb_char_t const** psstr, tb_char_t const** pestr, tb_int64_t mode) { // check - tb_assert(strstart && strend && trimchars); + tb_assert(psstr && pestr && *psstr && *pestr); + + tb_char_t const* p = *psstr; + tb_char_t const* e = *pestr; + + // trim left? + if (mode <= 0) + while (p < e && tb_isspace(*p)) + p++; + + // trim right + if (mode >= 0) + { + e--; + while (e >= p && tb_isspace(*e)) + e--; + e++; + } + + // save trimed string + *psstr = p; + *pestr = e; +} + +static tb_char_t const* xm_string_ltrim(tb_char_t const* sstr, tb_char_t const* estr, tb_char_t const* ctrim, size_t ntrim) +{ + // check + tb_assert(sstr && estr && ctrim); // done - tb_char_t const* p = strstart; - while (p < strend && tb_strnchr(trimchars, ntrimchars, *p)) + tb_char_t const* p = sstr; + while (p < estr && tb_strnchr(ctrim, ntrim, *p)) p++; return p; } -static tb_char_t const* xm_string_rtrim(tb_char_t const* strstart, tb_char_t const* strend, tb_char_t const* trimchars, - size_t ntrimchars) +static tb_char_t const* xm_string_rtrim(tb_char_t const* sstr, tb_char_t const* estr, tb_char_t const* ctrim, size_t ntrim) { // check - tb_assert(strstart && strend && trimchars); + tb_assert(sstr && estr && ctrim); // done - tb_char_t const* p = strend - 1; - while (p >= strstart && tb_strnchr(trimchars, ntrimchars, *p)) + tb_char_t const* p = estr - 1; + while (p >= sstr && tb_strnchr(ctrim, ntrim, *p)) p--; return p + 1; @@ -85,28 +110,34 @@ tb_int_t xm_string_trim(lua_State* lua) size_t lstr, ltrim; tb_char_t const* sstr = luaL_checklstring(lua, 1, &lstr); tb_char_t const* estr = sstr + lstr; - tb_char_t const* trimchars = luaL_optlstring(lua, 2, "\r\n\t \f\v", <rim); + tb_char_t const* trimchars = luaL_optlstring(lua, 2, "", <rim); tb_int64_t const trimtype = (tb_int64_t)luaL_optinteger(lua, 3, 0); + do + { + tb_assert_and_check_break(sstr && trimchars); + // empty string + tb_check_break(lstr != 0); + + tb_char_t const* const rsstr = sstr; + tb_char_t const* const restr = estr; + if (ltrim == 0) + xm_string_trim_space(&sstr, &estr, trimtype); + else + { + // trim chars + if (trimtype <= 0) sstr = xm_string_ltrim(sstr, estr, trimchars, ltrim); + if (trimtype >= 0) estr = xm_string_rtrim(sstr, estr, trimchars, ltrim); + } + + // no trimed chars + tb_check_break(sstr != rsstr || estr != restr); + + // ok + lua_pushlstring(lua, sstr, estr - sstr); + return 1; + + } while (tb_false); - tb_char_t const* const rsstr = sstr; - tb_char_t const* const restr = estr; - - tb_assert_and_check_goto(sstr && trimchars, failed); - // empty string or empty tmim chars - tb_check_goto(ltrim != 0 && lstr != 0, failed); - - // trim chars - if (trimtype <= 0) sstr = xm_string_ltrim(sstr, estr, trimchars, ltrim); - if (trimtype >= 0) estr = xm_string_rtrim(sstr, estr, trimchars, ltrim); - - // no trimed chars - tb_check_goto(sstr != rsstr || estr != restr, failed); - - // ok - lua_pushlstring(lua, sstr, estr - sstr); - return 1; - -failed: // return orignal value lua_settop(lua, 1); return 1; -- cgit v1.3.1 From 09f10b74034b040a6cb56640cd2c2f1027051b50 Mon Sep 17 00:00:00 2001 From: OpportunityLiu Date: Wed, 17 Jul 2019 12:59:26 +0800 Subject: add tests --- core/src/xmake/string/trim.c | 10 +++++----- tests/modules/string/test.lua | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/core/src/xmake/string/trim.c b/core/src/xmake/string/trim.c index b2e1fa4f5..1c03e999a 100644 --- a/core/src/xmake/string/trim.c +++ b/core/src/xmake/string/trim.c @@ -22,8 +22,8 @@ /* ////////////////////////////////////////////////////////////////////////////////////// * trace */ -#define TB_TRACE_MODULE_NAME "trim" -#define TB_TRACE_MODULE_DEBUG (0) +#define TB_TRACE_MODULE_NAME "trim" +#define TB_TRACE_MODULE_DEBUG (0) /* ////////////////////////////////////////////////////////////////////////////////////// * includes @@ -34,7 +34,7 @@ * privates */ -static tb_void_t xm_string_trim_space(tb_char_t const** psstr, tb_char_t const** pestr, tb_int64_t mode) +static tb_void_t xm_string_trim_space(tb_char_t const** psstr, tb_char_t const** pestr, tb_int_t mode) { // check tb_assert(psstr && pestr && *psstr && *pestr); @@ -111,7 +111,7 @@ tb_int_t xm_string_trim(lua_State* lua) tb_char_t const* sstr = luaL_checklstring(lua, 1, &lstr); tb_char_t const* estr = sstr + lstr; tb_char_t const* trimchars = luaL_optlstring(lua, 2, "", <rim); - tb_int64_t const trimtype = (tb_int64_t)luaL_optinteger(lua, 3, 0); + tb_int_t const trimtype = (tb_int_t)luaL_optinteger(lua, 3, 0); do { tb_assert_and_check_break(sstr && trimchars); @@ -136,7 +136,7 @@ tb_int_t xm_string_trim(lua_State* lua) lua_pushlstring(lua, sstr, estr - sstr); return 1; - } while (tb_false); + } while (0); // return orignal value lua_settop(lua, 1); diff --git a/tests/modules/string/test.lua b/tests/modules/string/test.lua index fbbadde08..538dfd893 100644 --- a/tests/modules/string/test.lua +++ b/tests/modules/string/test.lua @@ -14,27 +14,42 @@ function test_startswith(t) end function test_trim(t) + t:are_equal((""):trim(), "") + t:are_equal((" "):trim(), "") + t:are_equal((""):trim(""), "") + t:are_equal((" "):trim(""), "") t:are_equal((" aaa ccc "):trim(), "aaa ccc") t:are_equal(("aaa ccc "):trim(), "aaa ccc") t:are_equal((" aaa ccc"):trim(), "aaa ccc") t:are_equal(("aaa ccc"):trim(), "aaa ccc") t:are_equal(("\t\naaa ccc\r\n"):trim(), "aaa ccc") + t:are_equal(("aba"):trim("a"), "b") end function test_ltrim(t) + t:are_equal((""):ltrim(), "") + t:are_equal((" "):ltrim(), "") + t:are_equal((""):ltrim(""), "") + t:are_equal((" "):ltrim(""), "") t:are_equal((" aaa ccc "):ltrim(), "aaa ccc ") t:are_equal(("aaa ccc "):ltrim(), "aaa ccc ") t:are_equal((" aaa ccc"):ltrim(), "aaa ccc") t:are_equal(("aaa ccc"):ltrim(), "aaa ccc") t:are_equal(("\t\naaa ccc\r\n"):ltrim(), "aaa ccc\r\n") + t:are_equal(("aba"):ltrim("a"), "ba") end function test_rtrim(t) + t:are_equal((""):rtrim(), "") + t:are_equal((" "):rtrim(), "") + t:are_equal((""):rtrim(""), "") + t:are_equal((" "):rtrim(""), "") t:are_equal((" aaa ccc "):rtrim(), " aaa ccc") t:are_equal(("aaa ccc "):rtrim(), "aaa ccc") t:are_equal((" aaa ccc"):rtrim(), " aaa ccc") t:are_equal(("aaa ccc"):rtrim(), "aaa ccc") t:are_equal(("\t\naaa ccc\r\n"):rtrim(), "\t\naaa ccc") + t:are_equal(("aba"):rtrim("a"), "ab") end function test_split(t) -- cgit v1.3.1