Skip to content
Snippets Groups Projects
Commit 779633ba authored by Simon McVittie's avatar Simon McVittie
Browse files

g_string_replace: Backport from GLib

Note that this implementation does not cope gracefully with zero-length
patterns (https://gitlab.gnome.org/GNOME/glib/-/issues/2452

) so we
should be careful not to use it like that. For the use-case that I
have in mind, that won't be a problem.

Signed-off-by: default avatarSimon McVittie <smcv@collabora.com>
parent 47dc463c
No related branches found
No related tags found
1 merge request!343g_string_replace: Backport from GLib
Pipeline #16369 passed
......@@ -157,3 +157,11 @@ gboolean my_g_ptr_array_find_with_equal_func (GPtrArray *haystack,
#define g_warning_once g_warning
#endif
#endif
#if !GLIB_CHECK_VERSION(2, 68, 0)
#define g_string_replace(s,f,r,l) my_g_string_replace (s, f, r, l)
guint my_g_string_replace (GString *string,
const gchar *find,
const gchar *replace,
guint limit);
#endif
......@@ -7,6 +7,7 @@
* Copyright 2013-2019 Collabora Ltd.
* Copyright 2018 Georges Basile Stavracas Neto
* Copyright 2018 Philip Withnall
* Copyright 2021 Joshua Lee
* g_execvpe implementation based on GNU libc execvp:
* Copyright 1991, 92, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
* SPDX-License-Identifier: LGPL-2.1-or-later
......@@ -586,3 +587,54 @@ my_g_ptr_array_find_with_equal_func (GPtrArray *haystack,
return FALSE;
}
#endif
#if !GLIB_CHECK_VERSION(2, 68, 0)
/**
* 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 @limit is `0`,
* all instances of @find are replaced.
*
* Returns: the number of find and replace operations performed.
*
* Since: 2.68
*/
guint
my_g_string_replace (GString *string,
const gchar *find,
const gchar *replace,
guint limit)
{
gsize f_len, r_len, pos;
gchar *cur, *next;
guint 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;
}
#endif
......@@ -29,6 +29,7 @@
#include <glib/gstdio.h>
#include <glib-object.h>
#include "steam-runtime-tools/glib-backports-internal.h"
#include "steam-runtime-tools/input-device-internal.h"
#include "steam-runtime-tools/utils-internal.h"
#include "test-utils.h"
......@@ -339,6 +340,38 @@ filter_gameoverlayrenderer (Fixture *f,
g_free (filtered_preload);
}
static void
test_gstring_replace (Fixture *f,
gconstpointer context)
{
static const struct
{
const char *string;
const char *original;
const char *replacement;
const char *expected;
}
tests[] =
{
{ "/usr/$LIB/libMangoHud.so", "$LIB", "lib32", "/usr/lib32/libMangoHud.so" },
{ "food for foals", "o", "", "fd fr fals" },
{ "aaa", "a", "aaa", "aaaaaaaaa" },
{ "aaa", "a", "", "" },
{ "aaa", "aa", "bb", "bba" },
};
gsize i;
for (i = 0; i < G_N_ELEMENTS (tests); i++)
{
g_autoptr(GString) buffer = g_string_new (tests[i].string);
g_string_replace (buffer, tests[i].original, tests[i].replacement, 0);
g_assert_cmpstr (buffer->str, ==, tests[i].expected);
g_assert_cmpuint (buffer->len, ==, strlen (tests[i].expected));
g_assert_cmpuint (buffer->allocated_len, >=, strlen (tests[i].expected) + 1);
}
}
static void
test_same_file (Fixture *f,
gconstpointer context)
......@@ -472,6 +505,8 @@ main (int argc,
filter_gameoverlayrenderer, teardown);
g_test_add ("/utils/get-path-after", Fixture, NULL,
setup, test_get_path_after, teardown);
g_test_add ("/utils/gstring-replace", Fixture, NULL,
setup, test_gstring_replace, teardown);
g_test_add ("/utils/same-file", Fixture, NULL,
setup, test_same_file, teardown);
g_test_add ("/utils/str_is_integer", Fixture, NULL,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment