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