Tarantool development patches archive
 help / color / mirror / Atom feed
From: "Michał Durak" <dmarc-noreply@freelists.org> (Redacted sender "gdrbyko1" for DMARC)
To: "tarantool-patches@freelists.org" <tarantool-patches@freelists.org>
Subject: [tarantool-patches] [PATCH] lua: add optional 'chars' param to string.strip functions
Date: Thu, 20 Dec 2018 18:02:51 +0000	[thread overview]
Message-ID: <cVaRUKT0tLzagYw9QaRJmfTPuMRDZbMPvf_fNsKyZaq-7sQ8mbH6FxQVNiGdLqRuMZqgnaRB5v2Jkxg34gRgaXdZsVX9uA-k4mmbKxncPhw=@protonmail.com> (raw)

Add optional 'chars' parameter to string.strip, string.lstrip
and string.rstrip for specifying the unwanted characters.
Behavior modeled after the equivalent Python built-ins.

Closes: #2977
---

branch: https://github.com/gdrbyKo1/tarantool/tree/gh-2977
issue:  https://github.com/tarantool/tarantool/issues/2977

 src/lua/string.lua           | 51 ++++++++++++++++++++++++++++++++++++++------
 test/app-tap/string.test.lua | 44 +++++++++++++++++++++++++++++++-------
 2 files changed, 81 insertions(+), 14 deletions(-)

diff --git a/src/lua/string.lua b/src/lua/string.lua
index cbce26b35..9eab33423 100644
--- a/src/lua/string.lua
+++ b/src/lua/string.lua
@@ -339,25 +339,64 @@ local function string_fromhex(inp)
     return ffi.string(res, len)
 end

-local function string_strip(inp)
+local function string_strip(inp, chars)
     if type(inp) ~= 'string' then
         error(err_string_arg:format(1, "string.strip", 'string', type(inp)), 2)
     end
-    return (string.gsub(inp, "^%s*(.-)%s*$", "%1"))
+    if chars == nil then
+        return (string.gsub(inp, "^%s*(.-)%s*$", "%1"))
+    end
+
+    if type(chars) ~= 'string' then
+        error(err_string_arg:format(2, "string.strip", 'string', type(chars)), 2)
+    end
+    if chars == '' then
+        return inp
+    end
+
+    chars = chars:gsub('[%^%$%(%)%%%.%[%]%*%+%-%?]', "%%%0"):gsub('%z+', '%%z')
+    local pattern = string.format("^[%s]*(.-)[%s]*$", chars, chars)
+    return (string.gsub(inp, pattern, "%1"))
 end

-local function string_lstrip(inp)
+local function string_lstrip(inp, chars)
     if type(inp) ~= 'string' then
         error(err_string_arg:format(1, "string.lstrip", 'string', type(inp)), 2)
     end
-    return (string.gsub(inp, "^%s*(.-)", "%1"))
+    if chars == nil then
+        return (string.gsub(inp, "^%s*(.-)", "%1"))
+    end
+
+    if type(chars) ~= 'string' then
+        error(err_string_arg:format(2, "string.lstrip", 'string', type(chars)), 2)
+    end
+    if chars == '' then
+        return inp
+    end
+
+    chars = chars:gsub('[%^%$%(%)%%%.%[%]%*%+%-%?]', "%%%0"):gsub('%z+', '%%z')
+    local pattern = string.format("^[%s]*(.-)", chars)
+    return (string.gsub(inp, pattern, "%1"))
 end

-local function string_rstrip(inp)
+local function string_rstrip(inp, chars)
     if type(inp) ~= 'string' then
         error(err_string_arg:format(1, "string.rstrip", 'string', type(inp)), 2)
     end
-    return (string.gsub(inp, "(.-)%s*$", "%1"))
+    if chars == nil then
+        return (string.gsub(inp, "(.-)%s*$", "%1"))
+    end
+
+    if type(chars) ~= 'string' then
+        error(err_string_arg:format(2, "string.rstrip", 'string', type(chars)), 2)
+    end
+    if chars == '' then
+        return inp
+    end
+
+    chars = chars:gsub('[%^%$%(%)%%%.%[%]%*%+%-%?]', "%%%0"):gsub('%z+', '%%z')
+    local pattern = string.format("(.-)[%s]*$", chars)
+    return (string.gsub(inp, pattern, "%1"))
 end


diff --git a/test/app-tap/string.test.lua b/test/app-tap/string.test.lua
index 7203fcd36..6e87d3285 100755
--- a/test/app-tap/string.test.lua
+++ b/test/app-tap/string.test.lua
@@ -134,18 +134,46 @@ test:test("fromhex", function(test)
 end)

 test:test("strip", function(test)
-    test:plan(6)
+    test:plan(21)
     local str = "  hello hello "
-    test:is(string.len(string.strip(str)), 11, "strip")
-    test:is(string.len(string.lstrip(str)), 12, "lstrip")
-    test:is(string.len(string.rstrip(str)), 13, "rstrip")
+    test:is(string.len(string.strip(str)), 11, "strip (no chars)")
+    test:is(string.len(string.lstrip(str)), 12, "lstrip (no chars)")
+    test:is(string.len(string.rstrip(str)), 13, "rstrip (no chars)")
     local _, err = pcall(string.strip, 12)
-    test:ok(err and err:match("%(string expected, got number%)"))
+    test:ok(err and err:match("#1 to '.-%.strip' %(string expected, got number%)"))
     _, err = pcall(string.lstrip, 12)
-    test:ok(err and err:match("%(string expected, got number%)"))
+    test:ok(err and err:match("#1 to '.-%.lstrip' %(string expected, got number%)"))
     _, err = pcall(string.rstrip, 12)
-    test:ok(err and err:match("%(string expected, got number%)"))
-end )
+    test:ok(err and err:match("#1 to '.-%.rstrip' %(string expected, got number%)"))
+
+    str = "www.example.com/foo"
+    local chars = "w./fomc"
+    test:is(string.len(string.strip(str, chars)), 7, "strip (chars)")
+    test:is(string.len(string.lstrip(str, chars)), 15, "lstrip (chars)")
+    test:is(string.len(string.rstrip(str, chars)), 11, "rstrip (chars)")
+
+    str, chars = "^$()%.[]*+-?BEEP^$()%.[]*+-?%", "^$()%.[]*+-?"
+    test:is(string.len(string.strip(str, chars)), 4, "strip (magic chars)")
+    test:is(string.len(string.lstrip(str, chars)), 17, "lstrip (magic chars)")
+    test:is(string.len(string.rstrip(str, chars)), 16, "rstrip (magic chars)")
+
+    str, chars = "\0\00\000HELLO\000\00\0\0", "\0"
+    test:is(string.len(string.strip(str, chars)), 5, "strip (chars with embedded 0s)")
+    test:is(string.len(string.lstrip(str, chars)), 9, "lstrip (chars with embedded 0s)")
+    test:is(string.len(string.rstrip(str, chars)), 8, "rstrip (chars with embedded 0s)")
+
+    str, chars = " test ", ""
+    test:is(string.strip(str, chars), str, "strip (0-length chars)")
+    test:is(string.lstrip(str, chars), str, "lstrip (0-length chars)")
+    test:is(string.rstrip(str, chars), str, "rstrip (0-length chars)")
+
+    _, err = pcall(string.strip, 'foo', 12)
+    test:ok(err and err:match("#2 to '.-%.strip' %(string expected, got number%)"))
+    _, err = pcall(string.lstrip, 'bar', 12)
+    test:ok(err and err:match("#2 to '.-%.lstrip' %(string expected, got number%)"))
+    _, err = pcall(string.rstrip, 'baz', 12)
+    test:ok(err and err:match("#2 to '.-%.rstrip' %(string expected, got number%)"))
+end)

 test:test("unicode", function(test)
     test:plan(104)
--
2.11.0

             reply	other threads:[~2018-12-20 18:03 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-20 18:02 Michał Durak [this message]
2018-12-23  9:23 ` [tarantool-patches] " Alexander Turenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='cVaRUKT0tLzagYw9QaRJmfTPuMRDZbMPvf_fNsKyZaq-7sQ8mbH6FxQVNiGdLqRuMZqgnaRB5v2Jkxg34gRgaXdZsVX9uA-k4mmbKxncPhw=@protonmail.com' \
    --to=dmarc-noreply@freelists.org \
    --cc=tarantool-patches@freelists.org \
    --subject='Re: [tarantool-patches] [PATCH] lua: add optional '\''chars'\'' param to string.strip functions' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox