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