Skip to content

Commit

Permalink
utils: Replace as_gstring_replace definition with upstream's
Browse files Browse the repository at this point in the history
Until we can depend on 2.68, it's probably best to standardise on one
implementation - also, this one is much simpler.
  • Loading branch information
Iain Lane committed Jun 7, 2021
1 parent 0ca74e1 commit 6816d54
Showing 1 changed file with 26 additions and 46 deletions.
72 changes: 26 additions & 46 deletions src/as-utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -595,64 +595,44 @@ as_ptr_array_to_strv (GPtrArray *array)
/**
* as_gstring_replace:
* @string: The #GString to operate on
* @search: The text to search for
* @find: The text to search for
* @replace: The text to use for substitutions
*
* Performs multiple search and replace operations on the given string.
*
* Returns: the number of replacements done, or 0 if @search is not found.
**/
guint
as_gstring_replace (GString *string, const gchar *search, const gchar *replace)
{
gchar *tmp;
guint count = 0;
gsize search_idx = 0;
gsize replace_len;
gsize search_len;
as_gstring_replace (GString *string, const gchar *find, const gchar *replace)
{
/* note: This is a direct copy from GLib upstream (with whitespace
* fixed spaces to tabs). Once we can depend on GLib 2.68, this copy
* should be dropped and g_string_replace() used instead.
*
* GLib is licensed under the LGPL-2.1+.
*/
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 (search != NULL, 0);
g_return_val_if_fail (find != NULL, 0);
g_return_val_if_fail (replace != NULL, 0);

/* nothing to do */
if (string->len == 0)
return 0;

search_len = strlen (search);
replace_len = strlen (replace);

do {
tmp = g_strstr_len (string->str + search_idx, -1, search);
if (tmp == NULL)
break;

/* advance the counter in case @replace contains @search */
search_idx = (gsize) (tmp - string->str);

/* reallocate the string if required */
if (search_len > replace_len) {
g_string_erase (string,
(gssize) search_idx,
(gssize) (search_len - replace_len));
memcpy (tmp, replace, replace_len);
} else if (search_len < replace_len) {
g_string_insert_len (string,
(gssize) search_idx,
replace,
(gssize) (replace_len - search_len));
/* we have to treat this specially as it could have
* been reallocated when the insertion happened */
memcpy (string->str + search_idx, replace, replace_len);
} else {
/* just memcmp in the new string */
memcpy (tmp, replace, replace_len);
}
search_idx += replace_len;
count++;
} while (TRUE);
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++;
}

return count;
return n;
}

/**
Expand Down

0 comments on commit 6816d54

Please sign in to comment.