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