Handle the case where the to-be-inserted string is a substring of the

2003-11-05  Morten Welinder  <terra@gnome.org>

	* glib/gstring.c (g_string_insert_len): Handle the case where the
	to-be-inserted string is a substring of the target string.
	(g_string_assign): Handle "s = s;".
	(#114260, self.)
This commit is contained in:
Morten Welinder 2003-11-05 16:24:44 +00:00 committed by Morten Welinder
parent 76433d5365
commit 3b2f74d188
8 changed files with 122 additions and 14 deletions

View File

@ -1,3 +1,10 @@
2003-11-05 Morten Welinder <terra@gnome.org>
* glib/gstring.c (g_string_insert_len): Handle the case where the
to-be-inserted string is a substring of the target string.
(g_string_assign): Handle "s = s;".
(#114260, self.)
Sun Nov 2 01:47:31 2003 Matthias Clasen <maclas@gmx.de>
Fix 64bit printing for MSVC builds (#119292, Hans Breuer):

View File

@ -1,3 +1,10 @@
2003-11-05 Morten Welinder <terra@gnome.org>
* glib/gstring.c (g_string_insert_len): Handle the case where the
to-be-inserted string is a substring of the target string.
(g_string_assign): Handle "s = s;".
(#114260, self.)
Sun Nov 2 01:47:31 2003 Matthias Clasen <maclas@gmx.de>
Fix 64bit printing for MSVC builds (#119292, Hans Breuer):

View File

@ -1,3 +1,10 @@
2003-11-05 Morten Welinder <terra@gnome.org>
* glib/gstring.c (g_string_insert_len): Handle the case where the
to-be-inserted string is a substring of the target string.
(g_string_assign): Handle "s = s;".
(#114260, self.)
Sun Nov 2 01:47:31 2003 Matthias Clasen <maclas@gmx.de>
Fix 64bit printing for MSVC builds (#119292, Hans Breuer):

View File

@ -1,3 +1,10 @@
2003-11-05 Morten Welinder <terra@gnome.org>
* glib/gstring.c (g_string_insert_len): Handle the case where the
to-be-inserted string is a substring of the target string.
(g_string_assign): Handle "s = s;".
(#114260, self.)
Sun Nov 2 01:47:31 2003 Matthias Clasen <maclas@gmx.de>
Fix 64bit printing for MSVC builds (#119292, Hans Breuer):

View File

@ -1,3 +1,10 @@
2003-11-05 Morten Welinder <terra@gnome.org>
* glib/gstring.c (g_string_insert_len): Handle the case where the
to-be-inserted string is a substring of the target string.
(g_string_assign): Handle "s = s;".
(#114260, self.)
Sun Nov 2 01:47:31 2003 Matthias Clasen <maclas@gmx.de>
Fix 64bit printing for MSVC builds (#119292, Hans Breuer):

View File

@ -1,3 +1,10 @@
2003-11-05 Morten Welinder <terra@gnome.org>
* glib/gstring.c (g_string_insert_len): Handle the case where the
to-be-inserted string is a substring of the target string.
(g_string_assign): Handle "s = s;".
(#114260, self.)
Sun Nov 2 01:47:31 2003 Matthias Clasen <maclas@gmx.de>
Fix 64bit printing for MSVC builds (#119292, Hans Breuer):

View File

@ -373,9 +373,15 @@ g_string_assign (GString *string,
{
g_return_val_if_fail (string != NULL, NULL);
g_return_val_if_fail (rval != NULL, string);
g_string_truncate (string, 0);
g_string_append (string, rval);
/* Make sure assigning to itself doesn't corrupt the string. */
if (string->str != rval)
{
/* Assigning from substring should be ok since g_string_truncate
does not realloc. */
g_string_truncate (string, 0);
g_string_append (string, rval);
}
return string;
}
@ -436,17 +442,50 @@ g_string_insert_len (GString *string,
pos = string->len;
else
g_return_val_if_fail (pos <= string->len, string);
g_string_maybe_expand (string, len);
/* If we aren't appending at the end, move a hunk
* of the old string to the end, opening up space
*/
if (pos < string->len)
g_memmove (string->str + pos + len, string->str + pos, string->len - pos);
/* insert the new string */
g_memmove (string->str + pos, val, len);
/* Check whether val represents a substring of string. This test
probably violates chapter and verse of the C standards, since
">=" and "<=" are only valid when val really is a substring.
In practice, it will work on modern archs. */
if (val >= string->str && val <= string->str + string->len)
{
gsize offset = val - string->str;
gsize precount = 0;
g_string_maybe_expand (string, len);
val = string->str + offset;
/* At this point, val is valid again. */
/* Open up space where we are going to insert. */
if (pos < string->len)
g_memmove (string->str + pos + len, string->str + pos, string->len - pos);
/* Move the source part before the gap, if any. */
if (offset < pos)
{
precount = MIN (len, pos - offset);
memcpy (string->str + pos, val, precount);
}
/* Move the source part after the gap, if any. */
if (len > precount)
memcpy (string->str + pos + precount,
val + /* Already moved: */ precount + /* Space opened up: */ len,
len - precount);
}
else
{
g_string_maybe_expand (string, len);
/* If we aren't appending at the end, move a hunk
* of the old string to the end, opening up space
*/
if (pos < string->len)
g_memmove (string->str + pos + len, string->str + pos, string->len - pos);
/* insert the new string */
memcpy (string->str + pos, val, len);
}
string->len += len;

View File

@ -89,7 +89,7 @@ main (int argc,
g_string_chunk_free (string_chunk);
string1 = g_string_new ("hi pete!");
string2 = g_string_new ("");
string2 = g_string_new (NULL);
g_assert (string1 != NULL);
g_assert (string2 != NULL);
@ -182,6 +182,33 @@ main (int argc,
g_assert (strcmp (string1->str, "firstlast") == 0);
g_string_free (string1, TRUE);
/* insert_len with string overlap */
string1 = g_string_new ("textbeforetextafter");
g_string_insert_len (string1, 10, string1->str + 8, 5);
g_assert (strcmp (string1->str, "textbeforeretextextafter") == 0);
g_string_free (string1, TRUE);
string1 = g_string_new ("boring text");
g_string_insert_len (string1, 7, string1->str + 2, 4);
g_assert (strcmp (string1->str, "boring ringtext") == 0);
g_string_free (string1, TRUE);
string1 = g_string_new ("boring text");
g_string_insert_len (string1, 6, string1->str + 7, 4);
g_assert (strcmp (string1->str, "boringtext text") == 0);
g_string_free (string1, TRUE);
/* assign_len with string overlap */
string1 = g_string_new ("textbeforetextafter");
g_string_assign (string1, string1->str + 10);
g_assert (strcmp (string1->str, "textafter") == 0);
g_string_free (string1, TRUE);
string1 = g_string_new ("boring text");
g_string_assign (string1, string1->str);
g_assert (strcmp (string1->str, "boring text") == 0);
g_string_free (string1, TRUE);
/* g_string_equal */
string1 = g_string_new ("test");
string2 = g_string_new ("te");