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