(root)/
gettext-0.22.4/
libtextstyle/
gnulib-local/
lib/
glib/
gstrfuncs.c
       1  /* GLIB - Library of useful routines for C programming
       2   * Copyright (C) 2006-2023 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  #if 0
      47  #define _GNU_SOURCE		/* For stpcpy */
      48  #endif
      49  
      50  #include <stdarg.h>
      51  #include <stdio.h>
      52  #include <stdlib.h>
      53  #include <string.h>
      54  #include <locale.h>
      55  #include <errno.h>
      56  #include <ctype.h>		/* For tolower() */
      57  #if !defined (HAVE_STRSIGNAL) || !defined(NO_SYS_SIGLIST_DECL)
      58  #include <signal.h>
      59  #endif
      60  
      61  #include "glib.h"
      62  #if 0
      63  #include "gprintf.h"
      64  #endif
      65  #include "gprintfint.h"
      66  
      67  #if 0
      68  #include "galias.h"
      69  
      70  #ifdef G_OS_WIN32
      71  #include <windows.h>
      72  #endif
      73  #endif
      74  
      75  /* do not include <unistd.h> in this place since it
      76   * interferes with g_strsignal() on some OSes
      77   */
      78  
      79  static const guint16 ascii_table_data[256] = {
      80    0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
      81    0x004, 0x104, 0x104, 0x004, 0x104, 0x104, 0x004, 0x004,
      82    0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
      83    0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
      84    0x140, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0,
      85    0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0,
      86    0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459,
      87    0x459, 0x459, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0,
      88    0x0d0, 0x653, 0x653, 0x653, 0x653, 0x653, 0x653, 0x253,
      89    0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253,
      90    0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253,
      91    0x253, 0x253, 0x253, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0,
      92    0x0d0, 0x473, 0x473, 0x473, 0x473, 0x473, 0x473, 0x073,
      93    0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073,
      94    0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073,
      95    0x073, 0x073, 0x073, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x004
      96    /* the upper 128 are all zeroes */
      97  };
      98  
      99  const guint16 * const g_ascii_table = ascii_table_data;
     100  
     101  gchar*
     102  g_strdup (const gchar *str)
     103  {
     104    gchar *new_str;
     105    gsize length;
     106  
     107    if (str)
     108      {
     109        length = strlen (str) + 1;
     110        new_str = g_new (char, length);
     111        memcpy (new_str, str, length);
     112      }
     113    else
     114      new_str = NULL;
     115  
     116    return new_str;
     117  }
     118  
     119  #if 0
     120  
     121  gpointer
     122  g_memdup (gconstpointer mem,
     123  	  guint         byte_size)
     124  {
     125    gpointer new_mem;
     126  
     127    if (mem)
     128      {
     129        new_mem = g_malloc (byte_size);
     130        memcpy (new_mem, mem, byte_size);
     131      }
     132    else
     133      new_mem = NULL;
     134  
     135    return new_mem;
     136  }
     137  
     138  #endif
     139  
     140  gchar*
     141  g_strndup (const gchar *str,
     142  	   gsize        n)    
     143  {
     144    gchar *new_str;
     145  
     146    if (str)
     147      {
     148        new_str = g_new (gchar, n + 1);
     149        strncpy (new_str, str, n);
     150        new_str[n] = '\0';
     151      }
     152    else
     153      new_str = NULL;
     154  
     155    return new_str;
     156  }
     157  
     158  #if 0
     159  
     160  gchar*
     161  g_strnfill (gsize length,     
     162  	    gchar fill_char)
     163  {
     164    gchar *str;
     165  
     166    str = g_new (gchar, length + 1);
     167    memset (str, (guchar)fill_char, length);
     168    str[length] = '\0';
     169  
     170    return str;
     171  }
     172  
     173  #endif
     174  
     175  /**
     176   * g_stpcpy:
     177   * @dest: destination buffer.
     178   * @src: source string.
     179   * 
     180   * Copies a nul-terminated string into the dest buffer, include the
     181   * trailing nul, and return a pointer to the trailing nul byte.
     182   * This is useful for concatenating multiple strings together
     183   * without having to repeatedly scan for the end.
     184   * 
     185   * Return value: a pointer to trailing nul byte.
     186   **/
     187  gchar *
     188  g_stpcpy (gchar       *dest,
     189            const gchar *src)
     190  {
     191  #ifdef HAVE_STPCPY
     192    g_return_val_if_fail (dest != NULL, NULL);
     193    g_return_val_if_fail (src != NULL, NULL);
     194    return stpcpy (dest, src);
     195  #else
     196    register gchar *d = dest;
     197    register const gchar *s = src;
     198  
     199    g_return_val_if_fail (dest != NULL, NULL);
     200    g_return_val_if_fail (src != NULL, NULL);
     201    do
     202      *d++ = *s;
     203    while (*s++ != '\0');
     204  
     205    return d - 1;
     206  #endif
     207  }
     208  
     209  gchar*
     210  g_strdup_vprintf (const gchar *format,
     211  		  va_list      args)
     212  {
     213    gchar *string = NULL;
     214  
     215    g_vasprintf (&string, format, args);
     216  
     217    return string;
     218  }
     219  
     220  gchar*
     221  g_strdup_printf (const gchar *format,
     222  		 ...)
     223  {
     224    gchar *buffer;
     225    va_list args;
     226  
     227    va_start (args, format);
     228    buffer = g_strdup_vprintf (format, args);
     229    va_end (args);
     230  
     231    return buffer;
     232  }
     233  
     234  gchar*
     235  g_strconcat (const gchar *string1, ...)
     236  {
     237    gsize	  l;     
     238    va_list args;
     239    gchar	  *s;
     240    gchar	  *concat;
     241    gchar   *ptr;
     242  
     243    if (!string1)
     244      return NULL;
     245  
     246    l = 1 + strlen (string1);
     247    va_start (args, string1);
     248    s = va_arg (args, gchar*);
     249    while (s)
     250      {
     251        l += strlen (s);
     252        s = va_arg (args, gchar*);
     253      }
     254    va_end (args);
     255  
     256    concat = g_new (gchar, l);
     257    ptr = concat;
     258  
     259    ptr = g_stpcpy (ptr, string1);
     260    va_start (args, string1);
     261    s = va_arg (args, gchar*);
     262    while (s)
     263      {
     264        ptr = g_stpcpy (ptr, s);
     265        s = va_arg (args, gchar*);
     266      }
     267    va_end (args);
     268  
     269    return concat;
     270  }
     271  
     272  #if 0
     273  
     274  /**
     275   * g_strtod:
     276   * @nptr:    the string to convert to a numeric value.
     277   * @endptr:  if non-%NULL, it returns the character after
     278   *           the last character used in the conversion.
     279   * 
     280   * Converts a string to a #gdouble value.
     281   * It calls the standard strtod() function to handle the conversion, but
     282   * if the string is not completely converted it attempts the conversion
     283   * again with g_ascii_strtod(), and returns the best match.
     284   *
     285   * This function should seldomly be used. The normal situation when reading
     286   * numbers not for human consumption is to use g_ascii_strtod(). Only when
     287   * you know that you must expect both locale formatted and C formatted numbers
     288   * should you use this. Make sure that you don't pass strings such as comma
     289   * separated lists of values, since the commas may be interpreted as a decimal
     290   * point in some locales, causing unexpected results.
     291   * 
     292   * Return value: the #gdouble value.
     293   **/
     294  gdouble
     295  g_strtod (const gchar *nptr,
     296  	  gchar      **endptr)
     297  {
     298    gchar *fail_pos_1;
     299    gchar *fail_pos_2;
     300    gdouble val_1;
     301    gdouble val_2 = 0;
     302  
     303    g_return_val_if_fail (nptr != NULL, 0);
     304  
     305    fail_pos_1 = NULL;
     306    fail_pos_2 = NULL;
     307  
     308    val_1 = strtod (nptr, &fail_pos_1);
     309  
     310    if (fail_pos_1 && fail_pos_1[0] != 0)
     311      val_2 = g_ascii_strtod (nptr, &fail_pos_2);
     312  
     313    if (!fail_pos_1 || fail_pos_1[0] == 0 || fail_pos_1 >= fail_pos_2)
     314      {
     315        if (endptr)
     316  	*endptr = fail_pos_1;
     317        return val_1;
     318      }
     319    else
     320      {
     321        if (endptr)
     322  	*endptr = fail_pos_2;
     323        return val_2;
     324      }
     325  }
     326  
     327  /**
     328   * g_ascii_strtod:
     329   * @nptr:    the string to convert to a numeric value.
     330   * @endptr:  if non-%NULL, it returns the character after
     331   *           the last character used in the conversion.
     332   * 
     333   * Converts a string to a #gdouble value.
     334   * This function behaves like the standard strtod() function
     335   * does in the C locale. It does this without actually
     336   * changing the current locale, since that would not be
     337   * thread-safe.
     338   *
     339   * This function is typically used when reading configuration
     340   * files or other non-user input that should be locale independent.
     341   * To handle input from the user you should normally use the
     342   * locale-sensitive system strtod() function.
     343   *
     344   * To convert from a #gdouble to a string in a locale-insensitive
     345   * way, use g_ascii_dtostr().
     346   *
     347   * If the correct value would cause overflow, plus or minus %HUGE_VAL
     348   * is returned (according to the sign of the value), and %ERANGE is
     349   * stored in %errno. If the correct value would cause underflow,
     350   * zero is returned and %ERANGE is stored in %errno.
     351   * 
     352   * This function resets %errno before calling strtod() so that
     353   * you can reliably detect overflow and underflow.
     354   *
     355   * Return value: the #gdouble value.
     356   **/
     357  gdouble
     358  g_ascii_strtod (const gchar *nptr,
     359  		gchar      **endptr)
     360  {
     361    gchar *fail_pos;
     362    gdouble val;
     363    struct lconv *locale_data;
     364    const char *decimal_point;
     365    int decimal_point_len;
     366    const char *p, *decimal_point_pos;
     367    const char *end = NULL; /* Silence gcc */
     368    int strtod_errno;
     369  
     370    g_return_val_if_fail (nptr != NULL, 0);
     371  
     372    fail_pos = NULL;
     373  
     374    locale_data = localeconv ();
     375  #if HAVE_STRUCT_LCONV_DECIMAL_POINT
     376    decimal_point = locale_data->decimal_point;
     377  #else
     378    decimal_point = ".";
     379  #endif
     380    decimal_point_len = strlen (decimal_point);
     381  
     382    g_assert (decimal_point_len != 0);
     383    
     384    decimal_point_pos = NULL;
     385    end = NULL;
     386  
     387    if (decimal_point[0] != '.' || 
     388        decimal_point[1] != 0)
     389      {
     390        p = nptr;
     391        /* Skip leading space */
     392        while (g_ascii_isspace (*p))
     393  	p++;
     394        
     395        /* Skip leading optional sign */
     396        if (*p == '+' || *p == '-')
     397  	p++;
     398        
     399        if (p[0] == '0' && 
     400  	  (p[1] == 'x' || p[1] == 'X'))
     401  	{
     402  	  p += 2;
     403  	  /* HEX - find the (optional) decimal point */
     404  	  
     405  	  while (g_ascii_isxdigit (*p))
     406  	    p++;
     407  	  
     408  	  if (*p == '.')
     409  	    decimal_point_pos = p++;
     410  	      
     411  	  while (g_ascii_isxdigit (*p))
     412  	    p++;
     413  	  
     414  	  if (*p == 'p' || *p == 'P')
     415  	    p++;
     416  	  if (*p == '+' || *p == '-')
     417  	    p++;
     418  	  while (g_ascii_isdigit (*p))
     419  	    p++;
     420  
     421  	  end = p;
     422  	}
     423        else if (g_ascii_isdigit (*p) || *p == '.')
     424  	{
     425  	  while (g_ascii_isdigit (*p))
     426  	    p++;
     427  	  
     428  	  if (*p == '.')
     429  	    decimal_point_pos = p++;
     430  	  
     431  	  while (g_ascii_isdigit (*p))
     432  	    p++;
     433  	  
     434  	  if (*p == 'e' || *p == 'E')
     435  	    p++;
     436  	  if (*p == '+' || *p == '-')
     437  	    p++;
     438  	  while (g_ascii_isdigit (*p))
     439  	    p++;
     440  
     441  	  end = p;
     442  	}
     443        /* For the other cases, we need not convert the decimal point */
     444      }
     445  
     446    if (decimal_point_pos)
     447      {
     448        char *copy, *c;
     449  
     450        /* We need to convert the '.' to the locale specific decimal point */
     451        copy = g_malloc (end - nptr + 1 + decimal_point_len);
     452        
     453        c = copy;
     454        memcpy (c, nptr, decimal_point_pos - nptr);
     455        c += decimal_point_pos - nptr;
     456        memcpy (c, decimal_point, decimal_point_len);
     457        c += decimal_point_len;
     458        memcpy (c, decimal_point_pos + 1, end - (decimal_point_pos + 1));
     459        c += end - (decimal_point_pos + 1);
     460        *c = 0;
     461  
     462        errno = 0;
     463        val = strtod (copy, &fail_pos);
     464        strtod_errno = errno;
     465  
     466        if (fail_pos)
     467  	{
     468  	  if (fail_pos - copy > decimal_point_pos - nptr)
     469  	    fail_pos = (char *)nptr + (fail_pos - copy) - (decimal_point_len - 1);
     470  	  else
     471  	    fail_pos = (char *)nptr + (fail_pos - copy);
     472  	}
     473        
     474        g_free (copy);
     475  	  
     476      }
     477    else if (end)
     478      {
     479        char *copy;
     480        
     481        copy = g_malloc (end - (char *)nptr + 1);
     482        memcpy (copy, nptr, end - nptr);
     483        *(copy + (end - (char *)nptr)) = 0;
     484        
     485        errno = 0;
     486        val = strtod (copy, &fail_pos);
     487        strtod_errno = errno;
     488  
     489        if (fail_pos)
     490  	{
     491  	  fail_pos = (char *)nptr + (fail_pos - copy);
     492  	}
     493        
     494        g_free (copy);
     495      }
     496    else
     497      {
     498        errno = 0;
     499        val = strtod (nptr, &fail_pos);
     500        strtod_errno = errno;
     501      }
     502  
     503    if (endptr)
     504      *endptr = fail_pos;
     505  
     506    errno = strtod_errno;
     507  
     508    return val;
     509  }
     510  
     511  #endif
     512  
     513  /**
     514   * g_ascii_dtostr:
     515   * @buffer: A buffer to place the resulting string in
     516   * @buf_len: The length of the buffer.
     517   * @d: The #gdouble to convert
     518   *
     519   * Converts a #gdouble to a string, using the '.' as
     520   * decimal point. 
     521   * 
     522   * This functions generates enough precision that converting
     523   * the string back using g_ascii_strtod() gives the same machine-number
     524   * (on machines with IEEE compatible 64bit doubles). It is
     525   * guaranteed that the size of the resulting string will never
     526   * be larger than @G_ASCII_DTOSTR_BUF_SIZE bytes.
     527   *
     528   * Return value: The pointer to the buffer with the converted string.
     529   **/
     530  gchar *
     531  g_ascii_dtostr (gchar       *buffer,
     532  		gint         buf_len,
     533  		gdouble      d)
     534  {
     535    return g_ascii_formatd (buffer, buf_len, "%.17g", d);
     536  }
     537  
     538  /**
     539   * g_ascii_formatd:
     540   * @buffer: A buffer to place the resulting string in
     541   * @buf_len: The length of the buffer.
     542   * @format: The printf()-style format to use for the
     543   *          code to use for converting. 
     544   * @d: The #gdouble to convert
     545   *
     546   * Converts a #gdouble to a string, using the '.' as
     547   * decimal point. To format the number you pass in
     548   * a printf()-style format string. Allowed conversion
     549   * specifiers are 'e', 'E', 'f', 'F', 'g' and 'G'. 
     550   * 
     551   * If you just want to want to serialize the value into a
     552   * string, use g_ascii_dtostr().
     553   *
     554   * Return value: The pointer to the buffer with the converted string.
     555   **/
     556  gchar *
     557  g_ascii_formatd (gchar       *buffer,
     558  		 gint         buf_len,
     559  		 const gchar *format,
     560  		 gdouble      d)
     561  {
     562    struct lconv *locale_data;
     563    const char *decimal_point;
     564    int decimal_point_len;
     565    gchar *p;
     566    int rest_len;
     567    gchar format_char;
     568  
     569    g_return_val_if_fail (buffer != NULL, NULL);
     570    g_return_val_if_fail (format[0] == '%', NULL);
     571    g_return_val_if_fail (strpbrk (format + 1, "'l%") == NULL, NULL);
     572   
     573    format_char = format[strlen (format) - 1];
     574    
     575    g_return_val_if_fail (format_char == 'e' || format_char == 'E' ||
     576  			format_char == 'f' || format_char == 'F' ||
     577  			format_char == 'g' || format_char == 'G',
     578  			NULL);
     579  
     580    if (format[0] != '%')
     581      return NULL;
     582  
     583    if (strpbrk (format + 1, "'l%"))
     584      return NULL;
     585  
     586    if (!(format_char == 'e' || format_char == 'E' ||
     587  	format_char == 'f' || format_char == 'F' ||
     588  	format_char == 'g' || format_char == 'G'))
     589      return NULL;
     590  
     591        
     592    _g_snprintf (buffer, buf_len, format, d);
     593  
     594    locale_data = localeconv ();
     595  #if HAVE_STRUCT_LCONV_DECIMAL_POINT
     596    decimal_point = locale_data->decimal_point;
     597  #else
     598    decimal_point = ".";
     599  #endif
     600    decimal_point_len = strlen (decimal_point);
     601  
     602    g_assert (decimal_point_len != 0);
     603  
     604    if (decimal_point[0] != '.' ||
     605        decimal_point[1] != 0)
     606      {
     607        p = buffer;
     608  
     609        while (g_ascii_isspace (*p))
     610  	p++;
     611  
     612        if (*p == '+' || *p == '-')
     613  	p++;
     614  
     615        while (isdigit ((guchar)*p))
     616  	p++;
     617  
     618        if (strncmp (p, decimal_point, decimal_point_len) == 0)
     619  	{
     620  	  *p = '.';
     621  	  p++;
     622  	  if (decimal_point_len > 1) {
     623  	    rest_len = strlen (p + (decimal_point_len-1));
     624  	    memmove (p, p + (decimal_point_len-1),
     625  		     rest_len);
     626  	    p[rest_len] = 0;
     627  	    
     628  	  }
     629  	}
     630      }
     631    
     632    return buffer;
     633  }
     634  
     635  #define ISSPACE(c)		((c) == ' ' || (c) == '\f' || (c) == '\n' || \
     636  				 (c) == '\r' || (c) == '\t' || (c) == '\v')
     637  #define ISUPPER(c)		((c) >= 'A' && (c) <= 'Z')
     638  #define ISLOWER(c)		((c) >= 'a' && (c) <= 'z')
     639  #define ISALPHA(c)		(ISUPPER (c) || ISLOWER (c))
     640  #define	TOUPPER(c)		(ISLOWER (c) ? (c) - 'a' + 'A' : (c))
     641  #define	TOLOWER(c)		(ISUPPER (c) ? (c) - 'A' + 'a' : (c))
     642  
     643  #if 0
     644  
     645  static guint64
     646  g_parse_long_long (const gchar *nptr,
     647  		   gchar      **endptr,
     648  		   guint        base,
     649  		   gboolean    *negative)
     650  {
     651    /* this code is based on on the strtol(3) code from GNU libc released under
     652     * the GNU Lesser General Public License.
     653     *
     654     * Copyright (C) 1991-1992, 1994-2002 Free Software Foundation, Inc.
     655     */
     656    gboolean overflow;
     657    guint64 cutoff;
     658    guint64 cutlim;
     659    guint64 ui64;
     660    const gchar *s, *save;
     661    guchar c;
     662    
     663    g_return_val_if_fail (nptr != NULL, 0);
     664    
     665    if (base == 1 || base > 36)
     666      {
     667        errno = EINVAL;
     668        return 0;
     669      }
     670    
     671    save = s = nptr;
     672    
     673    /* Skip white space.  */
     674    while (ISSPACE (*s))
     675      ++s;
     676  
     677    if (G_UNLIKELY (!*s))
     678      goto noconv;
     679    
     680    /* Check for a sign.  */
     681    *negative = FALSE;
     682    if (*s == '-')
     683      {
     684        *negative = TRUE;
     685        ++s;
     686      }
     687    else if (*s == '+')
     688      ++s;
     689    
     690    /* Recognize number prefix and if BASE is zero, figure it out ourselves.  */
     691    if (*s == '0')
     692      {
     693        if ((base == 0 || base == 16) && TOUPPER (s[1]) == 'X')
     694  	{
     695  	  s += 2;
     696  	  base = 16;
     697  	}
     698        else if (base == 0)
     699  	base = 8;
     700      }
     701    else if (base == 0)
     702      base = 10;
     703    
     704    /* Save the pointer so we can check later if anything happened.  */
     705    save = s;
     706    cutoff = G_MAXUINT64 / base;
     707    cutlim = G_MAXUINT64 % base;
     708    
     709    overflow = FALSE;
     710    ui64 = 0;
     711    c = *s;
     712    for (; c; c = *++s)
     713      {
     714        if (c >= '0' && c <= '9')
     715  	c -= '0';
     716        else if (ISALPHA (c))
     717  	c = TOUPPER (c) - 'A' + 10;
     718        else
     719  	break;
     720        if (c >= base)
     721  	break;
     722        /* Check for overflow.  */
     723        if (ui64 > cutoff || (ui64 == cutoff && c > cutlim))
     724  	overflow = TRUE;
     725        else
     726  	{
     727  	  ui64 *= base;
     728  	  ui64 += c;
     729  	}
     730      }
     731    
     732    /* Check if anything actually happened.  */
     733    if (s == save)
     734      goto noconv;
     735    
     736    /* Store in ENDPTR the address of one character
     737       past the last character we converted.  */
     738    if (endptr)
     739      *endptr = (gchar*) s;
     740    
     741    if (G_UNLIKELY (overflow))
     742      {
     743        errno = ERANGE;
     744        return G_MAXUINT64;
     745      }
     746  
     747    return ui64;
     748    
     749   noconv:
     750    /* We must handle a special case here: the base is 0 or 16 and the
     751       first two characters are '0' and 'x', but the rest are no
     752       hexadecimal digits.  This is no error case.  We return 0 and
     753       ENDPTR points to the `x`.  */
     754    if (endptr)
     755      {
     756        if (save - nptr >= 2 && TOUPPER (save[-1]) == 'X'
     757  	  && save[-2] == '0')
     758  	*endptr = (gchar*) &save[-1];
     759        else
     760  	/*  There was no number to convert.  */
     761  	*endptr = (gchar*) nptr;
     762      }
     763    return 0;
     764  }
     765  
     766  /**
     767   * g_ascii_strtoull:
     768   * @nptr:    the string to convert to a numeric value.
     769   * @endptr:  if non-%NULL, it returns the character after
     770   *           the last character used in the conversion.
     771   * @base:    to be used for the conversion, 2..36 or 0
     772   *
     773   * Converts a string to a #guint64 value.
     774   * This function behaves like the standard strtoull() function
     775   * does in the C locale. It does this without actually
     776   * changing the current locale, since that would not be
     777   * thread-safe.
     778   *
     779   * This function is typically used when reading configuration
     780   * files or other non-user input that should be locale independent.
     781   * To handle input from the user you should normally use the
     782   * locale-sensitive system strtoull() function.
     783   *
     784   * If the correct value would cause overflow, %G_MAXUINT64
     785   * is returned, and %ERANGE is stored in %errno.  If the base is
     786   * outside the valid range, zero is returned, and %EINVAL is stored
     787   * in %errno.  If the string conversion fails, zero is returned, and
     788   * @endptr returns @nptr (if @endptr is non-%NULL).
     789   *
     790   * Return value: the #guint64 value or zero on error.
     791   *
     792   * Since: 2.2
     793   **/
     794  guint64
     795  g_ascii_strtoull (const gchar *nptr,
     796  		  gchar      **endptr,
     797  		  guint        base)
     798  {
     799    gboolean negative;
     800    guint64 result;
     801  
     802    result = g_parse_long_long (nptr, endptr, base, &negative);
     803  
     804    /* Return the result of the appropriate sign.  */
     805    return negative ? -result : result;
     806  }
     807  
     808  /**
     809   * g_ascii_strtoll:
     810   * @nptr:    the string to convert to a numeric value.
     811   * @endptr:  if non-%NULL, it returns the character after
     812   *           the last character used in the conversion.
     813   * @base:    to be used for the conversion, 2..36 or 0
     814   *
     815   * Converts a string to a #gint64 value.
     816   * This function behaves like the standard strtoll() function
     817   * does in the C locale. It does this without actually
     818   * changing the current locale, since that would not be
     819   * thread-safe.
     820   *
     821   * This function is typically used when reading configuration
     822   * files or other non-user input that should be locale independent.
     823   * To handle input from the user you should normally use the
     824   * locale-sensitive system strtoll() function.
     825   *
     826   * If the correct value would cause overflow, %G_MAXINT64 or %G_MININT64
     827   * is returned, and %ERANGE is stored in %errno.  If the base is
     828   * outside the valid range, zero is returned, and %EINVAL is stored
     829   * in %errno.  If the string conversion fails, zero is returned, and
     830   * @endptr returns @nptr (if @endptr is non-%NULL).
     831   *
     832   * Return value: the #gint64 value or zero on error.
     833   *
     834   * Since: 2.12
     835   **/
     836  gint64 
     837  g_ascii_strtoll (const gchar *nptr,
     838  		 gchar      **endptr,
     839  		 guint        base)
     840  {
     841    gboolean negative;
     842    guint64 result;
     843  
     844    result = g_parse_long_long (nptr, endptr, base, &negative);
     845  
     846    if (negative && result > (guint64) G_MININT64)
     847      {
     848        errno = ERANGE;
     849        return G_MININT64;
     850      }
     851    else if (!negative && result > (guint64) G_MAXINT64)
     852      {
     853        errno = ERANGE;
     854        return G_MAXINT64;
     855      }
     856    else
     857      return (gint64) result;
     858  }
     859  
     860  G_CONST_RETURN gchar*
     861  g_strerror (gint errnum)
     862  {
     863    static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
     864    char *msg;
     865    int saved_errno = errno;
     866  
     867  #ifdef HAVE_STRERROR
     868    const char *msg_locale;
     869  
     870    msg_locale = strerror (errnum);
     871    if (g_get_charset (NULL))
     872      {
     873        errno = saved_errno;
     874        return msg_locale;
     875      }
     876    else
     877      {
     878        gchar *msg_utf8 = g_locale_to_utf8 (msg_locale, -1, NULL, NULL, NULL);
     879        if (msg_utf8)
     880  	{
     881  	  /* Stick in the quark table so that we can return a static result
     882  	   */
     883  	  GQuark msg_quark = g_quark_from_string (msg_utf8);
     884  	  g_free (msg_utf8);
     885  	  
     886  	  msg_utf8 = (gchar *) g_quark_to_string (msg_quark);
     887  	  errno = saved_errno;
     888  	  return msg_utf8;
     889  	}
     890      }
     891  #elif NO_SYS_ERRLIST
     892    switch (errnum)
     893      {
     894  #ifdef E2BIG
     895      case E2BIG: return "argument list too long";
     896  #endif
     897  #ifdef EACCES
     898      case EACCES: return "permission denied";
     899  #endif
     900  #ifdef EADDRINUSE
     901      case EADDRINUSE: return "address already in use";
     902  #endif
     903  #ifdef EADDRNOTAVAIL
     904      case EADDRNOTAVAIL: return "can't assign requested address";
     905  #endif
     906  #ifdef EADV
     907      case EADV: return "advertise error";
     908  #endif
     909  #ifdef EAFNOSUPPORT
     910      case EAFNOSUPPORT: return "address family not supported by protocol family";
     911  #endif
     912  #ifdef EAGAIN
     913      case EAGAIN: return "try again";
     914  #endif
     915  #ifdef EALIGN
     916      case EALIGN: return "EALIGN";
     917  #endif
     918  #ifdef EALREADY
     919      case EALREADY: return "operation already in progress";
     920  #endif
     921  #ifdef EBADE
     922      case EBADE: return "bad exchange descriptor";
     923  #endif
     924  #ifdef EBADF
     925      case EBADF: return "bad file number";
     926  #endif
     927  #ifdef EBADFD
     928      case EBADFD: return "file descriptor in bad state";
     929  #endif
     930  #ifdef EBADMSG
     931      case EBADMSG: return "not a data message";
     932  #endif
     933  #ifdef EBADR
     934      case EBADR: return "bad request descriptor";
     935  #endif
     936  #ifdef EBADRPC
     937      case EBADRPC: return "RPC structure is bad";
     938  #endif
     939  #ifdef EBADRQC
     940      case EBADRQC: return "bad request code";
     941  #endif
     942  #ifdef EBADSLT
     943      case EBADSLT: return "invalid slot";
     944  #endif
     945  #ifdef EBFONT
     946      case EBFONT: return "bad font file format";
     947  #endif
     948  #ifdef EBUSY
     949      case EBUSY: return "mount device busy";
     950  #endif
     951  #ifdef ECHILD
     952      case ECHILD: return "no children";
     953  #endif
     954  #ifdef ECHRNG
     955      case ECHRNG: return "channel number out of range";
     956  #endif
     957  #ifdef ECOMM
     958      case ECOMM: return "communication error on send";
     959  #endif
     960  #ifdef ECONNABORTED
     961      case ECONNABORTED: return "software caused connection abort";
     962  #endif
     963  #ifdef ECONNREFUSED
     964      case ECONNREFUSED: return "connection refused";
     965  #endif
     966  #ifdef ECONNRESET
     967      case ECONNRESET: return "connection reset by peer";
     968  #endif
     969  #if defined(EDEADLK) && (!defined(EWOULDBLOCK) || (EDEADLK != EWOULDBLOCK))
     970      case EDEADLK: return "resource deadlock avoided";
     971  #endif
     972  #ifdef EDEADLOCK
     973      case EDEADLOCK: return "resource deadlock avoided";
     974  #endif
     975  #ifdef EDESTADDRREQ
     976      case EDESTADDRREQ: return "destination address required";
     977  #endif
     978  #ifdef EDIRTY
     979      case EDIRTY: return "mounting a dirty fs w/o force";
     980  #endif
     981  #ifdef EDOM
     982      case EDOM: return "math argument out of range";
     983  #endif
     984  #ifdef EDOTDOT
     985      case EDOTDOT: return "cross mount point";
     986  #endif
     987  #ifdef EDQUOT
     988      case EDQUOT: return "disk quota exceeded";
     989  #endif
     990  #ifdef EDUPPKG
     991      case EDUPPKG: return "duplicate package name";
     992  #endif
     993  #ifdef EEXIST
     994      case EEXIST: return "file already exists";
     995  #endif
     996  #ifdef EFAULT
     997      case EFAULT: return "bad address in system call argument";
     998  #endif
     999  #ifdef EFBIG
    1000      case EFBIG: return "file too large";
    1001  #endif
    1002  #ifdef EHOSTDOWN
    1003      case EHOSTDOWN: return "host is down";
    1004  #endif
    1005  #ifdef EHOSTUNREACH
    1006      case EHOSTUNREACH: return "host is unreachable";
    1007  #endif
    1008  #ifdef EIDRM
    1009      case EIDRM: return "identifier removed";
    1010  #endif
    1011  #ifdef EINIT
    1012      case EINIT: return "initialization error";
    1013  #endif
    1014  #ifdef EINPROGRESS
    1015      case EINPROGRESS: return "operation now in progress";
    1016  #endif
    1017  #ifdef EINTR
    1018      case EINTR: return "interrupted system call";
    1019  #endif
    1020  #ifdef EINVAL
    1021      case EINVAL: return "invalid argument";
    1022  #endif
    1023  #ifdef EIO
    1024      case EIO: return "I/O error";
    1025  #endif
    1026  #ifdef EISCONN
    1027      case EISCONN: return "socket is already connected";
    1028  #endif
    1029  #ifdef EISDIR
    1030      case EISDIR: return "is a directory";
    1031  #endif
    1032  #ifdef EISNAME
    1033      case EISNAM: return "is a name file";
    1034  #endif
    1035  #ifdef ELBIN
    1036      case ELBIN: return "ELBIN";
    1037  #endif
    1038  #ifdef EL2HLT
    1039      case EL2HLT: return "level 2 halted";
    1040  #endif
    1041  #ifdef EL2NSYNC
    1042      case EL2NSYNC: return "level 2 not synchronized";
    1043  #endif
    1044  #ifdef EL3HLT
    1045      case EL3HLT: return "level 3 halted";
    1046  #endif
    1047  #ifdef EL3RST
    1048      case EL3RST: return "level 3 reset";
    1049  #endif
    1050  #ifdef ELIBACC
    1051      case ELIBACC: return "can not access a needed shared library";
    1052  #endif
    1053  #ifdef ELIBBAD
    1054      case ELIBBAD: return "accessing a corrupted shared library";
    1055  #endif
    1056  #ifdef ELIBEXEC
    1057      case ELIBEXEC: return "can not exec a shared library directly";
    1058  #endif
    1059  #ifdef ELIBMAX
    1060      case ELIBMAX: return "attempting to link in more shared libraries than system limit";
    1061  #endif
    1062  #ifdef ELIBSCN
    1063      case ELIBSCN: return ".lib section in a.out corrupted";
    1064  #endif
    1065  #ifdef ELNRNG
    1066      case ELNRNG: return "link number out of range";
    1067  #endif
    1068  #ifdef ELOOP
    1069      case ELOOP: return "too many levels of symbolic links";
    1070  #endif
    1071  #ifdef EMFILE
    1072      case EMFILE: return "too many open files";
    1073  #endif
    1074  #ifdef EMLINK
    1075      case EMLINK: return "too many links";
    1076  #endif
    1077  #ifdef EMSGSIZE
    1078      case EMSGSIZE: return "message too long";
    1079  #endif
    1080  #ifdef EMULTIHOP
    1081      case EMULTIHOP: return "multihop attempted";
    1082  #endif
    1083  #ifdef ENAMETOOLONG
    1084      case ENAMETOOLONG: return "file name too long";
    1085  #endif
    1086  #ifdef ENAVAIL
    1087      case ENAVAIL: return "not available";
    1088  #endif
    1089  #ifdef ENET
    1090      case ENET: return "ENET";
    1091  #endif
    1092  #ifdef ENETDOWN
    1093      case ENETDOWN: return "network is down";
    1094  #endif
    1095  #ifdef ENETRESET
    1096      case ENETRESET: return "network dropped connection on reset";
    1097  #endif
    1098  #ifdef ENETUNREACH
    1099      case ENETUNREACH: return "network is unreachable";
    1100  #endif
    1101  #ifdef ENFILE
    1102      case ENFILE: return "file table overflow";
    1103  #endif
    1104  #ifdef ENOANO
    1105      case ENOANO: return "anode table overflow";
    1106  #endif
    1107  #if defined(ENOBUFS) && (!defined(ENOSR) || (ENOBUFS != ENOSR))
    1108      case ENOBUFS: return "no buffer space available";
    1109  #endif
    1110  #ifdef ENOCSI
    1111      case ENOCSI: return "no CSI structure available";
    1112  #endif
    1113  #ifdef ENODATA
    1114      case ENODATA: return "no data available";
    1115  #endif
    1116  #ifdef ENODEV
    1117      case ENODEV: return "no such device";
    1118  #endif
    1119  #ifdef ENOENT
    1120      case ENOENT: return "no such file or directory";
    1121  #endif
    1122  #ifdef ENOEXEC
    1123      case ENOEXEC: return "exec format error";
    1124  #endif
    1125  #ifdef ENOLCK
    1126      case ENOLCK: return "no locks available";
    1127  #endif
    1128  #ifdef ENOLINK
    1129      case ENOLINK: return "link has be severed";
    1130  #endif
    1131  #ifdef ENOMEM
    1132      case ENOMEM: return "not enough memory";
    1133  #endif
    1134  #ifdef ENOMSG
    1135      case ENOMSG: return "no message of desired type";
    1136  #endif
    1137  #ifdef ENONET
    1138      case ENONET: return "machine is not on the network";
    1139  #endif
    1140  #ifdef ENOPKG
    1141      case ENOPKG: return "package not installed";
    1142  #endif
    1143  #ifdef ENOPROTOOPT
    1144      case ENOPROTOOPT: return "bad proocol option";
    1145  #endif
    1146  #ifdef ENOSPC
    1147      case ENOSPC: return "no space left on device";
    1148  #endif
    1149  #ifdef ENOSR
    1150      case ENOSR: return "out of stream resources";
    1151  #endif
    1152  #ifdef ENOSTR
    1153      case ENOSTR: return "not a stream device";
    1154  #endif
    1155  #ifdef ENOSYM
    1156      case ENOSYM: return "unresolved symbol name";
    1157  #endif
    1158  #ifdef ENOSYS
    1159      case ENOSYS: return "function not implemented";
    1160  #endif
    1161  #ifdef ENOTBLK
    1162      case ENOTBLK: return "block device required";
    1163  #endif
    1164  #ifdef ENOTCONN
    1165      case ENOTCONN: return "socket is not connected";
    1166  #endif
    1167  #ifdef ENOTDIR
    1168      case ENOTDIR: return "not a directory";
    1169  #endif
    1170  #ifdef ENOTEMPTY
    1171      case ENOTEMPTY: return "directory not empty";
    1172  #endif
    1173  #ifdef ENOTNAM
    1174      case ENOTNAM: return "not a name file";
    1175  #endif
    1176  #ifdef ENOTSOCK
    1177      case ENOTSOCK: return "socket operation on non-socket";
    1178  #endif
    1179  #ifdef ENOTTY
    1180      case ENOTTY: return "inappropriate device for ioctl";
    1181  #endif
    1182  #ifdef ENOTUNIQ
    1183      case ENOTUNIQ: return "name not unique on network";
    1184  #endif
    1185  #ifdef ENXIO
    1186      case ENXIO: return "no such device or address";
    1187  #endif
    1188  #ifdef EOPNOTSUPP
    1189      case EOPNOTSUPP: return "operation not supported on socket";
    1190  #endif
    1191  #ifdef EPERM
    1192      case EPERM: return "not owner";
    1193  #endif
    1194  #ifdef EPFNOSUPPORT
    1195      case EPFNOSUPPORT: return "protocol family not supported";
    1196  #endif
    1197  #ifdef EPIPE
    1198      case EPIPE: return "broken pipe";
    1199  #endif
    1200  #ifdef EPROCLIM
    1201      case EPROCLIM: return "too many processes";
    1202  #endif
    1203  #ifdef EPROCUNAVAIL
    1204      case EPROCUNAVAIL: return "bad procedure for program";
    1205  #endif
    1206  #ifdef EPROGMISMATCH
    1207      case EPROGMISMATCH: return "program version wrong";
    1208  #endif
    1209  #ifdef EPROGUNAVAIL
    1210      case EPROGUNAVAIL: return "RPC program not available";
    1211  #endif
    1212  #ifdef EPROTO
    1213      case EPROTO: return "protocol error";
    1214  #endif
    1215  #ifdef EPROTONOSUPPORT
    1216      case EPROTONOSUPPORT: return "protocol not suppored";
    1217  #endif
    1218  #ifdef EPROTOTYPE
    1219      case EPROTOTYPE: return "protocol wrong type for socket";
    1220  #endif
    1221  #ifdef ERANGE
    1222      case ERANGE: return "math result unrepresentable";
    1223  #endif
    1224  #if defined(EREFUSED) && (!defined(ECONNREFUSED) || (EREFUSED != ECONNREFUSED))
    1225      case EREFUSED: return "EREFUSED";
    1226  #endif
    1227  #ifdef EREMCHG
    1228      case EREMCHG: return "remote address changed";
    1229  #endif
    1230  #ifdef EREMDEV
    1231      case EREMDEV: return "remote device";
    1232  #endif
    1233  #ifdef EREMOTE
    1234      case EREMOTE: return "pathname hit remote file system";
    1235  #endif
    1236  #ifdef EREMOTEIO
    1237      case EREMOTEIO: return "remote i/o error";
    1238  #endif
    1239  #ifdef EREMOTERELEASE
    1240      case EREMOTERELEASE: return "EREMOTERELEASE";
    1241  #endif
    1242  #ifdef EROFS
    1243      case EROFS: return "read-only file system";
    1244  #endif
    1245  #ifdef ERPCMISMATCH
    1246      case ERPCMISMATCH: return "RPC version is wrong";
    1247  #endif
    1248  #ifdef ERREMOTE
    1249      case ERREMOTE: return "object is remote";
    1250  #endif
    1251  #ifdef ESHUTDOWN
    1252      case ESHUTDOWN: return "can't send afer socket shutdown";
    1253  #endif
    1254  #ifdef ESOCKTNOSUPPORT
    1255      case ESOCKTNOSUPPORT: return "socket type not supported";
    1256  #endif
    1257  #ifdef ESPIPE
    1258      case ESPIPE: return "invalid seek";
    1259  #endif
    1260  #ifdef ESRCH
    1261      case ESRCH: return "no such process";
    1262  #endif
    1263  #ifdef ESRMNT
    1264      case ESRMNT: return "srmount error";
    1265  #endif
    1266  #ifdef ESTALE
    1267      case ESTALE: return "stale remote file handle";
    1268  #endif
    1269  #ifdef ESUCCESS
    1270      case ESUCCESS: return "Error 0";
    1271  #endif
    1272  #ifdef ETIME
    1273      case ETIME: return "timer expired";
    1274  #endif
    1275  #ifdef ETIMEDOUT
    1276      case ETIMEDOUT: return "connection timed out";
    1277  #endif
    1278  #ifdef ETOOMANYREFS
    1279      case ETOOMANYREFS: return "too many references: can't splice";
    1280  #endif
    1281  #ifdef ETXTBSY
    1282      case ETXTBSY: return "text file or pseudo-device busy";
    1283  #endif
    1284  #ifdef EUCLEAN
    1285      case EUCLEAN: return "structure needs cleaning";
    1286  #endif
    1287  #ifdef EUNATCH
    1288      case EUNATCH: return "protocol driver not attached";
    1289  #endif
    1290  #ifdef EUSERS
    1291      case EUSERS: return "too many users";
    1292  #endif
    1293  #ifdef EVERSION
    1294      case EVERSION: return "version mismatch";
    1295  #endif
    1296  #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
    1297      case EWOULDBLOCK: return "operation would block";
    1298  #endif
    1299  #ifdef EXDEV
    1300      case EXDEV: return "cross-domain link";
    1301  #endif
    1302  #ifdef EXFULL
    1303      case EXFULL: return "message tables full";
    1304  #endif
    1305      }
    1306  #else /* NO_SYS_ERRLIST */
    1307    extern int sys_nerr;
    1308    extern char *sys_errlist[];
    1309  
    1310    if ((errnum > 0) && (errnum <= sys_nerr))
    1311      return sys_errlist [errnum];
    1312  #endif /* NO_SYS_ERRLIST */
    1313  
    1314    msg = g_static_private_get (&msg_private);
    1315    if (!msg)
    1316      {
    1317        msg = g_new (gchar, 64);
    1318        g_static_private_set (&msg_private, msg, g_free);
    1319      }
    1320  
    1321    _g_sprintf (msg, "unknown error (%d)", errnum);
    1322  
    1323    errno = saved_errno;
    1324    return msg;
    1325  }
    1326  
    1327  G_CONST_RETURN gchar*
    1328  g_strsignal (gint signum)
    1329  {
    1330    static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
    1331    char *msg;
    1332  
    1333  #ifdef HAVE_STRSIGNAL
    1334    const char *msg_locale;
    1335    
    1336  #if defined(G_OS_BEOS) || defined(G_WITH_CYGWIN)
    1337  extern const char *strsignal(int);
    1338  #else
    1339    /* this is declared differently (const) in string.h on BeOS */
    1340    extern char *strsignal (int sig);
    1341  #endif /* !G_OS_BEOS && !G_WITH_CYGWIN */
    1342    msg_locale = strsignal (signum);
    1343    if (g_get_charset (NULL))
    1344      return msg_locale;
    1345    else
    1346      {
    1347        gchar *msg_utf8 = g_locale_to_utf8 (msg_locale, -1, NULL, NULL, NULL);
    1348        if (msg_utf8)
    1349  	{
    1350  	  /* Stick in the quark table so that we can return a static result
    1351  	   */
    1352  	  GQuark msg_quark = g_quark_from_string (msg_utf8);
    1353  	  g_free (msg_utf8);
    1354  	  
    1355  	  return g_quark_to_string (msg_quark);
    1356  	}
    1357      }
    1358  #elif NO_SYS_SIGLIST
    1359    switch (signum)
    1360      {
    1361  #ifdef SIGHUP
    1362      case SIGHUP: return "Hangup";
    1363  #endif
    1364  #ifdef SIGINT
    1365      case SIGINT: return "Interrupt";
    1366  #endif
    1367  #ifdef SIGQUIT
    1368      case SIGQUIT: return "Quit";
    1369  #endif
    1370  #ifdef SIGILL
    1371      case SIGILL: return "Illegal instruction";
    1372  #endif
    1373  #ifdef SIGTRAP
    1374      case SIGTRAP: return "Trace/breakpoint trap";
    1375  #endif
    1376  #ifdef SIGABRT
    1377      case SIGABRT: return "IOT trap/Abort";
    1378  #endif
    1379  #ifdef SIGBUS
    1380      case SIGBUS: return "Bus error";
    1381  #endif
    1382  #ifdef SIGFPE
    1383      case SIGFPE: return "Floating point exception";
    1384  #endif
    1385  #ifdef SIGKILL
    1386      case SIGKILL: return "Killed";
    1387  #endif
    1388  #ifdef SIGUSR1
    1389      case SIGUSR1: return "User defined signal 1";
    1390  #endif
    1391  #ifdef SIGSEGV
    1392      case SIGSEGV: return "Segmentation fault";
    1393  #endif
    1394  #ifdef SIGUSR2
    1395      case SIGUSR2: return "User defined signal 2";
    1396  #endif
    1397  #ifdef SIGPIPE
    1398      case SIGPIPE: return "Broken pipe";
    1399  #endif
    1400  #ifdef SIGALRM
    1401      case SIGALRM: return "Alarm clock";
    1402  #endif
    1403  #ifdef SIGTERM
    1404      case SIGTERM: return "Terminated";
    1405  #endif
    1406  #ifdef SIGSTKFLT
    1407      case SIGSTKFLT: return "Stack fault";
    1408  #endif
    1409  #ifdef SIGCHLD
    1410      case SIGCHLD: return "Child exited";
    1411  #endif
    1412  #ifdef SIGCONT
    1413      case SIGCONT: return "Continued";
    1414  #endif
    1415  #ifdef SIGSTOP
    1416      case SIGSTOP: return "Stopped (signal)";
    1417  #endif
    1418  #ifdef SIGTSTP
    1419      case SIGTSTP: return "Stopped";
    1420  #endif
    1421  #ifdef SIGTTIN
    1422      case SIGTTIN: return "Stopped (tty input)";
    1423  #endif
    1424  #ifdef SIGTTOU
    1425      case SIGTTOU: return "Stopped (tty output)";
    1426  #endif
    1427  #ifdef SIGURG
    1428      case SIGURG: return "Urgent condition";
    1429  #endif
    1430  #ifdef SIGXCPU
    1431      case SIGXCPU: return "CPU time limit exceeded";
    1432  #endif
    1433  #ifdef SIGXFSZ
    1434      case SIGXFSZ: return "File size limit exceeded";
    1435  #endif
    1436  #ifdef SIGVTALRM
    1437      case SIGVTALRM: return "Virtual time alarm";
    1438  #endif
    1439  #ifdef SIGPROF
    1440      case SIGPROF: return "Profile signal";
    1441  #endif
    1442  #ifdef SIGWINCH
    1443      case SIGWINCH: return "Window size changed";
    1444  #endif
    1445  #ifdef SIGIO
    1446      case SIGIO: return "Possible I/O";
    1447  #endif
    1448  #ifdef SIGPWR
    1449      case SIGPWR: return "Power failure";
    1450  #endif
    1451  #ifdef SIGUNUSED
    1452      case SIGUNUSED: return "Unused signal";
    1453  #endif
    1454      }
    1455  #else /* NO_SYS_SIGLIST */
    1456  
    1457  #ifdef NO_SYS_SIGLIST_DECL
    1458    extern char *sys_siglist[];	/*(see Tue Jan 19 00:44:24 1999 in changelog)*/
    1459  #endif
    1460  
    1461    return (char*) /* this function should return const --josh */ sys_siglist [signum];
    1462  #endif /* NO_SYS_SIGLIST */
    1463  
    1464    msg = g_static_private_get (&msg_private);
    1465    if (!msg)
    1466      {
    1467        msg = g_new (gchar, 64);
    1468        g_static_private_set (&msg_private, msg, g_free);
    1469      }
    1470  
    1471    _g_sprintf (msg, "unknown signal (%d)", signum);
    1472    
    1473    return msg;
    1474  }
    1475  
    1476  /* Functions g_strlcpy and g_strlcat were originally developed by
    1477   * Todd C. Miller <Todd.Miller@courtesan.com> to simplify writing secure code.
    1478   * See ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3
    1479   * for more information.
    1480   */
    1481  
    1482  #ifdef HAVE_STRLCPY
    1483  /* Use the native ones, if available; they might be implemented in assembly */
    1484  gsize
    1485  g_strlcpy (gchar       *dest,
    1486  	   const gchar *src,
    1487  	   gsize        dest_size)
    1488  {
    1489    g_return_val_if_fail (dest != NULL, 0);
    1490    g_return_val_if_fail (src  != NULL, 0);
    1491    
    1492    return strlcpy (dest, src, dest_size);
    1493  }
    1494  
    1495  gsize
    1496  g_strlcat (gchar       *dest,
    1497  	   const gchar *src,
    1498  	   gsize        dest_size)
    1499  {
    1500    g_return_val_if_fail (dest != NULL, 0);
    1501    g_return_val_if_fail (src  != NULL, 0);
    1502    
    1503    return strlcat (dest, src, dest_size);
    1504  }
    1505  
    1506  #else /* ! HAVE_STRLCPY */
    1507  /* g_strlcpy
    1508   *
    1509   * Copy string src to buffer dest (of buffer size dest_size).  At most
    1510   * dest_size-1 characters will be copied.  Always NUL terminates
    1511   * (unless dest_size == 0).  This function does NOT allocate memory.
    1512   * Unlike strncpy, this function doesn't pad dest (so it's often faster).
    1513   * Returns size of attempted result, strlen(src),
    1514   * so if retval >= dest_size, truncation occurred.
    1515   */
    1516  gsize
    1517  g_strlcpy (gchar       *dest,
    1518             const gchar *src,
    1519             gsize        dest_size)
    1520  {
    1521    register gchar *d = dest;
    1522    register const gchar *s = src;
    1523    register gsize n = dest_size;
    1524    
    1525    g_return_val_if_fail (dest != NULL, 0);
    1526    g_return_val_if_fail (src  != NULL, 0);
    1527    
    1528    /* Copy as many bytes as will fit */
    1529    if (n != 0 && --n != 0)
    1530      do
    1531        {
    1532  	register gchar c = *s++;
    1533  	
    1534  	*d++ = c;
    1535  	if (c == 0)
    1536  	  break;
    1537        }
    1538      while (--n != 0);
    1539    
    1540    /* If not enough room in dest, add NUL and traverse rest of src */
    1541    if (n == 0)
    1542      {
    1543        if (dest_size != 0)
    1544  	*d = 0;
    1545        while (*s++)
    1546  	;
    1547      }
    1548    
    1549    return s - src - 1;  /* count does not include NUL */
    1550  }
    1551  
    1552  /* g_strlcat
    1553   *
    1554   * Appends string src to buffer dest (of buffer size dest_size).
    1555   * At most dest_size-1 characters will be copied.
    1556   * Unlike strncat, dest_size is the full size of dest, not the space left over.
    1557   * This function does NOT allocate memory.
    1558   * This always NUL terminates (unless siz == 0 or there were no NUL characters
    1559   * in the dest_size characters of dest to start with).
    1560   * Returns size of attempted result, which is
    1561   * MIN (dest_size, strlen (original dest)) + strlen (src),
    1562   * so if retval >= dest_size, truncation occurred.
    1563   */
    1564  gsize
    1565  g_strlcat (gchar       *dest,
    1566             const gchar *src,
    1567             gsize        dest_size)
    1568  {
    1569    register gchar *d = dest;
    1570    register const gchar *s = src;
    1571    register gsize bytes_left = dest_size;
    1572    gsize dlength;  /* Logically, MIN (strlen (d), dest_size) */
    1573    
    1574    g_return_val_if_fail (dest != NULL, 0);
    1575    g_return_val_if_fail (src  != NULL, 0);
    1576    
    1577    /* Find the end of dst and adjust bytes left but don't go past end */
    1578    while (*d != 0 && bytes_left-- != 0)
    1579      d++;
    1580    dlength = d - dest;
    1581    bytes_left = dest_size - dlength;
    1582    
    1583    if (bytes_left == 0)
    1584      return dlength + strlen (s);
    1585    
    1586    while (*s != 0)
    1587      {
    1588        if (bytes_left != 1)
    1589  	{
    1590  	  *d++ = *s;
    1591  	  bytes_left--;
    1592  	}
    1593        s++;
    1594      }
    1595    *d = 0;
    1596    
    1597    return dlength + (s - src);  /* count does not include NUL */
    1598  }
    1599  #endif /* ! HAVE_STRLCPY */
    1600  
    1601  /**
    1602   * g_ascii_strdown:
    1603   * @str: a string.
    1604   * @len: length of @str in bytes, or -1 if @str is nul-terminated.
    1605   * 
    1606   * Converts all upper case ASCII letters to lower case ASCII letters.
    1607   * 
    1608   * Return value: a newly-allocated string, with all the upper case
    1609   *               characters in @str converted to lower case, with
    1610   *               semantics that exactly match g_ascii_tolower(). (Note
    1611   *               that this is unlike the old g_strdown(), which modified
    1612   *               the string in place.)
    1613   **/
    1614  gchar*
    1615  g_ascii_strdown (const gchar *str,
    1616  		 gssize       len)
    1617  {
    1618    gchar *result, *s;
    1619    
    1620    g_return_val_if_fail (str != NULL, NULL);
    1621  
    1622    if (len < 0)
    1623      len = strlen (str);
    1624  
    1625    result = g_strndup (str, len);
    1626    for (s = result; *s; s++)
    1627      *s = g_ascii_tolower (*s);
    1628    
    1629    return result;
    1630  }
    1631  
    1632  #endif
    1633  
    1634  /**
    1635   * g_ascii_strup:
    1636   * @str: a string.
    1637   * @len: length of @str in bytes, or -1 if @str is nul-terminated.
    1638   * 
    1639   * Converts all lower case ASCII letters to upper case ASCII letters.
    1640   * 
    1641   * Return value: a newly allocated string, with all the lower case
    1642   *               characters in @str converted to upper case, with
    1643   *               semantics that exactly match g_ascii_toupper(). (Note
    1644   *               that this is unlike the old g_strup(), which modified
    1645   *               the string in place.)
    1646   **/
    1647  gchar*
    1648  g_ascii_strup (const gchar *str,
    1649  	       gssize       len)
    1650  {
    1651    gchar *result, *s;
    1652  
    1653    g_return_val_if_fail (str != NULL, NULL);
    1654  
    1655    if (len < 0)
    1656      len = strlen (str);
    1657  
    1658    result = g_strndup (str, len);
    1659    for (s = result; *s; s++)
    1660      *s = g_ascii_toupper (*s);
    1661  
    1662    return result;
    1663  }
    1664  
    1665  #if 0
    1666  
    1667  /**
    1668   * g_strdown:
    1669   * @string: the string to convert.
    1670   * 
    1671   * Converts a string to lower case.  
    1672   * 
    1673   * Return value: the string 
    1674   *
    1675   * Deprecated:2.2: This function is totally broken for the reasons discussed 
    1676   * in the g_strncasecmp() docs - use g_ascii_strdown() or g_utf8_strdown() 
    1677   * instead.
    1678   **/
    1679  gchar*
    1680  g_strdown (gchar *string)
    1681  {
    1682    register guchar *s;
    1683    
    1684    g_return_val_if_fail (string != NULL, NULL);
    1685    
    1686    s = (guchar *) string;
    1687    
    1688    while (*s)
    1689      {
    1690        if (isupper (*s))
    1691  	*s = tolower (*s);
    1692        s++;
    1693      }
    1694    
    1695    return (gchar *) string;
    1696  }
    1697  
    1698  /**
    1699   * g_strup:
    1700   * @string: the string to convert.
    1701   * 
    1702   * Converts a string to upper case. 
    1703   * 
    1704   * Return value: the string
    1705   *
    1706   * Deprecated:2.2: This function is totally broken for the reasons discussed 
    1707   * in the g_strncasecmp() docs - use g_ascii_strup() or g_utf8_strup() instead.
    1708   **/
    1709  gchar*
    1710  g_strup (gchar *string)
    1711  {
    1712    register guchar *s;
    1713  
    1714    g_return_val_if_fail (string != NULL, NULL);
    1715  
    1716    s = (guchar *) string;
    1717  
    1718    while (*s)
    1719      {
    1720        if (islower (*s))
    1721  	*s = toupper (*s);
    1722        s++;
    1723      }
    1724  
    1725    return (gchar *) string;
    1726  }
    1727  
    1728  gchar*
    1729  g_strreverse (gchar *string)
    1730  {
    1731    g_return_val_if_fail (string != NULL, NULL);
    1732  
    1733    if (*string)
    1734      {
    1735        register gchar *h, *t;
    1736  
    1737        h = string;
    1738        t = string + strlen (string) - 1;
    1739  
    1740        while (h < t)
    1741  	{
    1742  	  register gchar c;
    1743  
    1744  	  c = *h;
    1745  	  *h = *t;
    1746  	  h++;
    1747  	  *t = c;
    1748  	  t--;
    1749  	}
    1750      }
    1751  
    1752    return string;
    1753  }
    1754  
    1755  /**
    1756   * g_ascii_tolower:
    1757   * @c: any character.
    1758   * 
    1759   * Convert a character to ASCII lower case.
    1760   *
    1761   * Unlike the standard C library tolower() function, this only
    1762   * recognizes standard ASCII letters and ignores the locale, returning
    1763   * all non-ASCII characters unchanged, even if they are lower case
    1764   * letters in a particular character set. Also unlike the standard
    1765   * library function, this takes and returns a char, not an int, so
    1766   * don't call it on %EOF but no need to worry about casting to #guchar
    1767   * before passing a possibly non-ASCII character in.
    1768   * 
    1769   * Return value: the result of converting @c to lower case.
    1770   *               If @c is not an ASCII upper case letter,
    1771   *               @c is returned unchanged.
    1772   **/
    1773  gchar
    1774  g_ascii_tolower (gchar c)
    1775  {
    1776    return g_ascii_isupper (c) ? c - 'A' + 'a' : c;
    1777  }
    1778  
    1779  #endif
    1780  
    1781  /**
    1782   * g_ascii_toupper:
    1783   * @c: any character.
    1784   * 
    1785   * Convert a character to ASCII upper case.
    1786   *
    1787   * Unlike the standard C library toupper() function, this only
    1788   * recognizes standard ASCII letters and ignores the locale, returning
    1789   * all non-ASCII characters unchanged, even if they are upper case
    1790   * letters in a particular character set. Also unlike the standard
    1791   * library function, this takes and returns a char, not an int, so
    1792   * don't call it on %EOF but no need to worry about casting to #guchar
    1793   * before passing a possibly non-ASCII character in.
    1794   * 
    1795   * Return value: the result of converting @c to upper case.
    1796   *               If @c is not an ASCII lower case letter,
    1797   *               @c is returned unchanged.
    1798   **/
    1799  gchar
    1800  g_ascii_toupper (gchar c)
    1801  {
    1802    return g_ascii_islower (c) ? c - 'a' + 'A' : c;
    1803  }
    1804  
    1805  #if 0
    1806  
    1807  /**
    1808   * g_ascii_digit_value:
    1809   * @c: an ASCII character.
    1810   *
    1811   * Determines the numeric value of a character as a decimal
    1812   * digit. Differs from g_unichar_digit_value() because it takes
    1813   * a char, so there's no worry about sign extension if characters
    1814   * are signed.
    1815   *
    1816   * Return value: If @c is a decimal digit (according to
    1817   * g_ascii_isdigit()), its numeric value. Otherwise, -1.
    1818   **/
    1819  int
    1820  g_ascii_digit_value (gchar c)
    1821  {
    1822    if (g_ascii_isdigit (c))
    1823      return c - '0';
    1824    return -1;
    1825  }
    1826  
    1827  /**
    1828   * g_ascii_xdigit_value:
    1829   * @c: an ASCII character.
    1830   *
    1831   * Determines the numeric value of a character as a hexidecimal
    1832   * digit. Differs from g_unichar_xdigit_value() because it takes
    1833   * a char, so there's no worry about sign extension if characters
    1834   * are signed.
    1835   *
    1836   * Return value: If @c is a hex digit (according to
    1837   * g_ascii_isxdigit()), its numeric value. Otherwise, -1.
    1838   **/
    1839  int
    1840  g_ascii_xdigit_value (gchar c)
    1841  {
    1842    if (c >= 'A' && c <= 'F')
    1843      return c - 'A' + 10;
    1844    if (c >= 'a' && c <= 'f')
    1845      return c - 'a' + 10;
    1846    return g_ascii_digit_value (c);
    1847  }
    1848  
    1849  #endif
    1850  
    1851  /**
    1852   * g_ascii_strcasecmp:
    1853   * @s1: string to compare with @s2.
    1854   * @s2: string to compare with @s1.
    1855   * 
    1856   * Compare two strings, ignoring the case of ASCII characters.
    1857   *
    1858   * Unlike the BSD strcasecmp() function, this only recognizes standard
    1859   * ASCII letters and ignores the locale, treating all non-ASCII
    1860   * bytes as if they are not letters.
    1861   *
    1862   * This function should be used only on strings that are known to be
    1863   * in encodings where the bytes corresponding to ASCII letters always
    1864   * represent themselves. This includes UTF-8 and the ISO-8859-*
    1865   * charsets, but not for instance double-byte encodings like the
    1866   * Windows Codepage 932, where the trailing bytes of double-byte
    1867   * characters include all ASCII letters. If you compare two CP932
    1868   * strings using this function, you will get false matches.
    1869   *
    1870   * Return value: 0 if the strings match, a negative value if @s1 &lt; @s2, 
    1871   *   or a positive value if @s1 &gt; @s2.
    1872   **/
    1873  gint
    1874  g_ascii_strcasecmp (const gchar *s1,
    1875  		    const gchar *s2)
    1876  {
    1877    gint c1, c2;
    1878  
    1879    g_return_val_if_fail (s1 != NULL, 0);
    1880    g_return_val_if_fail (s2 != NULL, 0);
    1881  
    1882    while (*s1 && *s2)
    1883      {
    1884        c1 = (gint)(guchar) TOLOWER (*s1);
    1885        c2 = (gint)(guchar) TOLOWER (*s2);
    1886        if (c1 != c2)
    1887  	return (c1 - c2);
    1888        s1++; s2++;
    1889      }
    1890  
    1891    return (((gint)(guchar) *s1) - ((gint)(guchar) *s2));
    1892  }
    1893  
    1894  #if 0
    1895  
    1896  /**
    1897   * g_ascii_strncasecmp:
    1898   * @s1: string to compare with @s2.
    1899   * @s2: string to compare with @s1.
    1900   * @n:  number of characters to compare.
    1901   * 
    1902   * Compare @s1 and @s2, ignoring the case of ASCII characters and any
    1903   * characters after the first @n in each string.
    1904   *
    1905   * Unlike the BSD strcasecmp() function, this only recognizes standard
    1906   * ASCII letters and ignores the locale, treating all non-ASCII
    1907   * characters as if they are not letters.
    1908   * 
    1909   * The same warning as in g_ascii_strcasecmp() applies: Use this
    1910   * function only on strings known to be in encodings where bytes
    1911   * corresponding to ASCII letters always represent themselves.
    1912   *
    1913   * Return value: 0 if the strings match, a negative value if @s1 &lt; @s2, 
    1914   *   or a positive value if @s1 &gt; @s2.
    1915   **/
    1916  gint
    1917  g_ascii_strncasecmp (const gchar *s1,
    1918  		     const gchar *s2,
    1919  		     gsize n)
    1920  {
    1921    gint c1, c2;
    1922  
    1923    g_return_val_if_fail (s1 != NULL, 0);
    1924    g_return_val_if_fail (s2 != NULL, 0);
    1925  
    1926    while (n && *s1 && *s2)
    1927      {
    1928        n -= 1;
    1929        c1 = (gint)(guchar) TOLOWER (*s1);
    1930        c2 = (gint)(guchar) TOLOWER (*s2);
    1931        if (c1 != c2)
    1932  	return (c1 - c2);
    1933        s1++; s2++;
    1934      }
    1935  
    1936    if (n)
    1937      return (((gint) (guchar) *s1) - ((gint) (guchar) *s2));
    1938    else
    1939      return 0;
    1940  }
    1941  
    1942  /**
    1943   * g_strcasecmp:
    1944   * @s1: a string.
    1945   * @s2: a string to compare with @s1.
    1946   * 
    1947   * A case-insensitive string comparison, corresponding to the standard
    1948   * strcasecmp() function on platforms which support it.
    1949   *
    1950   * Return value: 0 if the strings match, a negative value if @s1 &lt; @s2, 
    1951   *   or a positive value if @s1 &gt; @s2.
    1952   *
    1953   * Deprecated:2.2: See g_strncasecmp() for a discussion of why this function 
    1954   *   is deprecated and how to replace it.
    1955   **/
    1956  gint
    1957  g_strcasecmp (const gchar *s1,
    1958  	      const gchar *s2)
    1959  {
    1960  #ifdef HAVE_STRCASECMP
    1961    g_return_val_if_fail (s1 != NULL, 0);
    1962    g_return_val_if_fail (s2 != NULL, 0);
    1963  
    1964    return strcasecmp (s1, s2);
    1965  #else
    1966    gint c1, c2;
    1967  
    1968    g_return_val_if_fail (s1 != NULL, 0);
    1969    g_return_val_if_fail (s2 != NULL, 0);
    1970  
    1971    while (*s1 && *s2)
    1972      {
    1973        /* According to A. Cox, some platforms have islower's that
    1974         * don't work right on non-uppercase
    1975         */
    1976        c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1;
    1977        c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2;
    1978        if (c1 != c2)
    1979  	return (c1 - c2);
    1980        s1++; s2++;
    1981      }
    1982  
    1983    return (((gint)(guchar) *s1) - ((gint)(guchar) *s2));
    1984  #endif
    1985  }
    1986  
    1987  /**
    1988   * g_strncasecmp:
    1989   * @s1: a string.
    1990   * @s2: a string to compare with @s1.
    1991   * @n: the maximum number of characters to compare.
    1992   * 
    1993   * A case-insensitive string comparison, corresponding to the standard
    1994   * strncasecmp() function on platforms which support it.
    1995   * It is similar to g_strcasecmp() except it only compares the first @n 
    1996   * characters of the strings.
    1997   * 
    1998   * Return value: 0 if the strings match, a negative value if @s1 &lt; @s2, 
    1999   *   or a positive value if @s1 &gt; @s2.
    2000   *
    2001   * Deprecated:2.2: The problem with g_strncasecmp() is that it does the 
    2002   * comparison by calling toupper()/tolower(). These functions are
    2003   * locale-specific and operate on single bytes. However, it is impossible
    2004   * to handle things correctly from an I18N standpoint by operating on
    2005   * bytes, since characters may be multibyte. Thus g_strncasecmp() is
    2006   * broken if your string is guaranteed to be ASCII, since it's
    2007   * locale-sensitive, and it's broken if your string is localized, since
    2008   * it doesn't work on many encodings at all, including UTF-8, EUC-JP,
    2009   * etc.
    2010   *
    2011   * There are therefore two replacement functions: g_ascii_strncasecmp(),
    2012   * which only works on ASCII and is not locale-sensitive, and
    2013   * g_utf8_casefold(), which is good for case-insensitive sorting of UTF-8.
    2014   **/
    2015  gint
    2016  g_strncasecmp (const gchar *s1,
    2017  	       const gchar *s2,
    2018  	       guint n)     
    2019  {
    2020  #ifdef HAVE_STRNCASECMP
    2021    return strncasecmp (s1, s2, n);
    2022  #else
    2023    gint c1, c2;
    2024  
    2025    g_return_val_if_fail (s1 != NULL, 0);
    2026    g_return_val_if_fail (s2 != NULL, 0);
    2027  
    2028    while (n && *s1 && *s2)
    2029      {
    2030        n -= 1;
    2031        /* According to A. Cox, some platforms have islower's that
    2032         * don't work right on non-uppercase
    2033         */
    2034        c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1;
    2035        c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2;
    2036        if (c1 != c2)
    2037  	return (c1 - c2);
    2038        s1++; s2++;
    2039      }
    2040  
    2041    if (n)
    2042      return (((gint) (guchar) *s1) - ((gint) (guchar) *s2));
    2043    else
    2044      return 0;
    2045  #endif
    2046  }
    2047  
    2048  gchar*
    2049  g_strdelimit (gchar	  *string,
    2050  	      const gchar *delimiters,
    2051  	      gchar	   new_delim)
    2052  {
    2053    register gchar *c;
    2054  
    2055    g_return_val_if_fail (string != NULL, NULL);
    2056  
    2057    if (!delimiters)
    2058      delimiters = G_STR_DELIMITERS;
    2059  
    2060    for (c = string; *c; c++)
    2061      {
    2062        if (strchr (delimiters, *c))
    2063  	*c = new_delim;
    2064      }
    2065  
    2066    return string;
    2067  }
    2068  
    2069  gchar*
    2070  g_strcanon (gchar       *string,
    2071  	    const gchar *valid_chars,
    2072  	    gchar        substitutor)
    2073  {
    2074    register gchar *c;
    2075  
    2076    g_return_val_if_fail (string != NULL, NULL);
    2077    g_return_val_if_fail (valid_chars != NULL, NULL);
    2078  
    2079    for (c = string; *c; c++)
    2080      {
    2081        if (!strchr (valid_chars, *c))
    2082  	*c = substitutor;
    2083      }
    2084  
    2085    return string;
    2086  }
    2087  
    2088  gchar*
    2089  g_strcompress (const gchar *source)
    2090  {
    2091    const gchar *p = source, *octal;
    2092    gchar *dest = g_malloc (strlen (source) + 1);
    2093    gchar *q = dest;
    2094    
    2095    while (*p)
    2096      {
    2097        if (*p == '\\')
    2098  	{
    2099  	  p++;
    2100  	  switch (*p)
    2101  	    {
    2102  	    case '\0':
    2103  	      g_warning ("g_strcompress: trailing \\");
    2104  	      goto out;
    2105  	    case '0':  case '1':  case '2':  case '3':  case '4':
    2106  	    case '5':  case '6':  case '7':
    2107  	      *q = 0;
    2108  	      octal = p;
    2109  	      while ((p < octal + 3) && (*p >= '0') && (*p <= '7'))
    2110  		{
    2111  		  *q = (*q * 8) + (*p - '0');
    2112  		  p++;
    2113  		}
    2114  	      q++;
    2115  	      p--;
    2116  	      break;
    2117  	    case 'b':
    2118  	      *q++ = '\b';
    2119  	      break;
    2120  	    case 'f':
    2121  	      *q++ = '\f';
    2122  	      break;
    2123  	    case 'n':
    2124  	      *q++ = '\n';
    2125  	      break;
    2126  	    case 'r':
    2127  	      *q++ = '\r';
    2128  	      break;
    2129  	    case 't':
    2130  	      *q++ = '\t';
    2131  	      break;
    2132  	    default:		/* Also handles \" and \\ */
    2133  	      *q++ = *p;
    2134  	      break;
    2135  	    }
    2136  	}
    2137        else
    2138  	*q++ = *p;
    2139        p++;
    2140      }
    2141  out:
    2142    *q = 0;
    2143    
    2144    return dest;
    2145  }
    2146  
    2147  gchar *
    2148  g_strescape (const gchar *source,
    2149  	     const gchar *exceptions)
    2150  {
    2151    const guchar *p;
    2152    gchar *dest;
    2153    gchar *q;
    2154    guchar excmap[256];
    2155    
    2156    g_return_val_if_fail (source != NULL, NULL);
    2157  
    2158    p = (guchar *) source;
    2159    /* Each source byte needs maximally four destination chars (\777) */
    2160    q = dest = g_malloc (strlen (source) * 4 + 1);
    2161  
    2162    memset (excmap, 0, 256);
    2163    if (exceptions)
    2164      {
    2165        guchar *e = (guchar *) exceptions;
    2166  
    2167        while (*e)
    2168  	{
    2169  	  excmap[*e] = 1;
    2170  	  e++;
    2171  	}
    2172      }
    2173  
    2174    while (*p)
    2175      {
    2176        if (excmap[*p])
    2177  	*q++ = *p;
    2178        else
    2179  	{
    2180  	  switch (*p)
    2181  	    {
    2182  	    case '\b':
    2183  	      *q++ = '\\';
    2184  	      *q++ = 'b';
    2185  	      break;
    2186  	    case '\f':
    2187  	      *q++ = '\\';
    2188  	      *q++ = 'f';
    2189  	      break;
    2190  	    case '\n':
    2191  	      *q++ = '\\';
    2192  	      *q++ = 'n';
    2193  	      break;
    2194  	    case '\r':
    2195  	      *q++ = '\\';
    2196  	      *q++ = 'r';
    2197  	      break;
    2198  	    case '\t':
    2199  	      *q++ = '\\';
    2200  	      *q++ = 't';
    2201  	      break;
    2202  	    case '\\':
    2203  	      *q++ = '\\';
    2204  	      *q++ = '\\';
    2205  	      break;
    2206  	    case '"':
    2207  	      *q++ = '\\';
    2208  	      *q++ = '"';
    2209  	      break;
    2210  	    default:
    2211  	      if ((*p < ' ') || (*p >= 0177))
    2212  		{
    2213  		  *q++ = '\\';
    2214  		  *q++ = '0' + (((*p) >> 6) & 07);
    2215  		  *q++ = '0' + (((*p) >> 3) & 07);
    2216  		  *q++ = '0' + ((*p) & 07);
    2217  		}
    2218  	      else
    2219  		*q++ = *p;
    2220  	      break;
    2221  	    }
    2222  	}
    2223        p++;
    2224      }
    2225    *q = 0;
    2226    return dest;
    2227  }
    2228  
    2229  gchar*
    2230  g_strchug (gchar *string)
    2231  {
    2232    guchar *start;
    2233  
    2234    g_return_val_if_fail (string != NULL, NULL);
    2235  
    2236    for (start = (guchar*) string; *start && g_ascii_isspace (*start); start++)
    2237      ;
    2238  
    2239    g_memmove (string, start, strlen ((gchar *) start) + 1);
    2240  
    2241    return string;
    2242  }
    2243  
    2244  gchar*
    2245  g_strchomp (gchar *string)
    2246  {
    2247    gsize len;
    2248  
    2249    g_return_val_if_fail (string != NULL, NULL);
    2250  
    2251    len = strlen (string);
    2252    while (len--)
    2253      {
    2254        if (g_ascii_isspace ((guchar) string[len]))
    2255  	string[len] = '\0';
    2256        else
    2257  	break;
    2258      }
    2259  
    2260    return string;
    2261  }
    2262  
    2263  /**
    2264   * g_strsplit:
    2265   * @string: a string to split.
    2266   * @delimiter: a string which specifies the places at which to split the string.
    2267   *     The delimiter is not included in any of the resulting strings, unless
    2268   *     @max_tokens is reached.
    2269   * @max_tokens: the maximum number of pieces to split @string into. If this is
    2270   *              less than 1, the string is split completely.
    2271   * 
    2272   * Splits a string into a maximum of @max_tokens pieces, using the given
    2273   * @delimiter. If @max_tokens is reached, the remainder of @string is appended
    2274   * to the last token. 
    2275   *
    2276   * As a special case, the result of splitting the empty string "" is an empty
    2277   * vector, not a vector containing a single string. The reason for this
    2278   * special case is that being able to represent a empty vector is typically
    2279   * more useful than consistent handling of empty elements. If you do need
    2280   * to represent empty elements, you'll need to check for the empty string
    2281   * before calling g_strsplit().
    2282   * 
    2283   * Return value: a newly-allocated %NULL-terminated array of strings. Use 
    2284   *    g_strfreev() to free it.
    2285   **/
    2286  gchar**
    2287  g_strsplit (const gchar *string,
    2288  	    const gchar *delimiter,
    2289  	    gint         max_tokens)
    2290  {
    2291    GSList *string_list = NULL, *slist;
    2292    gchar **str_array, *s;
    2293    guint n = 0;
    2294    const gchar *remainder;
    2295  
    2296    g_return_val_if_fail (string != NULL, NULL);
    2297    g_return_val_if_fail (delimiter != NULL, NULL);
    2298    g_return_val_if_fail (delimiter[0] != '\0', NULL);
    2299  
    2300    if (max_tokens < 1)
    2301      max_tokens = G_MAXINT;
    2302  
    2303    remainder = string;
    2304    s = strstr (remainder, delimiter);
    2305    if (s)
    2306      {
    2307        gsize delimiter_len = strlen (delimiter);   
    2308  
    2309        while (--max_tokens && s)
    2310  	{
    2311  	  gsize len;     
    2312  	  gchar *new_string;
    2313  
    2314  	  len = s - remainder;
    2315  	  new_string = g_new (gchar, len + 1);
    2316  	  strncpy (new_string, remainder, len);
    2317  	  new_string[len] = 0;
    2318  	  string_list = g_slist_prepend (string_list, new_string);
    2319  	  n++;
    2320  	  remainder = s + delimiter_len;
    2321  	  s = strstr (remainder, delimiter);
    2322  	}
    2323      }
    2324    if (*string)
    2325      {
    2326        n++;
    2327        string_list = g_slist_prepend (string_list, g_strdup (remainder));
    2328      }
    2329  
    2330    str_array = g_new (gchar*, n + 1);
    2331  
    2332    str_array[n--] = NULL;
    2333    for (slist = string_list; slist; slist = slist->next)
    2334      str_array[n--] = slist->data;
    2335  
    2336    g_slist_free (string_list);
    2337  
    2338    return str_array;
    2339  }
    2340  
    2341  /**
    2342   * g_strsplit_set:
    2343   * @string: The string to be tokenized
    2344   * @delimiters: A nul-terminated string containing bytes that are used
    2345   *              to split the string.
    2346   * @max_tokens: The maximum number of tokens to split @string into. 
    2347   *              If this is less than 1, the string is split completely
    2348   * 
    2349   * Splits @string into a number of tokens not containing any of the characters
    2350   * in @delimiter. A token is the (possibly empty) longest string that does not
    2351   * contain any of the characters in @delimiters. If @max_tokens is reached, the
    2352   * remainder is appended to the last token.
    2353   *
    2354   * For example the result of g_strsplit_set ("abc:def/ghi", ":/", -1) is a
    2355   * %NULL-terminated vector containing the three strings "abc", "def", 
    2356   * and "ghi".
    2357   *
    2358   * The result if g_strsplit_set (":def/ghi:", ":/", -1) is a %NULL-terminated
    2359   * vector containing the four strings "", "def", "ghi", and "".
    2360   * 
    2361   * As a special case, the result of splitting the empty string "" is an empty
    2362   * vector, not a vector containing a single string. The reason for this
    2363   * special case is that being able to represent a empty vector is typically
    2364   * more useful than consistent handling of empty elements. If you do need
    2365   * to represent empty elements, you'll need to check for the empty string
    2366   * before calling g_strsplit_set().
    2367   *
    2368   * Note that this function works on bytes not characters, so it can't be used 
    2369   * to delimit UTF-8 strings for anything but ASCII characters.
    2370   * 
    2371   * Return value: a newly-allocated %NULL-terminated array of strings. Use 
    2372   *    g_strfreev() to free it.
    2373   * 
    2374   * Since: 2.4
    2375   **/
    2376  gchar **
    2377  g_strsplit_set (const gchar *string,
    2378  	        const gchar *delimiters,
    2379  	        gint         max_tokens)
    2380  {
    2381    gboolean delim_table[256];
    2382    GSList *tokens, *list;
    2383    gint n_tokens;
    2384    const gchar *s;
    2385    const gchar *current;
    2386    gchar *token;
    2387    gchar **result;
    2388    
    2389    g_return_val_if_fail (string != NULL, NULL);
    2390    g_return_val_if_fail (delimiters != NULL, NULL);
    2391  
    2392    if (max_tokens < 1)
    2393      max_tokens = G_MAXINT;
    2394  
    2395    if (*string == '\0')
    2396      {
    2397        result = g_new (char *, 1);
    2398        result[0] = NULL;
    2399        return result;
    2400      }
    2401    
    2402    memset (delim_table, FALSE, sizeof (delim_table));
    2403    for (s = delimiters; *s != '\0'; ++s)
    2404      delim_table[*(guchar *)s] = TRUE;
    2405  
    2406    tokens = NULL;
    2407    n_tokens = 0;
    2408  
    2409    s = current = string;
    2410    while (*s != '\0')
    2411      {
    2412        if (delim_table[*(guchar *)s] && n_tokens + 1 < max_tokens)
    2413  	{
    2414  	  gchar *token;
    2415  
    2416  	  token = g_strndup (current, s - current);
    2417  	  tokens = g_slist_prepend (tokens, token);
    2418  	  ++n_tokens;
    2419  
    2420  	  current = s + 1;
    2421  	}
    2422        
    2423        ++s;
    2424      }
    2425  
    2426    token = g_strndup (current, s - current);
    2427    tokens = g_slist_prepend (tokens, token);
    2428    ++n_tokens;
    2429  
    2430    result = g_new (gchar *, n_tokens + 1);
    2431  
    2432    result[n_tokens] = NULL;
    2433    for (list = tokens; list != NULL; list = list->next)
    2434      result[--n_tokens] = list->data;
    2435  
    2436    g_slist_free (tokens);
    2437    
    2438    return result;
    2439  }
    2440  
    2441  /**
    2442   * g_strfreev:
    2443   * @str_array: a %NULL-terminated array of strings to free.
    2444  
    2445   * Frees a %NULL-terminated array of strings, and the array itself.
    2446   * If called on a %NULL value, g_strfreev() simply returns. 
    2447   **/
    2448  void
    2449  g_strfreev (gchar **str_array)
    2450  {
    2451    if (str_array)
    2452      {
    2453        int i;
    2454  
    2455        for(i = 0; str_array[i] != NULL; i++)
    2456  	g_free(str_array[i]);
    2457  
    2458        g_free (str_array);
    2459      }
    2460  }
    2461  
    2462  /**
    2463   * g_strdupv:
    2464   * @str_array: %NULL-terminated array of strings.
    2465   * 
    2466   * Copies %NULL-terminated array of strings. The copy is a deep copy;
    2467   * the new array should be freed by first freeing each string, then
    2468   * the array itself. g_strfreev() does this for you. If called
    2469   * on a %NULL value, g_strdupv() simply returns %NULL.
    2470   * 
    2471   * Return value: a new %NULL-terminated array of strings.
    2472   **/
    2473  gchar**
    2474  g_strdupv (gchar **str_array)
    2475  {
    2476    if (str_array)
    2477      {
    2478        gint i;
    2479        gchar **retval;
    2480  
    2481        i = 0;
    2482        while (str_array[i])
    2483          ++i;
    2484            
    2485        retval = g_new (gchar*, i + 1);
    2486  
    2487        i = 0;
    2488        while (str_array[i])
    2489          {
    2490            retval[i] = g_strdup (str_array[i]);
    2491            ++i;
    2492          }
    2493        retval[i] = NULL;
    2494  
    2495        return retval;
    2496      }
    2497    else
    2498      return NULL;
    2499  }
    2500  
    2501  gchar*
    2502  g_strjoinv (const gchar  *separator,
    2503  	    gchar       **str_array)
    2504  {
    2505    gchar *string;
    2506    gchar *ptr;
    2507  
    2508    g_return_val_if_fail (str_array != NULL, NULL);
    2509  
    2510    if (separator == NULL)
    2511      separator = "";
    2512  
    2513    if (*str_array)
    2514      {
    2515        gint i;
    2516        gsize len;
    2517        gsize separator_len;     
    2518  
    2519        separator_len = strlen (separator);
    2520        /* First part, getting length */
    2521        len = 1 + strlen (str_array[0]);
    2522        for (i = 1; str_array[i] != NULL; i++)
    2523          len += strlen (str_array[i]);
    2524        len += separator_len * (i - 1);
    2525  
    2526        /* Second part, building string */
    2527        string = g_new (gchar, len);
    2528        ptr = g_stpcpy (string, *str_array);
    2529        for (i = 1; str_array[i] != NULL; i++)
    2530  	{
    2531            ptr = g_stpcpy (ptr, separator);
    2532            ptr = g_stpcpy (ptr, str_array[i]);
    2533  	}
    2534        }
    2535    else
    2536      string = g_strdup ("");
    2537  
    2538    return string;
    2539  }
    2540  
    2541  gchar*
    2542  g_strjoin (const gchar  *separator,
    2543  	   ...)
    2544  {
    2545    gchar *string, *s;
    2546    va_list args;
    2547    gsize len;               
    2548    gsize separator_len;     
    2549    gchar *ptr;
    2550  
    2551    if (separator == NULL)
    2552      separator = "";
    2553  
    2554    separator_len = strlen (separator);
    2555  
    2556    va_start (args, separator);
    2557  
    2558    s = va_arg (args, gchar*);
    2559  
    2560    if (s)
    2561      {
    2562        /* First part, getting length */
    2563        len = 1 + strlen (s);
    2564  
    2565        s = va_arg (args, gchar*);
    2566        while (s)
    2567  	{
    2568  	  len += separator_len + strlen (s);
    2569  	  s = va_arg (args, gchar*);
    2570  	}
    2571        va_end (args);
    2572  
    2573        /* Second part, building string */
    2574        string = g_new (gchar, len);
    2575  
    2576        va_start (args, separator);
    2577  
    2578        s = va_arg (args, gchar*);
    2579        ptr = g_stpcpy (string, s);
    2580  
    2581        s = va_arg (args, gchar*);
    2582        while (s)
    2583  	{
    2584  	  ptr = g_stpcpy (ptr, separator);
    2585            ptr = g_stpcpy (ptr, s);
    2586  	  s = va_arg (args, gchar*);
    2587  	}
    2588      }
    2589    else
    2590      string = g_strdup ("");
    2591  
    2592    va_end (args);
    2593  
    2594    return string;
    2595  }
    2596  
    2597  #endif
    2598  
    2599  /**
    2600   * g_strstr_len:
    2601   * @haystack: a string.
    2602   * @haystack_len: the maximum length of @haystack.
    2603   * @needle: the string to search for.
    2604   *
    2605   * Searches the string @haystack for the first occurrence
    2606   * of the string @needle, limiting the length of the search
    2607   * to @haystack_len. 
    2608   *
    2609   * Return value: a pointer to the found occurrence, or
    2610   *    %NULL if not found.
    2611   **/
    2612  gchar *
    2613  g_strstr_len (const gchar *haystack,
    2614  	      gssize       haystack_len,
    2615  	      const gchar *needle)
    2616  {
    2617    g_return_val_if_fail (haystack != NULL, NULL);
    2618    g_return_val_if_fail (needle != NULL, NULL);
    2619    
    2620    if (haystack_len < 0)
    2621      return strstr (haystack, needle);
    2622    else
    2623      {
    2624        const gchar *p = haystack;
    2625        gsize needle_len = strlen (needle);
    2626        const gchar *end;
    2627        gsize i;
    2628  
    2629        if (needle_len == 0)
    2630  	return (gchar *)haystack;
    2631  
    2632        if (haystack_len < needle_len)
    2633  	return NULL;
    2634        
    2635        end = haystack + haystack_len - needle_len;
    2636        
    2637        while (*p && p <= end)
    2638  	{
    2639  	  for (i = 0; i < needle_len; i++)
    2640  	    if (p[i] != needle[i])
    2641  	      goto next;
    2642  	  
    2643  	  return (gchar *)p;
    2644  	  
    2645  	next:
    2646  	  p++;
    2647  	}
    2648        
    2649        return NULL;
    2650      }
    2651  }
    2652  
    2653  #if 0
    2654  
    2655  /**
    2656   * g_strrstr:
    2657   * @haystack: a nul-terminated string.
    2658   * @needle: the nul-terminated string to search for.
    2659   *
    2660   * Searches the string @haystack for the last occurrence
    2661   * of the string @needle.
    2662   *
    2663   * Return value: a pointer to the found occurrence, or
    2664   *    %NULL if not found.
    2665   **/
    2666  gchar *
    2667  g_strrstr (const gchar *haystack,
    2668  	   const gchar *needle)
    2669  {
    2670    gsize i;
    2671    gsize needle_len;
    2672    gsize haystack_len;
    2673    const gchar *p;
    2674        
    2675    g_return_val_if_fail (haystack != NULL, NULL);
    2676    g_return_val_if_fail (needle != NULL, NULL);
    2677  
    2678    needle_len = strlen (needle);
    2679    haystack_len = strlen (haystack);
    2680  
    2681    if (needle_len == 0)
    2682      return (gchar *)haystack;
    2683  
    2684    if (haystack_len < needle_len)
    2685      return NULL;
    2686    
    2687    p = haystack + haystack_len - needle_len;
    2688  
    2689    while (p >= haystack)
    2690      {
    2691        for (i = 0; i < needle_len; i++)
    2692  	if (p[i] != needle[i])
    2693  	  goto next;
    2694        
    2695        return (gchar *)p;
    2696        
    2697      next:
    2698        p--;
    2699      }
    2700    
    2701    return NULL;
    2702  }
    2703  
    2704  /**
    2705   * g_strrstr_len:
    2706   * @haystack: a nul-terminated string.
    2707   * @haystack_len: the maximum length of @haystack.
    2708   * @needle: the nul-terminated string to search for.
    2709   *
    2710   * Searches the string @haystack for the last occurrence
    2711   * of the string @needle, limiting the length of the search
    2712   * to @haystack_len. 
    2713   *
    2714   * Return value: a pointer to the found occurrence, or
    2715   *    %NULL if not found.
    2716   **/
    2717  gchar *
    2718  g_strrstr_len (const gchar *haystack,
    2719  	       gssize        haystack_len,
    2720  	       const gchar *needle)
    2721  {
    2722    g_return_val_if_fail (haystack != NULL, NULL);
    2723    g_return_val_if_fail (needle != NULL, NULL);
    2724    
    2725    if (haystack_len < 0)
    2726      return g_strrstr (haystack, needle);
    2727    else
    2728      {
    2729        gsize needle_len = strlen (needle);
    2730        const gchar *haystack_max = haystack + haystack_len;
    2731        const gchar *p = haystack;
    2732        gsize i;
    2733  
    2734        while (p < haystack_max && *p)
    2735  	p++;
    2736  
    2737        if (p < haystack + needle_len)
    2738  	return NULL;
    2739  	
    2740        p -= needle_len;
    2741  
    2742        while (p >= haystack)
    2743  	{
    2744  	  for (i = 0; i < needle_len; i++)
    2745  	    if (p[i] != needle[i])
    2746  	      goto next;
    2747  	  
    2748  	  return (gchar *)p;
    2749  	  
    2750  	next:
    2751  	  p--;
    2752  	}
    2753  
    2754        return NULL;
    2755      }
    2756  }
    2757  
    2758  
    2759  /**
    2760   * g_str_has_suffix:
    2761   * @str: a nul-terminated string.
    2762   * @suffix: the nul-terminated suffix to look for.
    2763   *
    2764   * Looks whether the string @str ends with @suffix.
    2765   *
    2766   * Return value: %TRUE if @str end with @suffix, %FALSE otherwise.
    2767   *
    2768   * Since: 2.2
    2769   **/
    2770  gboolean
    2771  g_str_has_suffix (const gchar  *str,
    2772  		  const gchar  *suffix)
    2773  {
    2774    int str_len;
    2775    int suffix_len;
    2776    
    2777    g_return_val_if_fail (str != NULL, FALSE);
    2778    g_return_val_if_fail (suffix != NULL, FALSE);
    2779  
    2780    str_len = strlen (str);
    2781    suffix_len = strlen (suffix);
    2782  
    2783    if (str_len < suffix_len)
    2784      return FALSE;
    2785  
    2786    return strcmp (str + str_len - suffix_len, suffix) == 0;
    2787  }
    2788  
    2789  /**
    2790   * g_str_has_prefix:
    2791   * @str: a nul-terminated string.
    2792   * @prefix: the nul-terminated prefix to look for.
    2793   *
    2794   * Looks whether the string @str begins with @prefix.
    2795   *
    2796   * Return value: %TRUE if @str begins with @prefix, %FALSE otherwise.
    2797   *
    2798   * Since: 2.2
    2799   **/
    2800  gboolean
    2801  g_str_has_prefix (const gchar  *str,
    2802  		  const gchar  *prefix)
    2803  {
    2804    int str_len;
    2805    int prefix_len;
    2806    
    2807    g_return_val_if_fail (str != NULL, FALSE);
    2808    g_return_val_if_fail (prefix != NULL, FALSE);
    2809  
    2810    str_len = strlen (str);
    2811    prefix_len = strlen (prefix);
    2812  
    2813    if (str_len < prefix_len)
    2814      return FALSE;
    2815    
    2816    return strncmp (str, prefix, prefix_len) == 0;
    2817  }
    2818  
    2819  
    2820  /**
    2821   * g_strip_context:
    2822   * @msgid: a string
    2823   * @msgval: another string
    2824   * 
    2825   * An auxiliary function for gettext() support (see Q_()).
    2826   * 
    2827   * Return value: @msgval, unless @msgval is identical to @msgid and contains
    2828   *   a '|' character, in which case a pointer to the substring of msgid after
    2829   *   the first '|' character is returned. 
    2830   *
    2831   * Since: 2.4
    2832   **/
    2833  G_CONST_RETURN gchar *
    2834  g_strip_context  (const gchar *msgid, 
    2835  		  const gchar *msgval)
    2836  {
    2837    if (msgval == msgid)
    2838      {
    2839        const char *c = strchr (msgid, '|');
    2840        if (c != NULL)
    2841  	return c + 1;
    2842      }
    2843    
    2844    return msgval;
    2845  }
    2846  
    2847  
    2848  /**
    2849   * g_strv_length:
    2850   * @str_array: a %NULL-terminated array of strings.
    2851   * 
    2852   * Returns the length of the given %NULL-terminated 
    2853   * string array @str_array.
    2854   * 
    2855   * Return value: length of @str_array.
    2856   *
    2857   * Since: 2.6
    2858   **/
    2859  guint
    2860  g_strv_length (gchar **str_array)
    2861  {
    2862    guint i = 0;
    2863  
    2864    g_return_val_if_fail (str_array != NULL, 0);
    2865  
    2866    while (str_array[i])
    2867      ++i;
    2868  
    2869    return i;
    2870  }
    2871  
    2872  #define __G_STRFUNCS_C__
    2873  #include "galiasdef.c"
    2874  #endif