Patch from Matthias Clasen (#59806)
[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 <ctype.h>              /* For tolower() */
43 #if !defined (HAVE_STRSIGNAL) || !defined(NO_SYS_SIGLIST_DECL)
44 #include <signal.h>
45 #endif
46 #include "glib.h"
47
48 #ifdef G_OS_WIN32
49 #include <windows.h>
50 #endif
51
52 /* do not include <unistd.h> in this place since it
53  * inteferes with g_strsignal() on some OSes
54  */
55
56 static const guint16 ascii_table_data[256] = {
57   0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
58   0x004, 0x104, 0x104, 0x004, 0x104, 0x104, 0x004, 0x004,
59   0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
60   0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
61   0x140, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0,
62   0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0,
63   0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459,
64   0x459, 0x459, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0,
65   0x0d0, 0x653, 0x653, 0x653, 0x653, 0x653, 0x653, 0x253,
66   0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253,
67   0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253,
68   0x253, 0x253, 0x253, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0,
69   0x0d0, 0x473, 0x473, 0x473, 0x473, 0x473, 0x473, 0x073,
70   0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073,
71   0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073,
72   0x073, 0x073, 0x073, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x004
73   /* the upper 128 are all zeroes */
74 };
75
76 #if defined(G_PLATFORM_WIN32) && defined(__GNUC__)
77 __declspec(dllexport)
78 #endif
79 const guint16 * const g_ascii_table = ascii_table_data;
80
81 gchar*
82 g_strdup (const gchar *str)
83 {
84   gchar *new_str;
85
86   if (str)
87     {
88       new_str = g_new (char, strlen (str) + 1);
89       strcpy (new_str, str);
90     }
91   else
92     new_str = NULL;
93
94   return new_str;
95 }
96
97 gpointer
98 g_memdup (gconstpointer mem,
99           guint         byte_size)
100 {
101   gpointer new_mem;
102
103   if (mem)
104     {
105       new_mem = g_malloc (byte_size);
106       memcpy (new_mem, mem, byte_size);
107     }
108   else
109     new_mem = NULL;
110
111   return new_mem;
112 }
113
114 gchar*
115 g_strndup (const gchar *str,
116            gsize        n)    
117 {
118   gchar *new_str;
119
120   if (str)
121     {
122       new_str = g_new (gchar, n + 1);
123       strncpy (new_str, str, n);
124       new_str[n] = '\0';
125     }
126   else
127     new_str = NULL;
128
129   return new_str;
130 }
131
132 gchar*
133 g_strnfill (gsize length,     
134             gchar fill_char)
135 {
136   register gchar *str, *s, *end;
137
138   str = g_new (gchar, length + 1);
139   s = str;
140   end = str + length;
141   while (s < end)
142     *(s++) = fill_char;
143   *s = 0;
144
145   return str;
146 }
147
148 /**
149  * g_stpcpy:
150  * @dest: destination buffer
151  * @src: source string
152  * 
153  * Copies a nul-terminated string into the dest buffer, include the
154  * trailing nul, and return a pointer to the trailing nul byte.
155  * This is useful for concatenating multiple strings together
156  * without having to repeatedly scan for the end.
157  * 
158  * Return value: a pointer to trailing nul byte.
159  **/
160 gchar *
161 g_stpcpy (gchar       *dest,
162           const gchar *src)
163 {
164 #ifdef HAVE_STPCPY
165   g_return_val_if_fail (dest != NULL, NULL);
166   g_return_val_if_fail (src != NULL, NULL);
167   return stpcpy (dest, src);
168 #else
169   register gchar *d = dest;
170   register const gchar *s = src;
171
172   g_return_val_if_fail (dest != NULL, NULL);
173   g_return_val_if_fail (src != NULL, NULL);
174   do
175     *d++ = *s;
176   while (*s++ != '\0');
177
178   return d - 1;
179 #endif
180 }
181
182 gchar*
183 g_strdup_vprintf (const gchar *format,
184                   va_list      args1)
185 {
186   gchar *buffer;
187 #ifdef HAVE_VASPRINTF
188   vasprintf (&buffer, format, args1);
189   if (g_mem_vtable_is_set ()) 
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   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 gdouble
260 g_strtod (const gchar *nptr,
261           gchar **endptr)
262 {
263   gchar *fail_pos_1;
264   gchar *fail_pos_2;
265   gdouble val_1;
266   gdouble val_2 = 0;
267
268   g_return_val_if_fail (nptr != NULL, 0);
269
270   fail_pos_1 = NULL;
271   fail_pos_2 = NULL;
272
273   val_1 = strtod (nptr, &fail_pos_1);
274
275   if (fail_pos_1 && fail_pos_1[0] != 0)
276     {
277       gchar *old_locale;
278
279       old_locale = g_strdup (setlocale (LC_NUMERIC, NULL));
280       setlocale (LC_NUMERIC, "C");
281       val_2 = strtod (nptr, &fail_pos_2);
282       setlocale (LC_NUMERIC, old_locale);
283       g_free (old_locale);
284     }
285
286   if (!fail_pos_1 || fail_pos_1[0] == 0 || fail_pos_1 >= fail_pos_2)
287     {
288       if (endptr)
289         *endptr = fail_pos_1;
290       return val_1;
291     }
292   else
293     {
294       if (endptr)
295         *endptr = fail_pos_2;
296       return val_2;
297     }
298 }
299
300 G_CONST_RETURN gchar*
301 g_strerror (gint errnum)
302 {
303   static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
304   char *msg;
305
306 #ifdef HAVE_STRERROR
307   return strerror (errnum);
308 #elif NO_SYS_ERRLIST
309   switch (errnum)
310     {
311 #ifdef E2BIG
312     case E2BIG: return "argument list too long";
313 #endif
314 #ifdef EACCES
315     case EACCES: return "permission denied";
316 #endif
317 #ifdef EADDRINUSE
318     case EADDRINUSE: return "address already in use";
319 #endif
320 #ifdef EADDRNOTAVAIL
321     case EADDRNOTAVAIL: return "can't assign requested address";
322 #endif
323 #ifdef EADV
324     case EADV: return "advertise error";
325 #endif
326 #ifdef EAFNOSUPPORT
327     case EAFNOSUPPORT: return "address family not supported by protocol family";
328 #endif
329 #ifdef EAGAIN
330     case EAGAIN: return "try again";
331 #endif
332 #ifdef EALIGN
333     case EALIGN: return "EALIGN";
334 #endif
335 #ifdef EALREADY
336     case EALREADY: return "operation already in progress";
337 #endif
338 #ifdef EBADE
339     case EBADE: return "bad exchange descriptor";
340 #endif
341 #ifdef EBADF
342     case EBADF: return "bad file number";
343 #endif
344 #ifdef EBADFD
345     case EBADFD: return "file descriptor in bad state";
346 #endif
347 #ifdef EBADMSG
348     case EBADMSG: return "not a data message";
349 #endif
350 #ifdef EBADR
351     case EBADR: return "bad request descriptor";
352 #endif
353 #ifdef EBADRPC
354     case EBADRPC: return "RPC structure is bad";
355 #endif
356 #ifdef EBADRQC
357     case EBADRQC: return "bad request code";
358 #endif
359 #ifdef EBADSLT
360     case EBADSLT: return "invalid slot";
361 #endif
362 #ifdef EBFONT
363     case EBFONT: return "bad font file format";
364 #endif
365 #ifdef EBUSY
366     case EBUSY: return "mount device busy";
367 #endif
368 #ifdef ECHILD
369     case ECHILD: return "no children";
370 #endif
371 #ifdef ECHRNG
372     case ECHRNG: return "channel number out of range";
373 #endif
374 #ifdef ECOMM
375     case ECOMM: return "communication error on send";
376 #endif
377 #ifdef ECONNABORTED
378     case ECONNABORTED: return "software caused connection abort";
379 #endif
380 #ifdef ECONNREFUSED
381     case ECONNREFUSED: return "connection refused";
382 #endif
383 #ifdef ECONNRESET
384     case ECONNRESET: return "connection reset by peer";
385 #endif
386 #if defined(EDEADLK) && (!defined(EWOULDBLOCK) || (EDEADLK != EWOULDBLOCK))
387     case EDEADLK: return "resource deadlock avoided";
388 #endif
389 #ifdef EDEADLOCK
390     case EDEADLOCK: return "resource deadlock avoided";
391 #endif
392 #ifdef EDESTADDRREQ
393     case EDESTADDRREQ: return "destination address required";
394 #endif
395 #ifdef EDIRTY
396     case EDIRTY: return "mounting a dirty fs w/o force";
397 #endif
398 #ifdef EDOM
399     case EDOM: return "math argument out of range";
400 #endif
401 #ifdef EDOTDOT
402     case EDOTDOT: return "cross mount point";
403 #endif
404 #ifdef EDQUOT
405     case EDQUOT: return "disk quota exceeded";
406 #endif
407 #ifdef EDUPPKG
408     case EDUPPKG: return "duplicate package name";
409 #endif
410 #ifdef EEXIST
411     case EEXIST: return "file already exists";
412 #endif
413 #ifdef EFAULT
414     case EFAULT: return "bad address in system call argument";
415 #endif
416 #ifdef EFBIG
417     case EFBIG: return "file too large";
418 #endif
419 #ifdef EHOSTDOWN
420     case EHOSTDOWN: return "host is down";
421 #endif
422 #ifdef EHOSTUNREACH
423     case EHOSTUNREACH: return "host is unreachable";
424 #endif
425 #ifdef EIDRM
426     case EIDRM: return "identifier removed";
427 #endif
428 #ifdef EINIT
429     case EINIT: return "initialization error";
430 #endif
431 #ifdef EINPROGRESS
432     case EINPROGRESS: return "operation now in progress";
433 #endif
434 #ifdef EINTR
435     case EINTR: return "interrupted system call";
436 #endif
437 #ifdef EINVAL
438     case EINVAL: return "invalid argument";
439 #endif
440 #ifdef EIO
441     case EIO: return "I/O error";
442 #endif
443 #ifdef EISCONN
444     case EISCONN: return "socket is already connected";
445 #endif
446 #ifdef EISDIR
447     case EISDIR: return "is a directory";
448 #endif
449 #ifdef EISNAME
450     case EISNAM: return "is a name file";
451 #endif
452 #ifdef ELBIN
453     case ELBIN: return "ELBIN";
454 #endif
455 #ifdef EL2HLT
456     case EL2HLT: return "level 2 halted";
457 #endif
458 #ifdef EL2NSYNC
459     case EL2NSYNC: return "level 2 not synchronized";
460 #endif
461 #ifdef EL3HLT
462     case EL3HLT: return "level 3 halted";
463 #endif
464 #ifdef EL3RST
465     case EL3RST: return "level 3 reset";
466 #endif
467 #ifdef ELIBACC
468     case ELIBACC: return "can not access a needed shared library";
469 #endif
470 #ifdef ELIBBAD
471     case ELIBBAD: return "accessing a corrupted shared library";
472 #endif
473 #ifdef ELIBEXEC
474     case ELIBEXEC: return "can not exec a shared library directly";
475 #endif
476 #ifdef ELIBMAX
477     case ELIBMAX: return "attempting to link in more shared libraries than system limit";
478 #endif
479 #ifdef ELIBSCN
480     case ELIBSCN: return ".lib section in a.out corrupted";
481 #endif
482 #ifdef ELNRNG
483     case ELNRNG: return "link number out of range";
484 #endif
485 #ifdef ELOOP
486     case ELOOP: return "too many levels of symbolic links";
487 #endif
488 #ifdef EMFILE
489     case EMFILE: return "too many open files";
490 #endif
491 #ifdef EMLINK
492     case EMLINK: return "too many links";
493 #endif
494 #ifdef EMSGSIZE
495     case EMSGSIZE: return "message too long";
496 #endif
497 #ifdef EMULTIHOP
498     case EMULTIHOP: return "multihop attempted";
499 #endif
500 #ifdef ENAMETOOLONG
501     case ENAMETOOLONG: return "file name too long";
502 #endif
503 #ifdef ENAVAIL
504     case ENAVAIL: return "not available";
505 #endif
506 #ifdef ENET
507     case ENET: return "ENET";
508 #endif
509 #ifdef ENETDOWN
510     case ENETDOWN: return "network is down";
511 #endif
512 #ifdef ENETRESET
513     case ENETRESET: return "network dropped connection on reset";
514 #endif
515 #ifdef ENETUNREACH
516     case ENETUNREACH: return "network is unreachable";
517 #endif
518 #ifdef ENFILE
519     case ENFILE: return "file table overflow";
520 #endif
521 #ifdef ENOANO
522     case ENOANO: return "anode table overflow";
523 #endif
524 #if defined(ENOBUFS) && (!defined(ENOSR) || (ENOBUFS != ENOSR))
525     case ENOBUFS: return "no buffer space available";
526 #endif
527 #ifdef ENOCSI
528     case ENOCSI: return "no CSI structure available";
529 #endif
530 #ifdef ENODATA
531     case ENODATA: return "no data available";
532 #endif
533 #ifdef ENODEV
534     case ENODEV: return "no such device";
535 #endif
536 #ifdef ENOENT
537     case ENOENT: return "no such file or directory";
538 #endif
539 #ifdef ENOEXEC
540     case ENOEXEC: return "exec format error";
541 #endif
542 #ifdef ENOLCK
543     case ENOLCK: return "no locks available";
544 #endif
545 #ifdef ENOLINK
546     case ENOLINK: return "link has be severed";
547 #endif
548 #ifdef ENOMEM
549     case ENOMEM: return "not enough memory";
550 #endif
551 #ifdef ENOMSG
552     case ENOMSG: return "no message of desired type";
553 #endif
554 #ifdef ENONET
555     case ENONET: return "machine is not on the network";
556 #endif
557 #ifdef ENOPKG
558     case ENOPKG: return "package not installed";
559 #endif
560 #ifdef ENOPROTOOPT
561     case ENOPROTOOPT: return "bad proocol option";
562 #endif
563 #ifdef ENOSPC
564     case ENOSPC: return "no space left on device";
565 #endif
566 #ifdef ENOSR
567     case ENOSR: return "out of stream resources";
568 #endif
569 #ifdef ENOSTR
570     case ENOSTR: return "not a stream device";
571 #endif
572 #ifdef ENOSYM
573     case ENOSYM: return "unresolved symbol name";
574 #endif
575 #ifdef ENOSYS
576     case ENOSYS: return "function not implemented";
577 #endif
578 #ifdef ENOTBLK
579     case ENOTBLK: return "block device required";
580 #endif
581 #ifdef ENOTCONN
582     case ENOTCONN: return "socket is not connected";
583 #endif
584 #ifdef ENOTDIR
585     case ENOTDIR: return "not a directory";
586 #endif
587 #ifdef ENOTEMPTY
588     case ENOTEMPTY: return "directory not empty";
589 #endif
590 #ifdef ENOTNAM
591     case ENOTNAM: return "not a name file";
592 #endif
593 #ifdef ENOTSOCK
594     case ENOTSOCK: return "socket operation on non-socket";
595 #endif
596 #ifdef ENOTTY
597     case ENOTTY: return "inappropriate device for ioctl";
598 #endif
599 #ifdef ENOTUNIQ
600     case ENOTUNIQ: return "name not unique on network";
601 #endif
602 #ifdef ENXIO
603     case ENXIO: return "no such device or address";
604 #endif
605 #ifdef EOPNOTSUPP
606     case EOPNOTSUPP: return "operation not supported on socket";
607 #endif
608 #ifdef EPERM
609     case EPERM: return "not owner";
610 #endif
611 #ifdef EPFNOSUPPORT
612     case EPFNOSUPPORT: return "protocol family not supported";
613 #endif
614 #ifdef EPIPE
615     case EPIPE: return "broken pipe";
616 #endif
617 #ifdef EPROCLIM
618     case EPROCLIM: return "too many processes";
619 #endif
620 #ifdef EPROCUNAVAIL
621     case EPROCUNAVAIL: return "bad procedure for program";
622 #endif
623 #ifdef EPROGMISMATCH
624     case EPROGMISMATCH: return "program version wrong";
625 #endif
626 #ifdef EPROGUNAVAIL
627     case EPROGUNAVAIL: return "RPC program not available";
628 #endif
629 #ifdef EPROTO
630     case EPROTO: return "protocol error";
631 #endif
632 #ifdef EPROTONOSUPPORT
633     case EPROTONOSUPPORT: return "protocol not suppored";
634 #endif
635 #ifdef EPROTOTYPE
636     case EPROTOTYPE: return "protocol wrong type for socket";
637 #endif
638 #ifdef ERANGE
639     case ERANGE: return "math result unrepresentable";
640 #endif
641 #if defined(EREFUSED) && (!defined(ECONNREFUSED) || (EREFUSED != ECONNREFUSED))
642     case EREFUSED: return "EREFUSED";
643 #endif
644 #ifdef EREMCHG
645     case EREMCHG: return "remote address changed";
646 #endif
647 #ifdef EREMDEV
648     case EREMDEV: return "remote device";
649 #endif
650 #ifdef EREMOTE
651     case EREMOTE: return "pathname hit remote file system";
652 #endif
653 #ifdef EREMOTEIO
654     case EREMOTEIO: return "remote i/o error";
655 #endif
656 #ifdef EREMOTERELEASE
657     case EREMOTERELEASE: return "EREMOTERELEASE";
658 #endif
659 #ifdef EROFS
660     case EROFS: return "read-only file system";
661 #endif
662 #ifdef ERPCMISMATCH
663     case ERPCMISMATCH: return "RPC version is wrong";
664 #endif
665 #ifdef ERREMOTE
666     case ERREMOTE: return "object is remote";
667 #endif
668 #ifdef ESHUTDOWN
669     case ESHUTDOWN: return "can't send afer socket shutdown";
670 #endif
671 #ifdef ESOCKTNOSUPPORT
672     case ESOCKTNOSUPPORT: return "socket type not supported";
673 #endif
674 #ifdef ESPIPE
675     case ESPIPE: return "invalid seek";
676 #endif
677 #ifdef ESRCH
678     case ESRCH: return "no such process";
679 #endif
680 #ifdef ESRMNT
681     case ESRMNT: return "srmount error";
682 #endif
683 #ifdef ESTALE
684     case ESTALE: return "stale remote file handle";
685 #endif
686 #ifdef ESUCCESS
687     case ESUCCESS: return "Error 0";
688 #endif
689 #ifdef ETIME
690     case ETIME: return "timer expired";
691 #endif
692 #ifdef ETIMEDOUT
693     case ETIMEDOUT: return "connection timed out";
694 #endif
695 #ifdef ETOOMANYREFS
696     case ETOOMANYREFS: return "too many references: can't splice";
697 #endif
698 #ifdef ETXTBSY
699     case ETXTBSY: return "text file or pseudo-device busy";
700 #endif
701 #ifdef EUCLEAN
702     case EUCLEAN: return "structure needs cleaning";
703 #endif
704 #ifdef EUNATCH
705     case EUNATCH: return "protocol driver not attached";
706 #endif
707 #ifdef EUSERS
708     case EUSERS: return "too many users";
709 #endif
710 #ifdef EVERSION
711     case EVERSION: return "version mismatch";
712 #endif
713 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
714     case EWOULDBLOCK: return "operation would block";
715 #endif
716 #ifdef EXDEV
717     case EXDEV: return "cross-domain link";
718 #endif
719 #ifdef EXFULL
720     case EXFULL: return "message tables full";
721 #endif
722     }
723 #else /* NO_SYS_ERRLIST */
724   extern int sys_nerr;
725   extern char *sys_errlist[];
726
727   if ((errnum > 0) && (errnum <= sys_nerr))
728     return sys_errlist [errnum];
729 #endif /* NO_SYS_ERRLIST */
730
731   msg = g_static_private_get (&msg_private);
732   if (!msg)
733     {
734       msg = g_new (gchar, 64);
735       g_static_private_set (&msg_private, msg, g_free);
736     }
737
738   sprintf (msg, "unknown error (%d)", errnum);
739
740   return msg;
741 }
742
743 G_CONST_RETURN gchar*
744 g_strsignal (gint signum)
745 {
746   static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
747   char *msg;
748
749 #ifdef HAVE_STRSIGNAL
750 #if defined(G_OS_BEOS) || defined(G_WITH_CYGWIN)
751 extern const char *strsignal(int);
752 #else
753   /* this is declared differently (const) in string.h on BeOS */
754   extern char *strsignal (int sig);
755 #endif /* !G_OS_BEOS && !G_WITH_CYGWIN */
756   return strsignal (signum);
757 #elif NO_SYS_SIGLIST
758   switch (signum)
759     {
760 #ifdef SIGHUP
761     case SIGHUP: return "Hangup";
762 #endif
763 #ifdef SIGINT
764     case SIGINT: return "Interrupt";
765 #endif
766 #ifdef SIGQUIT
767     case SIGQUIT: return "Quit";
768 #endif
769 #ifdef SIGILL
770     case SIGILL: return "Illegal instruction";
771 #endif
772 #ifdef SIGTRAP
773     case SIGTRAP: return "Trace/breakpoint trap";
774 #endif
775 #ifdef SIGABRT
776     case SIGABRT: return "IOT trap/Abort";
777 #endif
778 #ifdef SIGBUS
779     case SIGBUS: return "Bus error";
780 #endif
781 #ifdef SIGFPE
782     case SIGFPE: return "Floating point exception";
783 #endif
784 #ifdef SIGKILL
785     case SIGKILL: return "Killed";
786 #endif
787 #ifdef SIGUSR1
788     case SIGUSR1: return "User defined signal 1";
789 #endif
790 #ifdef SIGSEGV
791     case SIGSEGV: return "Segmentation fault";
792 #endif
793 #ifdef SIGUSR2
794     case SIGUSR2: return "User defined signal 2";
795 #endif
796 #ifdef SIGPIPE
797     case SIGPIPE: return "Broken pipe";
798 #endif
799 #ifdef SIGALRM
800     case SIGALRM: return "Alarm clock";
801 #endif
802 #ifdef SIGTERM
803     case SIGTERM: return "Terminated";
804 #endif
805 #ifdef SIGSTKFLT
806     case SIGSTKFLT: return "Stack fault";
807 #endif
808 #ifdef SIGCHLD
809     case SIGCHLD: return "Child exited";
810 #endif
811 #ifdef SIGCONT
812     case SIGCONT: return "Continued";
813 #endif
814 #ifdef SIGSTOP
815     case SIGSTOP: return "Stopped (signal)";
816 #endif
817 #ifdef SIGTSTP
818     case SIGTSTP: return "Stopped";
819 #endif
820 #ifdef SIGTTIN
821     case SIGTTIN: return "Stopped (tty input)";
822 #endif
823 #ifdef SIGTTOU
824     case SIGTTOU: return "Stopped (tty output)";
825 #endif
826 #ifdef SIGURG
827     case SIGURG: return "Urgent condition";
828 #endif
829 #ifdef SIGXCPU
830     case SIGXCPU: return "CPU time limit exceeded";
831 #endif
832 #ifdef SIGXFSZ
833     case SIGXFSZ: return "File size limit exceeded";
834 #endif
835 #ifdef SIGVTALRM
836     case SIGVTALRM: return "Virtual time alarm";
837 #endif
838 #ifdef SIGPROF
839     case SIGPROF: return "Profile signal";
840 #endif
841 #ifdef SIGWINCH
842     case SIGWINCH: return "Window size changed";
843 #endif
844 #ifdef SIGIO
845     case SIGIO: return "Possible I/O";
846 #endif
847 #ifdef SIGPWR
848     case SIGPWR: return "Power failure";
849 #endif
850 #ifdef SIGUNUSED
851     case SIGUNUSED: return "Unused signal";
852 #endif
853     }
854 #else /* NO_SYS_SIGLIST */
855
856 #ifdef NO_SYS_SIGLIST_DECL
857   extern char *sys_siglist[];   /*(see Tue Jan 19 00:44:24 1999 in changelog)*/
858 #endif
859
860   return (char*) /* this function should return const --josh */ sys_siglist [signum];
861 #endif /* NO_SYS_SIGLIST */
862
863   msg = g_static_private_get (&msg_private);
864   if (!msg)
865     {
866       msg = g_new (gchar, 64);
867       g_static_private_set (&msg_private, msg, g_free);
868     }
869
870   sprintf (msg, "unknown signal (%d)", signum);
871   
872   return msg;
873 }
874
875 /* Functions g_strlcpy and g_strlcat were originally developed by
876  * Todd C. Miller <Todd.Miller@courtesan.com> to simplify writing secure code.
877  * See ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3
878  * for more information.
879  */
880
881 #ifdef HAVE_STRLCPY
882 /* Use the native ones, if available; they might be implemented in assembly */
883 gsize
884 g_strlcpy (gchar       *dest,
885            const gchar *src,
886            gsize        dest_size)
887 {
888   g_return_val_if_fail (dest != NULL, 0);
889   g_return_val_if_fail (src  != NULL, 0);
890   
891   return strlcpy (dest, src, dest_size);
892 }
893
894 gsize
895 g_strlcat (gchar       *dest,
896            const gchar *src,
897            gsize        dest_size)
898 {
899   g_return_val_if_fail (dest != NULL, 0);
900   g_return_val_if_fail (src  != NULL, 0);
901   
902   return strlcat (dest, src, dest_size);
903 }
904
905 #else /* ! HAVE_STRLCPY */
906 /* g_strlcpy
907  *
908  * Copy string src to buffer dest (of buffer size dest_size).  At most
909  * dest_size-1 characters will be copied.  Always NUL terminates
910  * (unless dest_size == 0).  This function does NOT allocate memory.
911  * Unlike strncpy, this function doesn't pad dest (so it's often faster).
912  * Returns size of attempted result, strlen(src),
913  * so if retval >= dest_size, truncation occurred.
914  */
915 gsize
916 g_strlcpy (gchar       *dest,
917            const gchar *src,
918            gsize        dest_size)
919 {
920   register gchar *d = dest;
921   register const gchar *s = src;
922   register gsize n = dest_size;
923   
924   g_return_val_if_fail (dest != NULL, 0);
925   g_return_val_if_fail (src  != NULL, 0);
926   
927   /* Copy as many bytes as will fit */
928   if (n != 0 && --n != 0)
929     do
930       {
931         register gchar c = *s++;
932         
933         *d++ = c;
934         if (c == 0)
935           break;
936       }
937     while (--n != 0);
938   
939   /* If not enough room in dest, add NUL and traverse rest of src */
940   if (n == 0)
941     {
942       if (dest_size != 0)
943         *d = 0;
944       while (*s++)
945         ;
946     }
947   
948   return s - src - 1;  /* count does not include NUL */
949 }
950
951 /* g_strlcat
952  *
953  * Appends string src to buffer dest (of buffer size dest_size).
954  * At most dest_size-1 characters will be copied.
955  * Unlike strncat, dest_size is the full size of dest, not the space left over.
956  * This function does NOT allocate memory.
957  * This always NUL terminates (unless siz == 0 or there were no NUL characters
958  * in the dest_size characters of dest to start with).
959  * Returns size of attempted result, which is
960  * MIN (dest_size, strlen (original dest)) + strlen (src),
961  * so if retval >= dest_size, truncation occurred.
962  */
963 gsize
964 g_strlcat (gchar       *dest,
965            const gchar *src,
966            gsize        dest_size)
967 {
968   register gchar *d = dest;
969   register const gchar *s = src;
970   register gsize bytes_left = dest_size;
971   gsize dlength;  /* Logically, MIN (strlen (d), dest_size) */
972   
973   g_return_val_if_fail (dest != NULL, 0);
974   g_return_val_if_fail (src  != NULL, 0);
975   
976   /* Find the end of dst and adjust bytes left but don't go past end */
977   while (*d != 0 && bytes_left-- != 0)
978     d++;
979   dlength = d - dest;
980   bytes_left = dest_size - dlength;
981   
982   if (bytes_left == 0)
983     return dlength + strlen (s);
984   
985   while (*s != 0)
986     {
987       if (bytes_left != 1)
988         {
989           *d++ = *s;
990           bytes_left--;
991         }
992       s++;
993     }
994   *d = 0;
995   
996   return dlength + (s - src);  /* count does not include NUL */
997 }
998 #endif /* ! HAVE_STRLCPY */
999
1000 /**
1001  * g_ascii_strdown:
1002  * @string: a string
1003  * 
1004  * Converts all upper case ASCII letters to lower case ASCII letters.
1005  * 
1006  * Return value: a newly allocated string, with all the upper case
1007  *               characters in @string converted to lower case, with
1008  *               semantics that exactly match g_ascii_tolower. (Note
1009  *               that this is unlike the old g_strdown, which modified
1010  *               the string in place.)
1011  **/
1012 gchar*
1013 g_ascii_strdown (const gchar *string)
1014 {
1015   gchar *result, *s;
1016   
1017   g_return_val_if_fail (string != NULL, NULL);
1018
1019   result = g_strdup (string);
1020   for (s = result; *s; s++)
1021     *s = g_ascii_tolower (*s);
1022   
1023   return result;
1024 }
1025
1026 /**
1027  * g_ascii_strup:
1028  * @string: a string
1029  * 
1030  * Converts all lower case ASCII letters to upper case ASCII letters.
1031  * 
1032  * Return value: a newly allocated string, with all the lower case
1033  *               characters in @string converted to upper case, with
1034  *               semantics that exactly match g_ascii_toupper. (Note
1035  *               that this is unlike the old g_strup, which modified
1036  *               the string in place.)
1037  **/
1038 gchar*
1039 g_ascii_strup (const gchar *string)
1040 {
1041   gchar *result, *s;
1042
1043   g_return_val_if_fail (string != NULL, NULL);
1044
1045   result = g_strdup (string);
1046   for (s = result; *s; s++)
1047     *s = g_ascii_toupper (*s);
1048
1049   return result;
1050 }
1051
1052 gchar*
1053 g_strdown (gchar *string)
1054 {
1055   register guchar *s;
1056   
1057   g_return_val_if_fail (string != NULL, NULL);
1058   
1059   s = (guchar *) string;
1060   
1061   while (*s)
1062     {
1063       if (isupper (*s))
1064         *s = tolower (*s);
1065       s++;
1066     }
1067   
1068   return (gchar *) string;
1069 }
1070
1071 gchar*
1072 g_strup (gchar *string)
1073 {
1074   register guchar *s;
1075
1076   g_return_val_if_fail (string != NULL, NULL);
1077
1078   s = (guchar *) string;
1079
1080   while (*s)
1081     {
1082       if (islower (*s))
1083         *s = toupper (*s);
1084       s++;
1085     }
1086
1087   return (gchar *) string;
1088 }
1089
1090 gchar*
1091 g_strreverse (gchar *string)
1092 {
1093   g_return_val_if_fail (string != NULL, NULL);
1094
1095   if (*string)
1096     {
1097       register gchar *h, *t;
1098
1099       h = string;
1100       t = string + strlen (string) - 1;
1101
1102       while (h < t)
1103         {
1104           register gchar c;
1105
1106           c = *h;
1107           *h = *t;
1108           h++;
1109           *t = c;
1110           t--;
1111         }
1112     }
1113
1114   return string;
1115 }
1116
1117 /**
1118  * g_ascii_tolower:
1119  * @c: any character
1120  * 
1121  * Convert a character to ASCII lower case.
1122  *
1123  * Unlike the standard C library tolower function, this only
1124  * recognizes standard ASCII letters and ignores the locale, returning
1125  * all non-ASCII characters unchanged, even if they are lower case
1126  * letters in a particular character set. Also unlike the standard
1127  * library function, this takes and returns a char, not an int, so
1128  * don't call it on EOF but no need to worry about casting to guchar
1129  * before passing a possibly non-ASCII character in.
1130  * 
1131  * Return value: the result of converting @c to lower case.
1132  *               If @c is not an ASCII upper case letter,
1133  *               @c is returned unchanged.
1134  **/
1135 gchar
1136 g_ascii_tolower (gchar c)
1137 {
1138   return g_ascii_isupper (c) ? c - 'A' + 'a' : c;
1139 }
1140
1141 /**
1142  * g_ascii_toupper:
1143  * @c: any character
1144  * 
1145  * Convert a character to ASCII upper case.
1146  *
1147  * Unlike the standard C library toupper function, this only
1148  * recognizes standard ASCII letters and ignores the locale, returning
1149  * all non-ASCII characters unchanged, even if they are upper case
1150  * letters in a particular character set. Also unlike the standard
1151  * library function, this takes and returns a char, not an int, so
1152  * don't call it on EOF but no need to worry about casting to guchar
1153  * before passing a possibly non-ASCII character in.
1154  * 
1155  * Return value: the result of converting @c to upper case.
1156  *               If @c is not an ASCII lower case letter,
1157  *               @c is returned unchanged.
1158  **/
1159 gchar
1160 g_ascii_toupper (gchar c)
1161 {
1162   return g_ascii_islower (c) ? c - 'a' + 'A' : c;
1163 }
1164
1165 /**
1166  * g_ascii_digit_value:
1167  * @c: an ASCII character
1168  *
1169  * Determines the numeric value of a character as a decimal
1170  * digit. Differs from g_unichar_digit_value because it takes
1171  * a char, so there's no worry about sign extension if characters
1172  * are signed.
1173  *
1174  * Return value: If @c is a decimal digit (according to
1175  * `g_ascii_isdigit'), its numeric value. Otherwise, -1.
1176  **/
1177 int
1178 g_ascii_digit_value (gchar c)
1179 {
1180   if (g_ascii_isdigit (c))
1181     return c - '0';
1182   return -1;
1183 }
1184
1185 /**
1186  * g_ascii_xdigit_value:
1187  * @c: an ASCII character
1188  *
1189  * Determines the numeric value of a character as a hexidecimal
1190  * digit. Differs from g_unichar_xdigit_value because it takes
1191  * a char, so there's no worry about sign extension if characters
1192  * are signed.
1193  *
1194  * Return value: If @c is a hex digit (according to
1195  * `g_ascii_isxdigit'), its numeric value. Otherwise, -1.
1196  **/
1197 int
1198 g_ascii_xdigit_value (gchar c)
1199 {
1200   if (c >= 'A' && c <= 'F')
1201     return c - 'A' + 10;
1202   if (c >= 'a' && c <= 'f')
1203     return c - 'a' + 10;
1204   return g_ascii_digit_value (c);
1205 }
1206
1207 /**
1208  * g_ascii_strcasecmp:
1209  * @s1: string to compare with @s2
1210  * @s2: string to compare with @s1
1211  * 
1212  * Compare two strings, ignoring the case of ASCII characters.
1213  *
1214  * Unlike the BSD strcasecmp function, this only recognizes standard
1215  * ASCII letters and ignores the locale, treating all non-ASCII
1216  * characters as if they are not letters.
1217  * 
1218  * Return value: an integer less than, equal to, or greater than
1219  *               zero if @s1 is found, respectively, to be less than,
1220  *               to match, or to be greater than @s2.
1221  **/
1222 gint
1223 g_ascii_strcasecmp (const gchar *s1,
1224                     const gchar *s2)
1225 {
1226   gint c1, c2;
1227
1228   g_return_val_if_fail (s1 != NULL, 0);
1229   g_return_val_if_fail (s2 != NULL, 0);
1230
1231   while (*s1 && *s2)
1232     {
1233       c1 = (gint)(guchar) g_ascii_tolower (*s1);
1234       c2 = (gint)(guchar) g_ascii_tolower (*s2);
1235       if (c1 != c2)
1236         return (c1 - c2);
1237       s1++; s2++;
1238     }
1239
1240   return (((gint)(guchar) *s1) - ((gint)(guchar) *s2));
1241 }
1242
1243 /**
1244  * g_ascii_strncasecmp:
1245  * @s1: string to compare with @s2
1246  * @s2: string to compare with @s1
1247  * @n:  number of characters to compare
1248  * 
1249  * Compare @s1 and @s2, ignoring the case of ASCII characters and any
1250  * characters after the first @n in each string.
1251  *
1252  * Unlike the BSD strcasecmp function, this only recognizes standard
1253  * ASCII letters and ignores the locale, treating all non-ASCII
1254  * characters as if they are not letters.
1255  * 
1256  * Return value: an integer less than, equal to, or greater than zero
1257  *               if the first @n bytes of @s1 is found, respectively,
1258  *               to be less than, to match, or to be greater than the
1259  *               first @n bytes of @s2.
1260  **/
1261 gint
1262 g_ascii_strncasecmp (const gchar *s1,
1263                      const gchar *s2,
1264                      guint n)
1265 {
1266   gint c1, c2;
1267
1268   g_return_val_if_fail (s1 != NULL, 0);
1269   g_return_val_if_fail (s2 != NULL, 0);
1270
1271   while (n && *s1 && *s2)
1272     {
1273       n -= 1;
1274       c1 = (gint)(guchar) g_ascii_tolower (*s1);
1275       c2 = (gint)(guchar) g_ascii_tolower (*s2);
1276       if (c1 != c2)
1277         return (c1 - c2);
1278       s1++; s2++;
1279     }
1280
1281   if (n)
1282     return (((gint) (guchar) *s1) - ((gint) (guchar) *s2));
1283   else
1284     return 0;
1285 }
1286
1287 gint
1288 g_strcasecmp (const gchar *s1,
1289               const gchar *s2)
1290 {
1291 #ifdef HAVE_STRCASECMP
1292   g_return_val_if_fail (s1 != NULL, 0);
1293   g_return_val_if_fail (s2 != NULL, 0);
1294
1295   return strcasecmp (s1, s2);
1296 #else
1297   gint c1, c2;
1298
1299   g_return_val_if_fail (s1 != NULL, 0);
1300   g_return_val_if_fail (s2 != NULL, 0);
1301
1302   while (*s1 && *s2)
1303     {
1304       /* According to A. Cox, some platforms have islower's that
1305        * don't work right on non-uppercase
1306        */
1307       c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1;
1308       c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2;
1309       if (c1 != c2)
1310         return (c1 - c2);
1311       s1++; s2++;
1312     }
1313
1314   return (((gint)(guchar) *s1) - ((gint)(guchar) *s2));
1315 #endif
1316 }
1317
1318 gint
1319 g_strncasecmp (const gchar *s1,
1320                const gchar *s2,
1321                gsize n)     
1322 {
1323 #ifdef HAVE_STRNCASECMP
1324   return strncasecmp (s1, s2, n);
1325 #else
1326   gint c1, c2;
1327
1328   g_return_val_if_fail (s1 != NULL, 0);
1329   g_return_val_if_fail (s2 != NULL, 0);
1330
1331   while (n && *s1 && *s2)
1332     {
1333       n -= 1;
1334       /* According to A. Cox, some platforms have islower's that
1335        * don't work right on non-uppercase
1336        */
1337       c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1;
1338       c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2;
1339       if (c1 != c2)
1340         return (c1 - c2);
1341       s1++; s2++;
1342     }
1343
1344   if (n)
1345     return (((gint) (guchar) *s1) - ((gint) (guchar) *s2));
1346   else
1347     return 0;
1348 #endif
1349 }
1350
1351 gchar*
1352 g_strdelimit (gchar       *string,
1353               const gchar *delimiters,
1354               gchar        new_delim)
1355 {
1356   register gchar *c;
1357
1358   g_return_val_if_fail (string != NULL, NULL);
1359
1360   if (!delimiters)
1361     delimiters = G_STR_DELIMITERS;
1362
1363   for (c = string; *c; c++)
1364     {
1365       if (strchr (delimiters, *c))
1366         *c = new_delim;
1367     }
1368
1369   return string;
1370 }
1371
1372 gchar*
1373 g_strcanon (gchar       *string,
1374             const gchar *valid_chars,
1375             gchar        substitutor)
1376 {
1377   register gchar *c;
1378
1379   g_return_val_if_fail (string != NULL, NULL);
1380   g_return_val_if_fail (valid_chars != NULL, NULL);
1381
1382   for (c = string; *c; c++)
1383     {
1384       if (!strchr (valid_chars, *c))
1385         *c = substitutor;
1386     }
1387
1388   return string;
1389 }
1390
1391 gchar*
1392 g_strcompress (const gchar *source)
1393 {
1394   const gchar *p = source, *octal;
1395   gchar *dest = g_malloc (strlen (source) + 1);
1396   gchar *q = dest;
1397   
1398   while (*p)
1399     {
1400       if (*p == '\\')
1401         {
1402           p++;
1403           switch (*p)
1404             {
1405             case '0':  case '1':  case '2':  case '3':  case '4':
1406             case '5':  case '6':  case '7':
1407               *q = 0;
1408               octal = p;
1409               while ((p < octal + 3) && (*p >= '0') && (*p <= '7'))
1410                 {
1411                   *q = (*q * 8) + (*p - '0');
1412                   p++;
1413                 }
1414               q++;
1415               p--;
1416               break;
1417             case 'b':
1418               *q++ = '\b';
1419               break;
1420             case 'f':
1421               *q++ = '\f';
1422               break;
1423             case 'n':
1424               *q++ = '\n';
1425               break;
1426             case 'r':
1427               *q++ = '\r';
1428               break;
1429             case 't':
1430               *q++ = '\t';
1431               break;
1432             default:            /* Also handles \" and \\ */
1433               *q++ = *p;
1434               break;
1435             }
1436         }
1437       else
1438         *q++ = *p;
1439       p++;
1440     }
1441   *q = 0;
1442   
1443   return dest;
1444 }
1445
1446 gchar *
1447 g_strescape (const gchar *source,
1448              const gchar *exceptions)
1449 {
1450   const guchar *p;
1451   gchar *dest;
1452   gchar *q;
1453   guchar excmap[256];
1454   
1455   g_return_val_if_fail (source != NULL, NULL);
1456
1457   p = (guchar *) source;
1458   /* Each source byte needs maximally four destination chars (\777) */
1459   q = dest = g_malloc (strlen (source) * 4 + 1);
1460
1461   memset (excmap, 0, 256);
1462   if (exceptions)
1463     {
1464       guchar *e = (guchar *) exceptions;
1465
1466       while (*e)
1467         {
1468           excmap[*e] = 1;
1469           e++;
1470         }
1471     }
1472
1473   while (*p)
1474     {
1475       if (excmap[*p])
1476         *q++ = *p;
1477       else
1478         {
1479           switch (*p)
1480             {
1481             case '\b':
1482               *q++ = '\\';
1483               *q++ = 'b';
1484               break;
1485             case '\f':
1486               *q++ = '\\';
1487               *q++ = 'f';
1488               break;
1489             case '\n':
1490               *q++ = '\\';
1491               *q++ = 'n';
1492               break;
1493             case '\r':
1494               *q++ = '\\';
1495               *q++ = 'r';
1496               break;
1497             case '\t':
1498               *q++ = '\\';
1499               *q++ = 't';
1500               break;
1501             case '\\':
1502               *q++ = '\\';
1503               *q++ = '\\';
1504               break;
1505             case '"':
1506               *q++ = '\\';
1507               *q++ = '"';
1508               break;
1509             default:
1510               if ((*p < ' ') || (*p >= 0177))
1511                 {
1512                   *q++ = '\\';
1513                   *q++ = '0' + (((*p) >> 6) & 07);
1514                   *q++ = '0' + (((*p) >> 3) & 07);
1515                   *q++ = '0' + ((*p) & 07);
1516                 }
1517               else
1518                 *q++ = *p;
1519               break;
1520             }
1521         }
1522       p++;
1523     }
1524   *q = 0;
1525   return dest;
1526 }
1527
1528 gchar*
1529 g_strchug (gchar *string)
1530 {
1531   guchar *start;
1532
1533   g_return_val_if_fail (string != NULL, NULL);
1534
1535   for (start = (guchar*) string; *start && g_ascii_isspace (*start); start++)
1536     ;
1537
1538   g_memmove (string, start, strlen ((gchar *) start) + 1);
1539
1540   return string;
1541 }
1542
1543 gchar*
1544 g_strchomp (gchar *string)
1545 {
1546   gchar *s;
1547
1548   g_return_val_if_fail (string != NULL, NULL);
1549
1550   if (!*string)
1551     return string;
1552
1553   for (s = string + strlen (string) - 1; s >= string && g_ascii_isspace ((guchar)*s); 
1554        s--)
1555     *s = '\0';
1556
1557   return string;
1558 }
1559
1560 /**
1561  * g_strsplit:
1562  * @string: a string to split.
1563  * @delimiter: a string which specifies the places at which to split the string.
1564  *     The delimiter is not included in any of the resulting strings, unless
1565  *     max_tokens is reached.
1566  * @max_tokens: the maximum number of pieces to split @string into. If this is
1567  *              less than 1, the string is split completely.
1568  * 
1569  * Splits a string into a maximum of @max_tokens pieces, using the given
1570  * @delimiter. If @max_tokens is reached, the remainder of @string is appended
1571  * to the last token. 
1572  *
1573  * As a special case, the result of splitting the empty string "" is an empty
1574  * vector, not a vector containing a single string. The reason for this
1575  * special case is that being able to represent a empty vector is typically
1576  * more useful than consistent handling of empty elements. If you do need
1577  * to represent empty elements, you'll need to check for the empty string
1578  * before calling g_strsplit().
1579  * 
1580  * Return value: a newly-allocated %NULL-terminated array of strings. Use g_strfreev()
1581  *    to free it.
1582  **/
1583 gchar**
1584 g_strsplit (const gchar *string,
1585             const gchar *delimiter,
1586             gint         max_tokens)
1587 {
1588   GSList *string_list = NULL, *slist;
1589   gchar **str_array, *s;
1590   guint n = 0;
1591   const gchar *remainder;
1592
1593   g_return_val_if_fail (string != NULL, NULL);
1594   g_return_val_if_fail (delimiter != NULL, NULL);
1595   g_return_val_if_fail (delimiter[0] != '\0', NULL);
1596
1597   if (max_tokens < 1)
1598     max_tokens = G_MAXINT;
1599   else
1600     --max_tokens;
1601
1602   remainder = string;
1603   s = strstr (remainder, delimiter);
1604   if (s)
1605     {
1606       gsize delimiter_len = strlen (delimiter);   
1607
1608       do
1609         {
1610           gsize len;     
1611           gchar *new_string;
1612
1613           len = s - remainder;
1614           new_string = g_new (gchar, len + 1);
1615           strncpy (new_string, remainder, len);
1616           new_string[len] = 0;
1617           string_list = g_slist_prepend (string_list, new_string);
1618           n++;
1619           remainder = s + delimiter_len;
1620           s = strstr (remainder, delimiter);
1621         }
1622       while (--max_tokens && s);
1623     }
1624   if (*string)
1625     {
1626       n++;
1627       string_list = g_slist_prepend (string_list, g_strdup (remainder));
1628     }
1629
1630   str_array = g_new (gchar*, n + 1);
1631
1632   str_array[n--] = NULL;
1633   for (slist = string_list; slist; slist = slist->next)
1634     str_array[n--] = slist->data;
1635
1636   g_slist_free (string_list);
1637
1638   return str_array;
1639 }
1640
1641 void
1642 g_strfreev (gchar **str_array)
1643 {
1644   if (str_array)
1645     {
1646       int i;
1647
1648       for(i = 0; str_array[i] != NULL; i++)
1649         g_free(str_array[i]);
1650
1651       g_free (str_array);
1652     }
1653 }
1654
1655 /**
1656  * g_strdupv:
1657  * @str_array: %NULL-terminated array of strings
1658  * 
1659  * Copies %NULL-terminated array of strings. The copy is a deep copy;
1660  * the new array should be freed by first freeing each string, then
1661  * the array itself. g_strfreev() does this for you. If called
1662  * on a %NULL value, g_strdupv() simply returns %NULL.
1663  * 
1664  * Return value: a new %NULL-terminated array of strings
1665  **/
1666 gchar**
1667 g_strdupv (gchar **str_array)
1668 {
1669   if (str_array)
1670     {
1671       gint i;
1672       gchar **retval;
1673
1674       i = 0;
1675       while (str_array[i])
1676         ++i;
1677           
1678       retval = g_new (gchar*, i + 1);
1679
1680       i = 0;
1681       while (str_array[i])
1682         {
1683           retval[i] = g_strdup (str_array[i]);
1684           ++i;
1685         }
1686       retval[i] = NULL;
1687
1688       return retval;
1689     }
1690   else
1691     return NULL;
1692 }
1693
1694 gchar*
1695 g_strjoinv (const gchar  *separator,
1696             gchar       **str_array)
1697 {
1698   gchar *string;
1699   gchar *ptr;
1700
1701   g_return_val_if_fail (str_array != NULL, NULL);
1702
1703   if (separator == NULL)
1704     separator = "";
1705
1706   if (*str_array)
1707     {
1708       gint i;
1709       gsize len;
1710       gsize separator_len;     
1711
1712       separator_len = strlen (separator);
1713       /* First part, getting length */
1714       len = 1 + strlen (str_array[0]);
1715       for (i = 1; str_array[i] != NULL; i++)
1716         len += strlen (str_array[i]);
1717       len += separator_len * (i - 1);
1718
1719       /* Second part, building string */
1720       string = g_new (gchar, len);
1721       ptr = g_stpcpy (string, *str_array);
1722       for (i = 1; str_array[i] != NULL; i++)
1723         {
1724           ptr = g_stpcpy (ptr, separator);
1725           ptr = g_stpcpy (ptr, str_array[i]);
1726         }
1727       }
1728   else
1729     string = g_strdup ("");
1730
1731   return string;
1732 }
1733
1734 gchar*
1735 g_strjoin (const gchar  *separator,
1736            ...)
1737 {
1738   gchar *string, *s;
1739   va_list args;
1740   gsize len;               
1741   gsize separator_len;     
1742   gchar *ptr;
1743
1744   if (separator == NULL)
1745     separator = "";
1746
1747   separator_len = strlen (separator);
1748
1749   va_start (args, separator);
1750
1751   s = va_arg (args, gchar*);
1752
1753   if (s)
1754     {
1755       /* First part, getting length */
1756       len = 1 + strlen (s);
1757
1758       s = va_arg (args, gchar*);
1759       while (s)
1760         {
1761           len += separator_len + strlen (s);
1762           s = va_arg (args, gchar*);
1763         }
1764       va_end (args);
1765
1766       /* Second part, building string */
1767       string = g_new (gchar, len);
1768
1769       va_start (args, separator);
1770
1771       s = va_arg (args, gchar*);
1772       ptr = g_stpcpy (string, s);
1773
1774       s = va_arg (args, gchar*);
1775       while (s)
1776         {
1777           ptr = g_stpcpy (ptr, separator);
1778           ptr = g_stpcpy (ptr, s);
1779           s = va_arg (args, gchar*);
1780         }
1781     }
1782   else
1783     string = g_strdup ("");
1784
1785   va_end (args);
1786
1787   return string;
1788 }
1789
1790
1791 /**
1792  * g_strstr_len:
1793  * @haystack: a string
1794  * @haystack_len: The maximum length of haystack
1795  * @needle: The string to search for.
1796  *
1797  * Searches the string haystack for the first occurrence
1798  * of the string needle, limiting the length of the search
1799  * to haystack_len. 
1800  *
1801  * Return value: A pointer to the found occurrence, or
1802  * NULL if not found.
1803  **/
1804 gchar *
1805 g_strstr_len (const gchar *haystack,
1806               gssize       haystack_len,
1807               const gchar *needle)
1808 {
1809   g_return_val_if_fail (haystack != NULL, NULL);
1810   g_return_val_if_fail (needle != NULL, NULL);
1811   
1812   if (haystack_len < 0)
1813     return strstr (haystack, needle);
1814   else
1815     {
1816       const gchar *p = haystack;
1817       gsize needle_len = strlen (needle);
1818       const gchar *end;
1819       gsize i;
1820
1821       if (needle_len == 0)
1822         return (gchar *)haystack;
1823
1824       if (haystack_len < needle_len)
1825         return NULL;
1826       
1827       end = haystack + haystack_len - needle_len;
1828       
1829       while (*p && p <= end)
1830         {
1831           for (i = 0; i < needle_len; i++)
1832             if (p[i] != needle[i])
1833               goto next;
1834           
1835           return (gchar *)p;
1836           
1837         next:
1838           p++;
1839         }
1840       
1841       return NULL;
1842     }
1843 }
1844
1845 /**
1846  * g_strrstr_len:
1847  * @haystack: a nul-terminated string
1848  * @needle: The nul-terminated string to search for.
1849  *
1850  * Searches the string haystack for the last occurrence
1851  * of the string needle.
1852  *
1853  * Return value: A pointer to the found occurrence, or
1854  * NULL if not found.
1855  **/
1856 gchar *
1857 g_strrstr (const gchar *haystack,
1858            const gchar *needle)
1859 {
1860   gsize i;
1861   gsize needle_len;
1862   gsize haystack_len;
1863   const gchar *p;
1864       
1865   g_return_val_if_fail (haystack != NULL, NULL);
1866   g_return_val_if_fail (needle != NULL, NULL);
1867
1868   needle_len = strlen (needle);
1869   haystack_len = strlen (haystack);
1870
1871   if (needle_len == 0)
1872     return (gchar *)haystack;
1873
1874   if (haystack_len < needle_len)
1875     return NULL;
1876   
1877   p = haystack + haystack_len - needle_len;
1878
1879   while (p >= haystack)
1880     {
1881       for (i = 0; i < needle_len; i++)
1882         if (p[i] != needle[i])
1883           goto next;
1884       
1885       return (gchar *)p;
1886       
1887     next:
1888       p--;
1889     }
1890   
1891   return NULL;
1892 }
1893
1894 /**
1895  * g_strrstr_len:
1896  * @haystack: a nul-terminated string
1897  * @haystack_len: The maximum length of haystack
1898  * @needle: The nul-terminated string to search for.
1899  *
1900  * Searches the string haystack for the last occurrence
1901  * of the string needle, limiting the length of the search
1902  * to haystack_len. 
1903  *
1904  * Return value: A pointer to the found occurrence, or
1905  * NULL if not found.
1906  **/
1907 gchar *
1908 g_strrstr_len (const gchar *haystack,
1909                gssize        haystack_len,
1910                const gchar *needle)
1911 {
1912   g_return_val_if_fail (haystack != NULL, NULL);
1913   g_return_val_if_fail (needle != NULL, NULL);
1914   
1915   if (haystack_len < 0)
1916     return g_strrstr (haystack, needle);
1917   else
1918     {
1919       gsize needle_len = strlen (needle);
1920       const gchar *haystack_max = haystack + haystack_len;
1921       const gchar *p = haystack;
1922       gsize i;
1923
1924       while (p < haystack_max && *p)
1925         p++;
1926
1927       if (p < haystack + needle_len)
1928         return NULL;
1929         
1930       p -= needle_len;
1931
1932       while (p >= haystack)
1933         {
1934           for (i = 0; i < needle_len; i++)
1935             if (p[i] != needle[i])
1936               goto next;
1937           
1938           return (gchar *)p;
1939           
1940         next:
1941           p--;
1942         }
1943
1944       return NULL;
1945     }
1946 }
1947
1948