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