woohyun pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=c501d09c3aa4c3e7f1ab5a27171b897c3cb4a11c

commit c501d09c3aa4c3e7f1ab5a27171b897c3cb4a11c
Author: Ali Alzyod <ali198...@gmail.com>
Date:   Mon Jun 22 17:31:54 2020 +0900

    eina_strbuf: introduce change last occurrence function
    
    Reviewers: cedric, woohyun, bowonryu
    
    Reviewed By: cedric
    
    Subscribers: cedric, #reviewers, #committers
    
    Tags: #efl
    
    Maniphest Tasks: T8757
    
    Differential Revision: https://phab.enlightenment.org/D11990
---
 src/lib/eina/eina_strbuf.h        | 13 +++++++++
 src/lib/eina/eina_strbuf_common.c | 55 +++++++++++++++++++++++++++++++++++++++
 src/tests/eina/eina_test_strbuf.c |  6 ++++-
 3 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/src/lib/eina/eina_strbuf.h b/src/lib/eina/eina_strbuf.h
index da94435c2d..15d6294349 100644
--- a/src/lib/eina/eina_strbuf.h
+++ b/src/lib/eina/eina_strbuf.h
@@ -608,6 +608,19 @@ EAPI Eina_Bool eina_strbuf_replace(Eina_Strbuf *buf, const 
char *str, const char
  */
 #define eina_strbuf_replace_first(buf, str, with) eina_strbuf_replace(buf, 
str, with, 1)
 
+/**
+ * @brief Replaces the last occurrence of a substring with another string.
+ *
+ * @param[in,out] buf The string buffer.
+ * @param[in] str The text to match.
+ * @param[in] with The replacement string.
+ * @return #EINA_TRUE on success, #EINA_FALSE on failure.
+ *
+ * This function replaces the last occurrence of @p str in @p buf with
+ * @p with.
+ */
+EAPI Eina_Bool eina_strbuf_replace_last(Eina_Strbuf *buf, const char *str, 
const char *with) EINA_ARG_NONNULL(1, 2, 3);
+
 /**
  * @brief Replaces all matching substrings with another string.
  *
diff --git a/src/lib/eina/eina_strbuf_common.c 
b/src/lib/eina/eina_strbuf_common.c
index b4d3427a39..9a1d27d8ce 100644
--- a/src/lib/eina/eina_strbuf_common.c
+++ b/src/lib/eina/eina_strbuf_common.c
@@ -980,6 +980,61 @@ eina_strbuf_replace(Eina_Strbuf *buf,
    return EINA_TRUE;
 }
 
+EAPI Eina_Bool
+eina_strbuf_replace_last(Eina_Strbuf *buf,
+                    const char *str,
+                    const char *with)
+{
+   size_t len1, len2;
+   char *spos, *spos_next;
+   size_t pos;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL( str, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(with, EINA_FALSE);
+   EINA_MAGIC_CHECK_STRBUF(buf, 0);
+
+   spos = NULL;
+   spos_next = strstr(buf->buf, str);
+   while (spos_next && *spos_next)
+     {
+        spos = spos_next;
+        spos_next = strstr(spos + 1, str);
+     }
+
+   if (!spos) return EINA_FALSE;
+
+   pos = spos - (const char *)buf->buf;
+   len1 = strlen(str);
+   len2 = strlen(with);
+
+   /* This is a read only buffer which need change to be made */
+   if (buf->ro)
+     {
+        char *dest;
+
+        dest = malloc(buf->size);
+        if (!dest) return 0;
+        memcpy(dest, buf->buf, buf->len);
+        buf->buf = dest;
+     }
+
+   if (len1 != len2)
+     {
+        /* resize the buffer if necessary */
+        if (EINA_UNLIKELY(!_eina_strbuf_common_grow(_STRBUF_CSIZE, buf,
+                                                    buf->len - len1 + len2)))
+           return EINA_FALSE; /* move the existing text */
+        memmove(((unsigned char *)(buf->buf)) + pos + len2,
+                ((unsigned char *)(buf->buf)) + pos + len1,
+                buf->len - pos - len1);
+     }
+   /* and now insert the given string */
+   memcpy(((unsigned char *)(buf->buf)) + pos, with, len2);
+   buf->len += len2 - len1;
+   memset(((unsigned char *)(buf->buf)) + buf->len, 0, 1);
+   return EINA_TRUE;
+}
+
 EAPI int
 eina_strbuf_replace_all(Eina_Strbuf *buf, const char *str, const char *with)
 {
diff --git a/src/tests/eina/eina_test_strbuf.c 
b/src/tests/eina/eina_test_strbuf.c
index 1d9f52c0d2..ac99992a31 100644
--- a/src/tests/eina/eina_test_strbuf.c
+++ b/src/tests/eina/eina_test_strbuf.c
@@ -303,8 +303,12 @@ EFL_START_TEST(eina_test_strbuf_replace)
    fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
    fail_if(strcmp(eina_strbuf_string_get(buf), "baaaab"));
 
+   fail_if(eina_strbuf_replace_last(buf, "a", "x") == 0);
+   fail_if(strlen(eina_strbuf_string_get(buf)) != eina_strbuf_length_get(buf));
+   fail_if(strcmp(eina_strbuf_string_get(buf), "baaaxb"));
+
    fail_if(eina_strbuf_replace_first(buf, "a", "b") == 0);
-   fail_if(strcmp(eina_strbuf_string_get(buf), "bbaaab"));
+   fail_if(strcmp(eina_strbuf_string_get(buf), "bbaaxb"));
 
    eina_strbuf_free(buf);
 

-- 


Reply via email to