* src/gstring.c (g_string_truncate): Implement truncate.
(g_string_prepend): implement.
Fix various bugs uncovered by new tests.
* src/glib.h: introduce gssize type, the signed one. Important.
* src/eglib-config.h (G_OS_): Add the G_OS_UNIX and G_OS_WIN32
defines that we can use to check on the host OS.
svn path=/trunk/mono/; revision=64035
2006-08-18 Miguel de Icaza <miguel@novell.com>
+ * src/gstring.c (g_string_truncate): Implement truncate.
+ (g_string_prepend): implement.
+
+ Fix various bugs uncovered by new tests.
+
+ * src/glib.h: introduce gssize type, the signed one. Important.
+
* src/eglib-config.h (G_OS_): Add the G_OS_UNIX and G_OS_WIN32
defines that we can use to check on the host OS.
2 g_timer_stop
2 g_timer_start
2 g_timer_new
- 2 g_string_append_len
2 g_strdelimit
2 g_shell_parse_argv
2 g_set_prgname
2 g_array_append_val
1 g_win32_getlocale
1 g_timer_destroy
- 1 g_string_truncate
- 1 g_string_prepend
1 g_strescape
1 g_spawn_command_line_sync
1 g_spawn_async_with_pipes
typedef int gboolean;
typedef int gint;
typedef unsigned int gsize;
+typedef signed int gssize;
typedef unsigned int guint;
typedef short gshort;
typedef unsigned short gushort;
} GString;
GString *g_string_new (const gchar *init);
-GString *g_string_new_len (const gchar *init, gsize len);
+GString *g_string_new_len (const gchar *init, gssize len);
GString *g_string_sized_new (gsize default_size);
gchar *g_string_free (GString *string, gboolean free_segment);
GString *g_string_append (GString *string, const gchar *val);
void g_string_append_printf (GString *string, const gchar *format, ...);
GString *g_string_append_c (GString *string, gchar c);
GString *g_string_append (GString *string, const gchar *val);
-GString *g_string_append_len (GString *string, const gchar *val, gsize len);
+GString *g_string_append_len (GString *string, const gchar *val, gssize len);
+GString *g_string_truncate (GString *string, gsize len);
+GString *g_string_prepend (GString *string, const gchar *val);
+
#define g_string_sprintfa g_string_append_printf
/*
gunichar g_unichar_tolower (gunichar c);
GUnicodeType g_unichar_type (gunichar c);
+#ifndef MAX
+#define MAX(a,b) (((a)>(b)) ? (a) : (b))
+#endif
+
#endif
#include <stdlib.h>
#include <glib.h>
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-
typedef struct _GPtrArrayPriv {
gpointer *pdata;
guint len;
}
GString *
-g_string_new_len (const gchar *init, gsize len)
+g_string_new_len (const gchar *init, gssize len)
{
GString *ret = g_new (GString, 1);
}
GString *
-g_string_append_len (GString *string, const gchar *val, gsize len)
+g_string_append_len (GString *string, const gchar *val, gssize len)
{
int size;
char *new;
g_return_val_if_fail (string != NULL, NULL);
g_return_val_if_fail (val != NULL, string);
+ if (len < 0)
+ return g_string_append (string, val);
if ((string->len + len) < string->allocated_len){
memcpy (string->str+string->len, val, len);
GString *
g_string_truncate (GString *string, gsize len)
{
+ g_return_val_if_fail (string != NULL, string);
+
+ /* Silent return */
+ if (len < 0)
+ return string;
+
+ if (len >= string->len)
+ return string;
+ string->len = len;
+ string->str [len] = 0;
+ return string;
+}
+
+GString *
+g_string_prepend (GString *string, const gchar *val)
+{
+ int vallen;
+ g_return_val_if_fail (string != NULL, string);
+ g_return_val_if_fail (val != NULL, string);
+
+ vallen = strlen (val);
+
+ if ((string->len + vallen + 1) < string->allocated_len){
+ memmove (string->str+vallen, string->str, string->len+1);
+ memcpy (string->str, val, vallen);
+ } else {
+ /*
+ * Add some extra space, so we do not reallocate too often
+ * maybe we should centralize this decision somewhere else.
+ */
+ char *new;
+ int nl = MAX (string->len + vallen + 1, string->allocated_len);
+ nl = nl < 8192 ? (nl * 3) : nl + 1024;
+
+ new = malloc (nl);
+ /* Failure */
+ if (new == NULL) {
+ g_error ("No more memory");
+ return string;
+ }
+ strcpy (new, val);
+ /* To cope with embedded nulls */
+ memcpy (new + vallen, string->str, string->len);
+ string->len = string->len + vallen;
+ g_free (string->str);
+ string->str = new;
+ string->allocated_len = nl;
+ }
+
return string;
}
+
return OK;
}
+static char *
+test_sized ()
+{
+ GString *s = g_string_sized_new (20);
+
+ if (s->str [0] != 0)
+ return result ("Expected an empty string");
+ if (s->len != 0)
+ return result ("Expected an empty len");
+
+ g_string_free (s, TRUE);
+
+ return NULL;
+}
+
+static char *
+test_truncate ()
+{
+ GString *s = g_string_new ("0123456789");
+ g_string_truncate (s, 3);
+
+ if (strlen (s->str) != 3)
+ return result ("size of string should have been 3, instead it is [%s]\n", s->str);
+ g_string_free (s, TRUE);
+
+ s = g_string_new ("a");
+ s = g_string_truncate (s, 10);
+ if (strlen (s->str) != 1)
+ return result ("The size is not 1");
+ g_string_truncate (s, -1);
+ if (strlen (s->str) != 1)
+ return result ("The size is not 1");
+ g_string_truncate (s, 0);
+ if (strlen (s->str) != 0)
+ return result ("The size is not 0");
+
+ g_string_free (s, TRUE);
+
+ return NULL;
+}
+
+static char *
+test_prepend ()
+{
+ GString *s = g_string_new ("dingus");
+ g_string_prepend (s, "one");
+
+ if (strcmp (s->str, "onedingus") != 0)
+ return result ("Failed, expected onedingus, got [%s]", s->str);
+
+ g_string_free (s, TRUE);
+
+ /* This is to force the code that where stuff does not fit in the allocated block */
+ s = g_string_sized_new (1);
+ g_string_prepend (s, "one");
+ if (strcmp (s->str, "one") != 0)
+ return result ("Got erroneous result, expected [one] got [%s]", s->str);
+ g_string_free (s, TRUE);
+
+ /* This is to force the path where things fit */
+ s = g_string_new ("123123123123123123123123");
+ g_string_truncate (s, 1);
+ if (strcmp (s->str, "1") != 0)
+ return result ("Expected [1] string, got [%s]", s->str);
+
+ g_string_prepend (s, "pre");
+ if (strcmp (s->str, "pre1") != 0)
+ return result ("Expected [pre1], got [%s]", s->str);
+ g_string_free (s, TRUE);
+
+ return NULL;
+}
+
+static char *
+test_appendlen ()
+{
+ GString *s = g_string_new ("");
+
+ g_string_append_len (s, "boo\000x", 0);
+ if (s->len != 0)
+ return result ("The length is not zero %d", s->len);
+ g_string_append_len (s, "boo\000x", 5);
+ if (s->len != 5)
+ return result ("The length is not five %d", s->len);
+ g_string_append_len (s, "ha", -1);
+ if (s->len != 7)
+ return result ("The length is not seven %d", s->len);
+
+ g_string_free (s, FALSE);
+
+ return NULL;
+}
+
static Test string_tests [] = {
- {"GString", test_gstring},
+ {"constructors+append", test_gstring },
+ {"constructor-sized", test_sized },
+ {"truncate", test_truncate },
+ {"prepend", test_prepend },
+ {"append_len", test_appendlen },
{NULL, NULL}
};