summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2019-07-17 13:51:27 +0800
committerGitHub <[email protected]>2019-07-17 13:51:27 +0800
commite0fbf9ffa3e809bd72afa6182f439db7cd6f4474 (patch)
tree732500a47d61a02cf333c3fa043e07ff1eeb989d
parent7138d5770975053ad4fe60f1d8bdd5e4c774fe5b (diff)
parent09f10b74034b040a6cb56640cd2c2f1027051b50 (diff)
Merge pull request #492 from OpportunityLiu/trim
Custom trim chars
-rw-r--r--core/src/xmake/string/trim.c124
-rw-r--r--tests/modules/string/test.lua15
-rw-r--r--xmake/core/base/string.lua12
3 files changed, 116 insertions, 35 deletions
diff --git a/core/src/xmake/string/trim.c b/core/src/xmake/string/trim.c
index c7cce0168..1c03e999a 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
*
*/
@@ -31,48 +31,114 @@
#include "prefix.h"
/* //////////////////////////////////////////////////////////////////////////////////////
+ * privates
+ */
+
+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);
+
+ 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 = sstr;
+ while (p < estr && tb_strnchr(ctrim, ntrim, *p))
+ p++;
+
+ return p;
+}
+
+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(sstr && estr && ctrim);
+
+ // done
+ tb_char_t const* p = estr - 1;
+ while (p >= sstr && tb_strnchr(ctrim, ntrim, *p))
+ p--;
+
+ return p + 1;
+}
+
+/* //////////////////////////////////////////////////////////////////////////////////////
* implementation
*/
-/* trim string
+/* trim string
*
- * @param cstr the c-string
- * @param mode the trim mode, all: 0, left: -1, right: 1
+ * @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
+ *
+ * @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
+ 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, "", &ltrim);
+ tb_int_t const trimtype = (tb_int_t)luaL_optinteger(lua, 3, 0);
+ do
{
- 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++;
+ tb_assert_and_check_break(sstr && trimchars);
+ // empty string
+ tb_check_break(lstr != 0);
- // trim right
- if (mode >= 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
{
- e--;
- while (e >= cstr && tb_isspace(*e)) e--;
- e++;
+ // trim chars
+ if (trimtype <= 0) sstr = xm_string_ltrim(sstr, estr, trimchars, ltrim);
+ if (trimtype >= 0) estr = xm_string_rtrim(sstr, estr, trimchars, ltrim);
}
- // save trimed string
- if (e > p) lua_pushlstring(lua, p, e - p);
- else lua_pushstring(lua, "");
- }
+ // no trimed chars
+ tb_check_break(sstr != rsstr || estr != restr);
+
+ // ok
+ lua_pushlstring(lua, sstr, estr - sstr);
+ return 1;
+
+ } while (0);
- // ok
+ // return orignal value
+ lua_settop(lua, 1);
return 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)
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: ' ', '=', '\"', '<'