summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Withnall <philip@tecnocode.co.uk>2021-02-09 10:50:16 +0000
committerPhilip Withnall <philip@tecnocode.co.uk>2021-02-09 10:50:16 +0000
commitdc1f133c889d52725d70a62bbbba861655548139 (patch)
treef6c6731c302a5e4274d114f2642f1ece2de6c9d4
parent652026b9d130044a43719a1b7a7181f9d77a90fa (diff)
parentc576a4cd825462be4998bcf67937bf24bee475ac (diff)
downloadglib-dc1f133c889d52725d70a62bbbba861655548139.tar.gz
Merge branch '225' into 'master'
string: Add find and replace function Closes #225 See merge request GNOME/glib!1828
-rw-r--r--docs/reference/glib/glib-sections.txt1
-rw-r--r--glib/gstring.c49
-rw-r--r--glib/gstring.h5
-rw-r--r--glib/tests/string.c29
4 files changed, 84 insertions, 0 deletions
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index 2e219cf0c..1f27ec501 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -2861,6 +2861,7 @@ g_string_insert_unichar
g_string_insert_len
g_string_overwrite
g_string_overwrite_len
+g_string_replace
g_string_erase
g_string_truncate
g_string_set_size
diff --git a/glib/gstring.c b/glib/gstring.c
index 85294258b..030d75316 100644
--- a/glib/gstring.c
+++ b/glib/gstring.c
@@ -954,6 +954,55 @@ g_string_erase (GString *string,
}
/**
+ * g_string_replace:
+ * @string: a #GString
+ * @find: the string to find in @string
+ * @replace: the string to insert in place of @find
+ * @limit: the maximum instances of @find to replace with @replace, or `0` for
+ * no limit
+ *
+ * Replaces the string @find with the string @replace in a #GString up to
+ * @limit times. If the number of instances of @find in the #GString is
+ * less than @limit, all instances are replaced. If the number of
+ * instances is `0`, all instances of @find are replaced.
+ *
+ * Returns: the number of find and replace operations performed.
+ *
+ * Since: 2.68
+ */
+guint
+g_string_replace (GString *string,
+ const gchar *find,
+ const gchar *replace,
+ guint limit)
+{
+ gsize f_len, r_len, pos;
+ gchar *cur, *next;
+ gint n = 0;
+
+ g_return_val_if_fail (string != NULL, 0);
+ g_return_val_if_fail (find != NULL, 0);
+ g_return_val_if_fail (replace != NULL, 0);
+
+ f_len = strlen (find);
+ r_len = strlen (replace);
+ cur = string->str;
+
+ while ((next = strstr (cur, find)) != NULL)
+ {
+ pos = next - string->str;
+ g_string_erase (string, pos, f_len);
+ g_string_insert (string, pos, replace);
+ cur = string->str + pos + r_len;
+ n++;
+ if (n == limit)
+ break;
+ }
+
+ return n;
+}
+
+/**
* g_string_ascii_down:
* @string: a GString
*
diff --git a/glib/gstring.h b/glib/gstring.h
index e1b2e7fca..eec4c138f 100644
--- a/glib/gstring.h
+++ b/glib/gstring.h
@@ -127,6 +127,11 @@ GLIB_AVAILABLE_IN_ALL
GString* g_string_erase (GString *string,
gssize pos,
gssize len);
+GLIB_AVAILABLE_IN_2_68
+guint g_string_replace (GString *string,
+ const gchar *find,
+ const gchar *replace,
+ guint limit);
GLIB_AVAILABLE_IN_ALL
GString* g_string_ascii_down (GString *string);
GLIB_AVAILABLE_IN_ALL
diff --git a/glib/tests/string.c b/glib/tests/string.c
index cb5df4cec..819b192fb 100644
--- a/glib/tests/string.c
+++ b/glib/tests/string.c
@@ -495,6 +495,34 @@ test_string_to_bytes (void)
g_bytes_unref (bytes);
}
+static void
+test_string_replace (void)
+{
+ GString *s;
+ gint n;
+
+ s = g_string_new ("foo bar foo baz foo bar foobarbaz");
+
+ n = g_string_replace (s, "bar", "baz", 0);
+ g_assert_cmpstr ("foo baz foo baz foo baz foobazbaz", ==, s->str);
+ g_assert_cmpint (n, ==, 3);
+
+ n = g_string_replace (s, "baz", "bar", 3);
+ g_assert_cmpstr ("foo bar foo bar foo bar foobazbaz", ==, s->str);
+ g_assert_cmpint (n, ==, 3);
+
+ n = g_string_replace (s, "foobar", "bar", 1);
+ g_assert_cmpstr ("foo bar foo bar foo bar foobazbaz", ==, s->str);
+ g_assert_cmpint (n, ==, 0);
+
+ s = g_string_assign (s, "aaaaaaaa");
+ n = g_string_replace (s, "a", "abcdefghijkl", 0);
+ g_assert_cmpstr ("abcdefghijklabcdefghijklabcdefghijklabcdefghijklabcdefghijklabcdefghijklabcdefghijklabcdefghijkl",
+ ==, s->str);
+
+ g_string_free (s, TRUE);
+}
+
int
main (int argc,
char *argv[])
@@ -519,6 +547,7 @@ main (int argc,
g_test_add_func ("/string/test-string-up-down", test_string_up_down);
g_test_add_func ("/string/test-string-set-size", test_string_set_size);
g_test_add_func ("/string/test-string-to-bytes", test_string_to_bytes);
+ g_test_add_func ("/string/test-string-replace", test_string_replace);
return g_test_run();
}