(root)/
gettext-0.22.4/
libtextstyle/
lib/
glib/
gstring.c
       1  /* GLIB - Library of useful routines for C programming
       2   * Copyright (C) 2006-2019 Free Software Foundation, Inc.
       3   *
       4   * This file is not part of the GNU gettext program, but is used with
       5   * GNU gettext.
       6   *
       7   * The original copyright notice is as follows:
       8   */
       9  
      10  /* GLIB - Library of useful routines for C programming
      11   * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
      12   *
      13   * This library is free software; you can redistribute it and/or
      14   * modify it under the terms of the GNU Lesser General Public
      15   * License as published by the Free Software Foundation; either
      16   * version 2 of the License, or (at your option) any later version.
      17   *
      18   * This library is distributed in the hope that it will be useful,
      19   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      20   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      21   * Lesser General Public License for more details.
      22   *
      23   * You should have received a copy of the GNU Lesser General Public
      24   * License along with this library; if not, write to the
      25   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      26   * Boston, MA 02111-1307, USA.
      27   */
      28  
      29  /*
      30   * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
      31   * file for a list of people on the GLib Team.  See the ChangeLog
      32   * files for a list of changes.  These files are distributed with
      33   * GLib at ftp://ftp.gtk.org/pub/gtk/. 
      34   */
      35  
      36  /*
      37   * Modified by Bruno Haible for use as a gnulib module.
      38   */
      39  
      40  /* 
      41   * MT safe
      42   */
      43  
      44  #include "config.h"
      45  
      46  #ifdef HAVE_UNISTD_H
      47  #include <unistd.h>
      48  #endif
      49  #include <stdarg.h>
      50  #include <stdlib.h>
      51  #include <stdio.h>
      52  #include <string.h>
      53  #include <ctype.h>
      54  
      55  #include "glib.h"
      56  #if 0
      57  #include "gprintf.h"
      58  
      59  #include "galias.h"
      60  
      61  struct _GStringChunk
      62  {
      63    GHashTable *const_table;
      64    GSList     *storage_list;
      65    gsize       storage_next;    
      66    gsize       this_size;       
      67    gsize       default_size;    
      68  };
      69  #endif
      70  
      71  /* Hash Functions.
      72   */
      73  
      74  /**
      75   * g_str_equal:
      76   * @v1: a key. 
      77   * @v2: a key to compare with @v1.
      78   * 
      79   * Compares two strings and returns %TRUE if they are equal.
      80   * It can be passed to g_hash_table_new() as the @key_equal_func
      81   * parameter, when using strings as keys in a #GHashTable.
      82   *
      83   * Returns: %TRUE if the two keys match.
      84   */
      85  gboolean
      86  g_str_equal (gconstpointer v1,
      87  	     gconstpointer v2)
      88  {
      89    const gchar *string1 = v1;
      90    const gchar *string2 = v2;
      91    
      92    return strcmp (string1, string2) == 0;
      93  }
      94  
      95  /**
      96   * g_str_hash:
      97   * @v: a string key.
      98   *
      99   * Converts a string to a hash value.
     100   * It can be passed to g_hash_table_new() as the @hash_func parameter, 
     101   * when using strings as keys in a #GHashTable.
     102   *
     103   * Returns: a hash value corresponding to the key.
     104   */
     105  guint
     106  g_str_hash (gconstpointer v)
     107  {
     108    /* 31 bit hash function */
     109    const signed char *p = v;
     110    guint32 h = *p;
     111  
     112    if (h)
     113      for (p += 1; *p != '\0'; p++)
     114        h = (h << 5) - h + *p;
     115  
     116    return h;
     117  }
     118  
     119  #define MY_MAXSIZE ((gsize)-1)
     120  
     121  static inline gsize
     122  nearest_power (gsize base, gsize num)    
     123  {
     124    if (num > MY_MAXSIZE / 2)
     125      {
     126        return MY_MAXSIZE;
     127      }
     128    else
     129      {
     130        gsize n = base;
     131  
     132        while (n < num)
     133  	n <<= 1;
     134        
     135        return n;
     136      }
     137  }
     138  
     139  #if 0
     140  
     141  /* String Chunks.
     142   */
     143  
     144  GStringChunk*
     145  g_string_chunk_new (gsize default_size)    
     146  {
     147    GStringChunk *new_chunk = g_new (GStringChunk, 1);
     148    gsize size = 1;    
     149  
     150    size = nearest_power (1, default_size);
     151  
     152    new_chunk->const_table       = NULL;
     153    new_chunk->storage_list      = NULL;
     154    new_chunk->storage_next      = size;
     155    new_chunk->default_size      = size;
     156    new_chunk->this_size         = size;
     157  
     158    return new_chunk;
     159  }
     160  
     161  void
     162  g_string_chunk_free (GStringChunk *chunk)
     163  {
     164    GSList *tmp_list;
     165  
     166    g_return_if_fail (chunk != NULL);
     167  
     168    if (chunk->storage_list)
     169      {
     170        for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next)
     171  	g_free (tmp_list->data);
     172  
     173        g_slist_free (chunk->storage_list);
     174      }
     175  
     176    if (chunk->const_table)
     177      g_hash_table_destroy (chunk->const_table);
     178  
     179    g_free (chunk);
     180  }
     181  
     182  gchar*
     183  g_string_chunk_insert (GStringChunk *chunk,
     184  		       const gchar  *string)
     185  {
     186    g_return_val_if_fail (chunk != NULL, NULL);
     187  
     188    return g_string_chunk_insert_len (chunk, string, -1);
     189  }
     190  
     191  gchar*
     192  g_string_chunk_insert_const (GStringChunk *chunk,
     193  			     const gchar  *string)
     194  {
     195    char* lookup;
     196  
     197    g_return_val_if_fail (chunk != NULL, NULL);
     198  
     199    if (!chunk->const_table)
     200      chunk->const_table = g_hash_table_new (g_str_hash, g_str_equal);
     201  
     202    lookup = (char*) g_hash_table_lookup (chunk->const_table, (gchar *)string);
     203  
     204    if (!lookup)
     205      {
     206        lookup = g_string_chunk_insert (chunk, string);
     207        g_hash_table_insert (chunk->const_table, lookup, lookup);
     208      }
     209  
     210    return lookup;
     211  }
     212  
     213  /**
     214   * g_string_chunk_insert_len:
     215   * @chunk: a #GStringChunk
     216   * @string: bytes to insert
     217   * @len: number of bytes of @string to insert, or -1 to insert a 
     218   *     nul-terminated string. 
     219   * 
     220   * Adds a copy of the first @len bytes of @string to the #GStringChunk. The
     221   * copy is nul-terminated.
     222   * 
     223   * The characters in the string can be changed, if necessary, though you
     224   * should not change anything after the end of the string.
     225   * 
     226   * Return value: a pointer to the copy of @string within the #GStringChunk
     227   * 
     228   * Since: 2.4
     229   **/
     230  gchar*
     231  g_string_chunk_insert_len (GStringChunk *chunk,
     232  			   const gchar  *string, 
     233  			   gssize        len)
     234  {
     235    gssize size;
     236    gchar* pos;
     237  
     238    g_return_val_if_fail (chunk != NULL, NULL);
     239  
     240    if (len < 0)
     241      size = strlen (string);
     242    else
     243      size = len;
     244    
     245    if ((chunk->storage_next + size + 1) > chunk->this_size)
     246      {
     247        gsize new_size = nearest_power (chunk->default_size, size + 1);
     248  
     249        chunk->storage_list = g_slist_prepend (chunk->storage_list,
     250  					     g_new (gchar, new_size));
     251  
     252        chunk->this_size = new_size;
     253        chunk->storage_next = 0;
     254      }
     255  
     256    pos = ((gchar *) chunk->storage_list->data) + chunk->storage_next;
     257  
     258    *(pos + size) = '\0';
     259  
     260    strncpy (pos, string, size);
     261    if (len > 0)
     262      size = strlen (pos);
     263  
     264    chunk->storage_next += size + 1;
     265  
     266    return pos;
     267  }
     268  
     269  #endif
     270  
     271  /* Strings.
     272   */
     273  static void
     274  g_string_maybe_expand (GString* string,
     275  		       gsize    len) 
     276  {
     277    if (string->len + len >= string->allocated_len)
     278      {
     279        string->allocated_len = nearest_power (1, string->len + len + 1);
     280        string->str = g_realloc (string->str, string->allocated_len);
     281      }
     282  }
     283  
     284  GString*
     285  g_string_sized_new (gsize dfl_size)    
     286  {
     287    GString *string = g_slice_new (GString);
     288  
     289    string->allocated_len = 0;
     290    string->len   = 0;
     291    string->str   = NULL;
     292  
     293    g_string_maybe_expand (string, MAX (dfl_size, 2));
     294    string->str[0] = 0;
     295  
     296    return string;
     297  }
     298  
     299  GString*
     300  g_string_new (const gchar *init)
     301  {
     302    GString *string;
     303  
     304    if (init == NULL || *init == '\0')
     305      string = g_string_sized_new (2);
     306    else 
     307      {
     308        gint len;
     309  
     310        len = strlen (init);
     311        string = g_string_sized_new (len + 2);
     312  
     313        g_string_append_len (string, init, len);
     314      }
     315  
     316    return string;
     317  }
     318  
     319  GString*
     320  g_string_new_len (const gchar *init,
     321                    gssize       len)    
     322  {
     323    GString *string;
     324  
     325    if (len < 0)
     326      return g_string_new (init);
     327    else
     328      {
     329        string = g_string_sized_new (len);
     330        
     331        if (init)
     332          g_string_append_len (string, init, len);
     333        
     334        return string;
     335      }
     336  }
     337  
     338  gchar*
     339  g_string_free (GString *string,
     340  	       gboolean free_segment)
     341  {
     342    gchar *segment;
     343  
     344    g_return_val_if_fail (string != NULL, NULL);
     345  
     346    if (free_segment)
     347      {
     348        g_free (string->str);
     349        segment = NULL;
     350      }
     351    else
     352      segment = string->str;
     353  
     354    g_slice_free (GString, string);
     355  
     356    return segment;
     357  }
     358  
     359  #if 0
     360  
     361  gboolean
     362  g_string_equal (const GString *v,
     363                  const GString *v2)
     364  {
     365    gchar *p, *q;
     366    GString *string1 = (GString *) v;
     367    GString *string2 = (GString *) v2;
     368    gsize i = string1->len;    
     369  
     370    if (i != string2->len)
     371      return FALSE;
     372  
     373    p = string1->str;
     374    q = string2->str;
     375    while (i)
     376      {
     377        if (*p != *q)
     378  	return FALSE;
     379        p++;
     380        q++;
     381        i--;
     382      }
     383    return TRUE;
     384  }
     385  
     386  /* 31 bit hash function */
     387  guint
     388  g_string_hash (const GString *str)
     389  {
     390    const gchar *p = str->str;
     391    gsize n = str->len;    
     392    guint h = 0;
     393  
     394    while (n--)
     395      {
     396        h = (h << 5) - h + *p;
     397        p++;
     398      }
     399  
     400    return h;
     401  }
     402  
     403  GString*
     404  g_string_assign (GString     *string,
     405  		 const gchar *rval)
     406  {
     407    g_return_val_if_fail (string != NULL, NULL);
     408    g_return_val_if_fail (rval != NULL, string);
     409  
     410    /* Make sure assigning to itself doesn't corrupt the string.  */
     411    if (string->str != rval)
     412      {
     413        /* Assigning from substring should be ok since g_string_truncate
     414  	 does not realloc.  */
     415        g_string_truncate (string, 0);
     416        g_string_append (string, rval);
     417      }
     418  
     419    return string;
     420  }
     421  
     422  GString*
     423  g_string_truncate (GString *string,
     424  		   gsize    len)    
     425  {
     426    g_return_val_if_fail (string != NULL, NULL);
     427  
     428    string->len = MIN (len, string->len);
     429    string->str[string->len] = 0;
     430  
     431    return string;
     432  }
     433  
     434  /**
     435   * g_string_set_size:
     436   * @string: a #GString
     437   * @len: the new length
     438   * 
     439   * Sets the length of a #GString. If the length is less than
     440   * the current length, the string will be truncated. If the
     441   * length is greater than the current length, the contents
     442   * of the newly added area are undefined. (However, as
     443   * always, string->str[string->len] will be a nul byte.) 
     444   * 
     445   * Return value: @string
     446   **/
     447  GString*
     448  g_string_set_size (GString *string,
     449  		   gsize    len)    
     450  {
     451    g_return_val_if_fail (string != NULL, NULL);
     452  
     453    if (len >= string->allocated_len)
     454      g_string_maybe_expand (string, len - string->len);
     455    
     456    string->len = len;
     457    string->str[len] = 0;
     458  
     459    return string;
     460  }
     461  
     462  #endif
     463  
     464  GString*
     465  g_string_insert_len (GString     *string,
     466  		     gssize       pos,    
     467  		     const gchar *val,
     468  		     gssize       len)    
     469  {
     470    g_return_val_if_fail (string != NULL, NULL);
     471    g_return_val_if_fail (val != NULL, string);
     472  
     473    if (len < 0)
     474      len = strlen (val);
     475  
     476    if (pos < 0)
     477      pos = string->len;
     478    else
     479      g_return_val_if_fail (pos <= string->len, string);
     480  
     481    /* Check whether val represents a substring of string.  This test
     482       probably violates chapter and verse of the C standards, since
     483       ">=" and "<=" are only valid when val really is a substring.
     484       In practice, it will work on modern archs.  */
     485    if (val >= string->str && val <= string->str + string->len)
     486      {
     487        gsize offset = val - string->str;
     488        gsize precount = 0;
     489  
     490        g_string_maybe_expand (string, len);
     491        val = string->str + offset;
     492        /* At this point, val is valid again.  */
     493  
     494        /* Open up space where we are going to insert.  */
     495        if (pos < string->len)
     496  	g_memmove (string->str + pos + len, string->str + pos, string->len - pos);
     497  
     498        /* Move the source part before the gap, if any.  */
     499        if (offset < pos)
     500  	{
     501  	  precount = MIN (len, pos - offset);
     502  	  memcpy (string->str + pos, val, precount);
     503  	}
     504  
     505        /* Move the source part after the gap, if any.  */
     506        if (len > precount)
     507  	memcpy (string->str + pos + precount,
     508  		val + /* Already moved: */ precount + /* Space opened up: */ len,
     509  		len - precount);
     510      }
     511    else
     512      {
     513        g_string_maybe_expand (string, len);
     514  
     515        /* If we aren't appending at the end, move a hunk
     516         * of the old string to the end, opening up space
     517         */
     518        if (pos < string->len)
     519  	g_memmove (string->str + pos + len, string->str + pos, string->len - pos);
     520  
     521        /* insert the new string */
     522        if (len == 1)
     523          string->str[pos] = *val;
     524        else
     525          memcpy (string->str + pos, val, len);
     526      }
     527  
     528    string->len += len;
     529  
     530    string->str[string->len] = 0;
     531  
     532    return string;
     533  }
     534  
     535  GString*
     536  g_string_append (GString     *string,
     537  		 const gchar *val)
     538  {  
     539    g_return_val_if_fail (string != NULL, NULL);
     540    g_return_val_if_fail (val != NULL, string);
     541  
     542    return g_string_insert_len (string, -1, val, -1);
     543  }
     544  
     545  GString*
     546  g_string_append_len (GString	 *string,
     547                       const gchar *val,
     548                       gssize       len)    
     549  {
     550    g_return_val_if_fail (string != NULL, NULL);
     551    g_return_val_if_fail (val != NULL, string);
     552  
     553    return g_string_insert_len (string, -1, val, len);
     554  }
     555  
     556  #if !defined IN_LIBTEXTSTYLE
     557  #undef g_string_append_c
     558  #endif
     559  GString*
     560  g_string_append_c (GString *string,
     561  		   gchar    c)
     562  {
     563    g_return_val_if_fail (string != NULL, NULL);
     564  
     565    return g_string_insert_c (string, -1, c);
     566  }
     567  
     568  /**
     569   * g_string_append_unichar:
     570   * @string: a #GString
     571   * @wc: a Unicode character
     572   * 
     573   * Converts a Unicode character into UTF-8, and appends it
     574   * to the string.
     575   * 
     576   * Return value: @string
     577   **/
     578  GString*
     579  g_string_append_unichar (GString  *string,
     580  			 gunichar  wc)
     581  {  
     582    g_return_val_if_fail (string != NULL, NULL);
     583    
     584    return g_string_insert_unichar (string, -1, wc);
     585  }
     586  
     587  #if 0
     588  
     589  GString*
     590  g_string_prepend (GString     *string,
     591  		  const gchar *val)
     592  {
     593    g_return_val_if_fail (string != NULL, NULL);
     594    g_return_val_if_fail (val != NULL, string);
     595    
     596    return g_string_insert_len (string, 0, val, -1);
     597  }
     598  
     599  GString*
     600  g_string_prepend_len (GString	  *string,
     601                        const gchar *val,
     602                        gssize       len)    
     603  {
     604    g_return_val_if_fail (string != NULL, NULL);
     605    g_return_val_if_fail (val != NULL, string);
     606  
     607    return g_string_insert_len (string, 0, val, len);
     608  }
     609  
     610  GString*
     611  g_string_prepend_c (GString *string,
     612  		    gchar    c)
     613  {  
     614    g_return_val_if_fail (string != NULL, NULL);
     615    
     616    return g_string_insert_c (string, 0, c);
     617  }
     618  
     619  /**
     620   * g_string_prepend_unichar:
     621   * @string: a #GString.
     622   * @wc: a Unicode character.
     623   * 
     624   * Converts a Unicode character into UTF-8, and prepends it
     625   * to the string.
     626   * 
     627   * Return value: @string.
     628   **/
     629  GString*
     630  g_string_prepend_unichar (GString  *string,
     631  			  gunichar  wc)
     632  {  
     633    g_return_val_if_fail (string != NULL, NULL);
     634    
     635    return g_string_insert_unichar (string, 0, wc);
     636  }
     637  
     638  GString*
     639  g_string_insert (GString     *string,
     640  		 gssize       pos,    
     641  		 const gchar *val)
     642  {
     643    g_return_val_if_fail (string != NULL, NULL);
     644    g_return_val_if_fail (val != NULL, string);
     645    if (pos >= 0)
     646      g_return_val_if_fail (pos <= string->len, string);
     647    
     648    return g_string_insert_len (string, pos, val, -1);
     649  }
     650  
     651  #endif
     652  
     653  GString*
     654  g_string_insert_c (GString *string,
     655  		   gssize   pos,    
     656  		   gchar    c)
     657  {
     658    g_return_val_if_fail (string != NULL, NULL);
     659  
     660    g_string_maybe_expand (string, 1);
     661  
     662    if (pos < 0)
     663      pos = string->len;
     664    else
     665      g_return_val_if_fail (pos <= string->len, string);
     666    
     667    /* If not just an append, move the old stuff */
     668    if (pos < string->len)
     669      g_memmove (string->str + pos + 1, string->str + pos, string->len - pos);
     670  
     671    string->str[pos] = c;
     672  
     673    string->len += 1;
     674  
     675    string->str[string->len] = 0;
     676  
     677    return string;
     678  }
     679  
     680  /**
     681   * g_string_insert_unichar:
     682   * @string: a #GString
     683   * @pos: the position at which to insert character, or -1 to
     684   *       append at the end of the string.
     685   * @wc: a Unicode character
     686   * 
     687   * Converts a Unicode character into UTF-8, and insert it
     688   * into the string at the given position.
     689   * 
     690   * Return value: @string
     691   **/
     692  GString*
     693  g_string_insert_unichar (GString *string,
     694  			 gssize   pos,    
     695  			 gunichar wc)
     696  {
     697    gint charlen, first, i;
     698    gchar *dest;
     699  
     700    g_return_val_if_fail (string != NULL, NULL);
     701  
     702    /* Code copied from g_unichar_to_utf() */
     703    if (wc < 0x80)
     704      {
     705        first = 0;
     706        charlen = 1;
     707      }
     708    else if (wc < 0x800)
     709      {
     710        first = 0xc0;
     711        charlen = 2;
     712      }
     713    else if (wc < 0x10000)
     714      {
     715        first = 0xe0;
     716        charlen = 3;
     717      }
     718     else if (wc < 0x200000)
     719      {
     720        first = 0xf0;
     721        charlen = 4;
     722      }
     723    else if (wc < 0x4000000)
     724      {
     725        first = 0xf8;
     726        charlen = 5;
     727      }
     728    else
     729      {
     730        first = 0xfc;
     731        charlen = 6;
     732      }
     733    /* End of copied code */
     734  
     735    g_string_maybe_expand (string, charlen);
     736  
     737    if (pos < 0)
     738      pos = string->len;
     739    else
     740      g_return_val_if_fail (pos <= string->len, string);
     741  
     742    /* If not just an append, move the old stuff */
     743    if (pos < string->len)
     744      g_memmove (string->str + pos + charlen, string->str + pos, string->len - pos);
     745  
     746    dest = string->str + pos;
     747    /* Code copied from g_unichar_to_utf() */
     748    for (i = charlen - 1; i > 0; --i)
     749      {
     750        dest[i] = (wc & 0x3f) | 0x80;
     751        wc >>= 6;
     752      }
     753    dest[0] = wc | first;
     754    /* End of copied code */
     755    
     756    string->len += charlen;
     757  
     758    string->str[string->len] = 0;
     759  
     760    return string;
     761  }
     762  
     763  #if 0
     764  
     765  GString*
     766  g_string_erase (GString *string,
     767  		gssize   pos,
     768  		gssize   len)
     769  {
     770    g_return_val_if_fail (string != NULL, NULL);
     771    g_return_val_if_fail (pos >= 0, string);
     772    g_return_val_if_fail (pos <= string->len, string);
     773  
     774    if (len < 0)
     775      len = string->len - pos;
     776    else
     777      {
     778        g_return_val_if_fail (pos + len <= string->len, string);
     779  
     780        if (pos + len < string->len)
     781  	g_memmove (string->str + pos, string->str + pos + len, string->len - (pos + len));
     782      }
     783  
     784    string->len -= len;
     785    
     786    string->str[string->len] = 0;
     787  
     788    return string;
     789  }
     790  
     791  /**
     792   * g_string_ascii_down:
     793   * @string: a GString
     794   * 
     795   * Converts all upper case ASCII letters to lower case ASCII letters.
     796   * 
     797   * Return value: passed-in @string pointer, with all the upper case
     798   *               characters converted to lower case in place, with
     799   *               semantics that exactly match g_ascii_tolower.
     800   **/
     801  GString*
     802  g_string_ascii_down (GString *string)
     803  {
     804    gchar *s;
     805    gint n;
     806  
     807    g_return_val_if_fail (string != NULL, NULL);
     808  
     809    n = string->len;
     810    s = string->str;
     811  
     812    while (n)
     813      {
     814        *s = g_ascii_tolower (*s);
     815        s++;
     816        n--;
     817      }
     818  
     819    return string;
     820  }
     821  
     822  /**
     823   * g_string_ascii_up:
     824   * @string: a GString
     825   * 
     826   * Converts all lower case ASCII letters to upper case ASCII letters.
     827   * 
     828   * Return value: passed-in @string pointer, with all the lower case
     829   *               characters converted to upper case in place, with
     830   *               semantics that exactly match g_ascii_toupper.
     831   **/
     832  GString*
     833  g_string_ascii_up (GString *string)
     834  {
     835    gchar *s;
     836    gint n;
     837  
     838    g_return_val_if_fail (string != NULL, NULL);
     839  
     840    n = string->len;
     841    s = string->str;
     842  
     843    while (n)
     844      {
     845        *s = g_ascii_toupper (*s);
     846        s++;
     847        n--;
     848      }
     849  
     850    return string;
     851  }
     852  
     853  /**
     854   * g_string_down:
     855   * @string: a #GString
     856   *  
     857   * Converts a #GString to lowercase.
     858   *
     859   * Returns: the #GString.
     860   *
     861   * Deprecated:2.2: This function uses the locale-specific tolower() function, 
     862   * which is almost never the right thing. Use g_string_ascii_down() or 
     863   * g_utf8_strdown() instead.
     864   */
     865  GString*
     866  g_string_down (GString *string)
     867  {
     868    guchar *s;
     869    glong n;
     870  
     871    g_return_val_if_fail (string != NULL, NULL);
     872  
     873    n = string->len;    
     874    s = (guchar *) string->str;
     875  
     876    while (n)
     877      {
     878        if (isupper (*s))
     879  	*s = tolower (*s);
     880        s++;
     881        n--;
     882      }
     883  
     884    return string;
     885  }
     886  
     887  /**
     888   * g_string_up:
     889   * @string: a #GString 
     890   * 
     891   * Converts a #GString to uppercase.
     892   * 
     893   * Return value: the #GString
     894   *
     895   * Deprecated:2.2: This function uses the locale-specific toupper() function, 
     896   * which is almost never the right thing. Use g_string_ascii_up() or 
     897   * g_utf8_strup() instead.
     898   **/
     899  GString*
     900  g_string_up (GString *string)
     901  {
     902    guchar *s;
     903    glong n;
     904  
     905    g_return_val_if_fail (string != NULL, NULL);
     906  
     907    n = string->len;
     908    s = (guchar *) string->str;
     909  
     910    while (n)
     911      {
     912        if (islower (*s))
     913  	*s = toupper (*s);
     914        s++;
     915        n--;
     916      }
     917  
     918    return string;
     919  }
     920  
     921  #endif
     922  
     923  static void
     924  g_string_append_printf_internal (GString     *string,
     925  				 const gchar *fmt,
     926  				 va_list      args)
     927  {
     928    gchar *buffer;
     929    gint length;
     930    
     931    length = g_vasprintf (&buffer, fmt, args);
     932    g_string_append_len (string, buffer, length);
     933    g_free (buffer);
     934  }
     935  
     936  #if 0
     937  
     938  void
     939  g_string_printf (GString *string,
     940  		 const gchar *fmt,
     941  		 ...)
     942  {
     943    va_list args;
     944  
     945    g_string_truncate (string, 0);
     946  
     947    va_start (args, fmt);
     948    g_string_append_printf_internal (string, fmt, args);
     949    va_end (args);
     950  }
     951  
     952  #endif
     953  
     954  void
     955  g_string_append_printf (GString *string,
     956  			const gchar *fmt,
     957  			...)
     958  {
     959    va_list args;
     960  
     961    va_start (args, fmt);
     962    g_string_append_printf_internal (string, fmt, args);
     963    va_end (args);
     964  }
     965  
     966  #if 0
     967  #define __G_STRING_C__
     968  #include "galiasdef.c"
     969  #endif