2006-08-18 Miguel de Icaza <miguel@novell.com>
authorMiguel de Icaza <miguel@gnome.org>
Sat, 19 Aug 2006 00:55:57 +0000 (00:55 -0000)
committerMiguel de Icaza <miguel@gnome.org>
Sat, 19 Aug 2006 00:55:57 +0000 (00:55 -0000)
* 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

eglib/ChangeLog
eglib/TODO
eglib/src/glib.h
eglib/src/gptrarray.c
eglib/src/gstring.c
eglib/test/string.c

index e3cf2df2530a6c94270083bdc26394314fe94eea..08eb3b940e88942f47c0b932e48e43cc720ef4ed 100644 (file)
 
 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.
 
index 62379f339eb8332fd8e8ac9756ea6d13d62e4e12..f2d70379c5beab25a7ac2de2bb98286065150236 100644 (file)
@@ -64,7 +64,6 @@ Routines missing from eglib, by count number:
       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
@@ -90,8 +89,6 @@ Routines missing from eglib, by count number:
       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
index 41b93fc65f10cd0e4d8b3e8e9501ad6ee65f0ee4..755620f20184489972d0c3e841611a179c9a1d2e 100644 (file)
@@ -14,6 +14,7 @@
 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;
@@ -164,7 +165,7 @@ typedef struct {
 } 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);
@@ -172,7 +173,10 @@ void         g_string_printf        (GString *string, const gchar *format, ...);
 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
 
 /*
@@ -347,4 +351,8 @@ typedef enum {
 gunichar       g_unichar_tolower (gunichar c);
 GUnicodeType   g_unichar_type    (gunichar c);
 
+#ifndef MAX
+#define MAX(a,b) (((a)>(b)) ? (a) : (b))
+#endif
+
 #endif
index 1a5df1144f18226f96e899059e6efc927ea56b31..a875982a655eb43ff9ed5af2e2da3dbb6adb61d1 100644 (file)
@@ -30,8 +30,6 @@
 #include <stdlib.h>
 #include <glib.h>
 
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-
 typedef struct _GPtrArrayPriv {
        gpointer *pdata;
        guint len;
index 22cc2dd9a6abe4c92ea382338c0c9856a763405b..ae0ff39abe2717309ab8b14d103e84f8f5bff16a 100644 (file)
@@ -49,7 +49,7 @@ g_string_new (const gchar *init)
 }
 
 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);
 
@@ -151,13 +151,15 @@ g_string_append_c (GString *string, gchar c)
 }
 
 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);
@@ -215,5 +217,55 @@ g_string_printf (GString *string, const gchar *format, ...)
 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;
 }
+
index 802400d236c8ccc0f65f2e2f8ca6fed2791035c9..d7f380a9dde8bea39d7bc0fee52cce096cf14d78 100644 (file)
@@ -76,8 +76,105 @@ test_gstring ()
        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}
 };