+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):
+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):
+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):
+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):
+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):
+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):
{
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;
}
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;
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);
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");