mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-22 04:25:18 +00:00
glibcompat: "Backport" 'g_string_replace'
Backport the implementation of 'g_string_replace' until we require at least glib-2.68 Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
66112fbabb
commit
63080f0582
@ -1864,6 +1864,7 @@ vir_g_fsync;
|
||||
vir_g_source_unref;
|
||||
vir_g_strdup_printf;
|
||||
vir_g_strdup_vprintf;
|
||||
vir_g_string_replace;
|
||||
|
||||
|
||||
# util/viracpi.c
|
||||
|
@ -155,3 +155,68 @@ void vir_g_source_unref(GSource *src, GMainContext *ctx)
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Adapted (to pass syntax check) from 'g_string_replace' from
|
||||
* glib-2.81.1. Drop once minimum glib is bumped to 2.68.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* If @find is the empty string, since versions 2.69.1 and 2.68.4 the
|
||||
* replacement will be inserted no more than once per possible position
|
||||
* (beginning of string, end of string and between characters). This did
|
||||
* not work correctly in earlier versions.
|
||||
*
|
||||
* Returns: the number of find and replace operations performed.
|
||||
*
|
||||
* Since: 2.68
|
||||
*/
|
||||
guint
|
||||
vir_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++;
|
||||
/* Only match the empty string once at any given position, to
|
||||
* avoid infinite loops */
|
||||
if (f_len == 0) {
|
||||
if (cur[0] == '\0')
|
||||
break;
|
||||
else
|
||||
cur++;
|
||||
}
|
||||
if (n == limit)
|
||||
break;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
@ -85,6 +85,16 @@ char *vir_g_strdup_vprintf(const char *msg, va_list args)
|
||||
|
||||
void vir_g_source_unref(GSource *src, GMainContext *ctx);
|
||||
|
||||
|
||||
/* Drop once we require glib-2.68 at minimum */
|
||||
guint
|
||||
vir_g_string_replace(GString *string,
|
||||
const gchar *find,
|
||||
const gchar *replace,
|
||||
guint limit);
|
||||
#undef g_string_replace
|
||||
#define g_string_replace vir_g_string_replace
|
||||
|
||||
#if !GLIB_CHECK_VERSION(2, 73, 2)
|
||||
# if (defined(__has_attribute) && __has_attribute(__noinline__)) || G_GNUC_CHECK_VERSION (2, 96)
|
||||
# if defined (__cplusplus) && __cplusplus >= 201103L
|
||||
|
Loading…
x
Reference in New Issue
Block a user