Solaris has a broken strftime that produced garbage output for the test
[platform/upstream/glib.git] / gstring.c
index 3454e8f..312a540 100644 (file)
--- a/gstring.c
+++ b/gstring.c
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
+
+/* 
+ * MT safe
+ */
+
 #include <stdarg.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -43,7 +48,7 @@ struct _GRealString
   gint   alloc;
 };
 
-
+static G_LOCK_DEFINE(string_mem_chunk);
 static GMemChunk *string_mem_chunk = NULL;
 
 /* Hash Functions.
@@ -106,14 +111,10 @@ g_string_chunk_free (GStringChunk *fchunk)
 
   if (chunk->storage_list)
     {
-      GListAllocator *tmp_allocator = g_slist_set_allocator (NULL);
-
       for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next)
        g_free (tmp_list->data);
 
       g_slist_free (chunk->storage_list);
-
-      g_slist_set_allocator (tmp_allocator);
     }
 
   if (chunk->const_table)
@@ -134,7 +135,6 @@ g_string_chunk_insert (GStringChunk *fchunk,
 
   if ((chunk->storage_next + len + 1) > chunk->this_size)
     {
-      GListAllocator *tmp_allocator = g_slist_set_allocator (NULL);
       gint new_size = chunk->default_size;
 
       while (new_size < len+1)
@@ -145,8 +145,6 @@ g_string_chunk_insert (GStringChunk *fchunk,
 
       chunk->this_size = new_size;
       chunk->storage_next = 0;
-
-      g_slist_set_allocator (tmp_allocator);
     }
 
   pos = ((char*)chunk->storage_list->data) + chunk->storage_next;
@@ -209,12 +207,14 @@ g_string_sized_new (guint dfl_size)
 {
   GRealString *string;
 
+  g_lock (string_mem_chunk);
   if (!string_mem_chunk)
     string_mem_chunk = g_mem_chunk_new ("string mem chunk",
                                        sizeof (GRealString),
                                        1024, G_ALLOC_AND_FREE);
 
   string = g_chunk_new (GRealString, string_mem_chunk);
+  g_unlock (string_mem_chunk);
 
   string->alloc = 0;
   string->len   = 0;
@@ -248,7 +248,9 @@ g_string_free (GString *string,
   if (free_segment)
     g_free (string->str);
 
+  g_lock (string_mem_chunk);
   g_mem_chunk_free (string_mem_chunk, string);
+  g_unlock (string_mem_chunk);
 }
 
 GString*
@@ -466,152 +468,16 @@ g_string_up (GString *fstring)
   return fstring;
 }
 
-static int
-get_length_upper_bound (const gchar* fmt, va_list *args)
-{
-  int len = 0;
-  int short_int;
-  int long_int;
-  int done;
-  char *tmp;
-
-  while (*fmt)
-    {
-      char c = *fmt++;
-
-      short_int = FALSE;
-      long_int = FALSE;
-
-      if (c == '%')
-       {
-         done = FALSE;
-         while (*fmt && !done)
-           {
-             switch (*fmt++)
-               {
-               case '*':
-                 len += va_arg(*args, int);
-                 break;
-               case '1':
-               case '2':
-               case '3':
-               case '4':
-               case '5':
-               case '6':
-               case '7':
-               case '8':
-               case '9':
-                 fmt -= 1;
-                 len += strtol (fmt, (char **)&fmt, 10);
-                 break;
-               case 'h':
-                 short_int = TRUE;
-                 break;
-               case 'l':
-                 long_int = TRUE;
-                 break;
-
-                 /* I ignore 'q' and 'L', they're not portable anyway. */
-
-               case 's':
-                 tmp = va_arg(*args, char *);
-                 if(tmp)
-                   len += strlen (tmp);
-                 else
-                   len += strlen ("(null)");
-                 done = TRUE;
-                 break;
-               case 'd':
-               case 'i':
-               case 'o':
-               case 'u':
-               case 'x':
-               case 'X':
-                 if (long_int)
-                   (void)va_arg (*args, long);
-                 else if (short_int)
-                   (void)va_arg (*args, int);
-                 else
-                   (void)va_arg (*args, int);
-                 len += 32;
-                 done = TRUE;
-                 break;
-               case 'D':
-               case 'O':
-               case 'U':
-                 (void)va_arg (*args, long);
-                 len += 32;
-                 done = TRUE;
-                 break;
-               case 'e':
-               case 'E':
-               case 'f':
-               case 'g':
-                 (void)va_arg (*args, double);
-                 len += 32;
-                 done = TRUE;
-                 break;
-               case 'c':
-                 (void)va_arg (*args, int);
-                 len += 1;
-                 done = TRUE;
-                 break;
-               case 'p':
-               case 'n':
-                 (void)va_arg (*args, void*);
-                 len += 32;
-                 done = TRUE;
-                 break;
-               case '%':
-                 len += 1;
-                 done = TRUE;
-                 break;
-               default:
-                 break;
-               }
-           }
-       }
-      else
-       len += 1;
-    }
-
-  return len;
-}
-
-extern gchar* g_vsprintf (const gchar *fmt, va_list *args, va_list *args2);
-gchar*
-g_vsprintf (const gchar *fmt,
-           va_list     *args,
-           va_list     *args2)
-{
-  static gchar *buf = NULL;
-  static guint  alloc = 0;
-  guint len;
-
-  len = get_length_upper_bound (fmt, args);
-
-  if (len >= alloc)
-    {
-      if (buf)
-       g_free (buf);
-
-      alloc = nearest_pow (MAX (len + 1, 1024 + 1));
-
-      buf = g_new (gchar, alloc);
-    }
-
-  vsprintf (buf, fmt, *args2);
-
-  return buf;
-}
-
 static void
-g_string_sprintfa_int (GString *string,
+g_string_sprintfa_int (GString     *string,
                       const gchar *fmt,
-                      va_list *args,
-                      va_list *args2)
+                      va_list      args)
 {
-  g_string_append (string, g_vsprintf (fmt, args, args2));
+  gchar *buffer;
+
+  buffer = g_strdup_vprintf (fmt, args);
+  g_string_append (string, buffer);
+  g_free (buffer);
 }
 
 void
@@ -619,17 +485,13 @@ g_string_sprintf (GString *string,
                  const gchar *fmt,
                  ...)
 {
-  va_list args, args2;
-
-  va_start(args, fmt);
-  va_start(args2, fmt);
+  va_list args;
 
   g_string_truncate (string, 0);
 
-  g_string_sprintfa_int (string, fmt, &args, &args2);
-
-  va_end(args);
-  va_end(args2);
+  va_start (args, fmt);
+  g_string_sprintfa_int (string, fmt, args);
+  va_end (args);
 }
 
 void
@@ -637,13 +499,9 @@ g_string_sprintfa (GString *string,
                   const gchar *fmt,
                   ...)
 {
-  va_list args, args2;
-
-  va_start(args, fmt);
-  va_start(args2, fmt);
-
-  g_string_sprintfa_int (string, fmt, &args, &args2);
+  va_list args;
 
-  va_end(args);
-  va_end(args2);
+  va_start (args, fmt);
+  g_string_sprintfa_int (string, fmt, args);
+  va_end (args);
 }