applied patch from Andreas Persenius <ndap@swipnet.se> that updates the
[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 #include <stdarg.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <locale.h>
40 #include <ctype.h>              /* For tolower() */
41 #if !defined (HAVE_STRSIGNAL) || !defined(NO_SYS_SIGLIST_DECL)
42 #include <signal.h>
43 #endif
44 #include "glib.h"
45
46 #ifdef G_OS_WIN32
47 #include <windows.h>
48 #endif
49
50 /* do not include <unistd.h> in this place since it
51  * inteferes with g_strsignal() on some OSes
52  */
53
54 gchar*
55 g_strdup (const gchar *str)
56 {
57   gchar *new_str;
58
59   if (str)
60     {
61       new_str = g_new (char, strlen (str) + 1);
62       strcpy (new_str, str);
63     }
64   else
65     new_str = NULL;
66
67   return new_str;
68 }
69
70 gpointer
71 g_memdup (gconstpointer mem,
72           guint         byte_size)
73 {
74   gpointer new_mem;
75
76   if (mem)
77     {
78       new_mem = g_malloc (byte_size);
79       memcpy (new_mem, mem, byte_size);
80     }
81   else
82     new_mem = NULL;
83
84   return new_mem;
85 }
86
87 gchar*
88 g_strndup (const gchar *str,
89            guint        n)
90 {
91   gchar *new_str;
92
93   if (str)
94     {
95       new_str = g_new (gchar, n + 1);
96       strncpy (new_str, str, n);
97       new_str[n] = '\0';
98     }
99   else
100     new_str = NULL;
101
102   return new_str;
103 }
104
105 gchar*
106 g_strnfill (guint length,
107             gchar fill_char)
108 {
109   register gchar *str, *s, *end;
110
111   str = g_new (gchar, length + 1);
112   s = str;
113   end = str + length;
114   while (s < end)
115     *(s++) = fill_char;
116   *s = 0;
117
118   return str;
119 }
120
121 gchar*
122 g_strdup_vprintf (const gchar *format,
123                   va_list      args1)
124 {
125   gchar *buffer;
126   va_list args2;
127
128   G_VA_COPY (args2, args1);
129
130   buffer = g_new (gchar, g_printf_string_upper_bound (format, args1));
131
132   vsprintf (buffer, format, args2);
133   va_end (args2);
134
135   return buffer;
136 }
137
138 gchar*
139 g_strdup_printf (const gchar *format,
140                  ...)
141 {
142   gchar *buffer;
143   va_list args;
144
145   va_start (args, format);
146   buffer = g_strdup_vprintf (format, args);
147   va_end (args);
148
149   return buffer;
150 }
151
152 gchar*
153 g_strconcat (const gchar *string1, ...)
154 {
155   guint   l;
156   va_list args;
157   gchar   *s;
158   gchar   *concat;
159
160   g_return_val_if_fail (string1 != NULL, NULL);
161
162   l = 1 + strlen (string1);
163   va_start (args, string1);
164   s = va_arg (args, gchar*);
165   while (s)
166     {
167       l += strlen (s);
168       s = va_arg (args, gchar*);
169     }
170   va_end (args);
171
172   concat = g_new (gchar, l);
173   concat[0] = 0;
174
175   strcat (concat, string1);
176   va_start (args, string1);
177   s = va_arg (args, gchar*);
178   while (s)
179     {
180       strcat (concat, s);
181       s = va_arg (args, gchar*);
182     }
183   va_end (args);
184
185   return concat;
186 }
187
188 gdouble
189 g_strtod (const gchar *nptr,
190           gchar **endptr)
191 {
192   gchar *fail_pos_1;
193   gchar *fail_pos_2;
194   gdouble val_1;
195   gdouble val_2 = 0;
196
197   g_return_val_if_fail (nptr != NULL, 0);
198
199   fail_pos_1 = NULL;
200   fail_pos_2 = NULL;
201
202   val_1 = strtod (nptr, &fail_pos_1);
203
204   if (fail_pos_1 && fail_pos_1[0] != 0)
205     {
206       gchar *old_locale;
207
208       old_locale = g_strdup (setlocale (LC_NUMERIC, NULL));
209       setlocale (LC_NUMERIC, "C");
210       val_2 = strtod (nptr, &fail_pos_2);
211       setlocale (LC_NUMERIC, old_locale);
212       g_free (old_locale);
213     }
214
215   if (!fail_pos_1 || fail_pos_1[0] == 0 || fail_pos_1 >= fail_pos_2)
216     {
217       if (endptr)
218         *endptr = fail_pos_1;
219       return val_1;
220     }
221   else
222     {
223       if (endptr)
224         *endptr = fail_pos_2;
225       return val_2;
226     }
227 }
228
229 gchar*
230 g_strerror (gint errnum)
231 {
232   static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
233   char *msg;
234
235 #ifdef HAVE_STRERROR
236   return strerror (errnum);
237 #elif NO_SYS_ERRLIST
238   switch (errnum)
239     {
240 #ifdef E2BIG
241     case E2BIG: return "argument list too long";
242 #endif
243 #ifdef EACCES
244     case EACCES: return "permission denied";
245 #endif
246 #ifdef EADDRINUSE
247     case EADDRINUSE: return "address already in use";
248 #endif
249 #ifdef EADDRNOTAVAIL
250     case EADDRNOTAVAIL: return "can't assign requested address";
251 #endif
252 #ifdef EADV
253     case EADV: return "advertise error";
254 #endif
255 #ifdef EAFNOSUPPORT
256     case EAFNOSUPPORT: return "address family not supported by protocol family";
257 #endif
258 #ifdef EAGAIN
259     case EAGAIN: return "try again";
260 #endif
261 #ifdef EALIGN
262     case EALIGN: return "EALIGN";
263 #endif
264 #ifdef EALREADY
265     case EALREADY: return "operation already in progress";
266 #endif
267 #ifdef EBADE
268     case EBADE: return "bad exchange descriptor";
269 #endif
270 #ifdef EBADF
271     case EBADF: return "bad file number";
272 #endif
273 #ifdef EBADFD
274     case EBADFD: return "file descriptor in bad state";
275 #endif
276 #ifdef EBADMSG
277     case EBADMSG: return "not a data message";
278 #endif
279 #ifdef EBADR
280     case EBADR: return "bad request descriptor";
281 #endif
282 #ifdef EBADRPC
283     case EBADRPC: return "RPC structure is bad";
284 #endif
285 #ifdef EBADRQC
286     case EBADRQC: return "bad request code";
287 #endif
288 #ifdef EBADSLT
289     case EBADSLT: return "invalid slot";
290 #endif
291 #ifdef EBFONT
292     case EBFONT: return "bad font file format";
293 #endif
294 #ifdef EBUSY
295     case EBUSY: return "mount device busy";
296 #endif
297 #ifdef ECHILD
298     case ECHILD: return "no children";
299 #endif
300 #ifdef ECHRNG
301     case ECHRNG: return "channel number out of range";
302 #endif
303 #ifdef ECOMM
304     case ECOMM: return "communication error on send";
305 #endif
306 #ifdef ECONNABORTED
307     case ECONNABORTED: return "software caused connection abort";
308 #endif
309 #ifdef ECONNREFUSED
310     case ECONNREFUSED: return "connection refused";
311 #endif
312 #ifdef ECONNRESET
313     case ECONNRESET: return "connection reset by peer";
314 #endif
315 #if defined(EDEADLK) && (!defined(EWOULDBLOCK) || (EDEADLK != EWOULDBLOCK))
316     case EDEADLK: return "resource deadlock avoided";
317 #endif
318 #ifdef EDEADLOCK
319     case EDEADLOCK: return "resource deadlock avoided";
320 #endif
321 #ifdef EDESTADDRREQ
322     case EDESTADDRREQ: return "destination address required";
323 #endif
324 #ifdef EDIRTY
325     case EDIRTY: return "mounting a dirty fs w/o force";
326 #endif
327 #ifdef EDOM
328     case EDOM: return "math argument out of range";
329 #endif
330 #ifdef EDOTDOT
331     case EDOTDOT: return "cross mount point";
332 #endif
333 #ifdef EDQUOT
334     case EDQUOT: return "disk quota exceeded";
335 #endif
336 #ifdef EDUPPKG
337     case EDUPPKG: return "duplicate package name";
338 #endif
339 #ifdef EEXIST
340     case EEXIST: return "file already exists";
341 #endif
342 #ifdef EFAULT
343     case EFAULT: return "bad address in system call argument";
344 #endif
345 #ifdef EFBIG
346     case EFBIG: return "file too large";
347 #endif
348 #ifdef EHOSTDOWN
349     case EHOSTDOWN: return "host is down";
350 #endif
351 #ifdef EHOSTUNREACH
352     case EHOSTUNREACH: return "host is unreachable";
353 #endif
354 #ifdef EIDRM
355     case EIDRM: return "identifier removed";
356 #endif
357 #ifdef EINIT
358     case EINIT: return "initialization error";
359 #endif
360 #ifdef EINPROGRESS
361     case EINPROGRESS: return "operation now in progress";
362 #endif
363 #ifdef EINTR
364     case EINTR: return "interrupted system call";
365 #endif
366 #ifdef EINVAL
367     case EINVAL: return "invalid argument";
368 #endif
369 #ifdef EIO
370     case EIO: return "I/O error";
371 #endif
372 #ifdef EISCONN
373     case EISCONN: return "socket is already connected";
374 #endif
375 #ifdef EISDIR
376     case EISDIR: return "illegal operation on a directory";
377 #endif
378 #ifdef EISNAME
379     case EISNAM: return "is a name file";
380 #endif
381 #ifdef ELBIN
382     case ELBIN: return "ELBIN";
383 #endif
384 #ifdef EL2HLT
385     case EL2HLT: return "level 2 halted";
386 #endif
387 #ifdef EL2NSYNC
388     case EL2NSYNC: return "level 2 not synchronized";
389 #endif
390 #ifdef EL3HLT
391     case EL3HLT: return "level 3 halted";
392 #endif
393 #ifdef EL3RST
394     case EL3RST: return "level 3 reset";
395 #endif
396 #ifdef ELIBACC
397     case ELIBACC: return "can not access a needed shared library";
398 #endif
399 #ifdef ELIBBAD
400     case ELIBBAD: return "accessing a corrupted shared library";
401 #endif
402 #ifdef ELIBEXEC
403     case ELIBEXEC: return "can not exec a shared library directly";
404 #endif
405 #ifdef ELIBMAX
406     case ELIBMAX: return "attempting to link in more shared libraries than system limit";
407 #endif
408 #ifdef ELIBSCN
409     case ELIBSCN: return ".lib section in a.out corrupted";
410 #endif
411 #ifdef ELNRNG
412     case ELNRNG: return "link number out of range";
413 #endif
414 #ifdef ELOOP
415     case ELOOP: return "too many levels of symbolic links";
416 #endif
417 #ifdef EMFILE
418     case EMFILE: return "too many open files";
419 #endif
420 #ifdef EMLINK
421     case EMLINK: return "too many links";
422 #endif
423 #ifdef EMSGSIZE
424     case EMSGSIZE: return "message too long";
425 #endif
426 #ifdef EMULTIHOP
427     case EMULTIHOP: return "multihop attempted";
428 #endif
429 #ifdef ENAMETOOLONG
430     case ENAMETOOLONG: return "file name too long";
431 #endif
432 #ifdef ENAVAIL
433     case ENAVAIL: return "not available";
434 #endif
435 #ifdef ENET
436     case ENET: return "ENET";
437 #endif
438 #ifdef ENETDOWN
439     case ENETDOWN: return "network is down";
440 #endif
441 #ifdef ENETRESET
442     case ENETRESET: return "network dropped connection on reset";
443 #endif
444 #ifdef ENETUNREACH
445     case ENETUNREACH: return "network is unreachable";
446 #endif
447 #ifdef ENFILE
448     case ENFILE: return "file table overflow";
449 #endif
450 #ifdef ENOANO
451     case ENOANO: return "anode table overflow";
452 #endif
453 #if defined(ENOBUFS) && (!defined(ENOSR) || (ENOBUFS != ENOSR))
454     case ENOBUFS: return "no buffer space available";
455 #endif
456 #ifdef ENOCSI
457     case ENOCSI: return "no CSI structure available";
458 #endif
459 #ifdef ENODATA
460     case ENODATA: return "no data available";
461 #endif
462 #ifdef ENODEV
463     case ENODEV: return "no such device";
464 #endif
465 #ifdef ENOENT
466     case ENOENT: return "no such file or directory";
467 #endif
468 #ifdef ENOEXEC
469     case ENOEXEC: return "exec format error";
470 #endif
471 #ifdef ENOLCK
472     case ENOLCK: return "no locks available";
473 #endif
474 #ifdef ENOLINK
475     case ENOLINK: return "link has be severed";
476 #endif
477 #ifdef ENOMEM
478     case ENOMEM: return "not enough memory";
479 #endif
480 #ifdef ENOMSG
481     case ENOMSG: return "no message of desired type";
482 #endif
483 #ifdef ENONET
484     case ENONET: return "machine is not on the network";
485 #endif
486 #ifdef ENOPKG
487     case ENOPKG: return "package not installed";
488 #endif
489 #ifdef ENOPROTOOPT
490     case ENOPROTOOPT: return "bad proocol option";
491 #endif
492 #ifdef ENOSPC
493     case ENOSPC: return "no space left on device";
494 #endif
495 #ifdef ENOSR
496     case ENOSR: return "out of stream resources";
497 #endif
498 #ifdef ENOSTR
499     case ENOSTR: return "not a stream device";
500 #endif
501 #ifdef ENOSYM
502     case ENOSYM: return "unresolved symbol name";
503 #endif
504 #ifdef ENOSYS
505     case ENOSYS: return "function not implemented";
506 #endif
507 #ifdef ENOTBLK
508     case ENOTBLK: return "block device required";
509 #endif
510 #ifdef ENOTCONN
511     case ENOTCONN: return "socket is not connected";
512 #endif
513 #ifdef ENOTDIR
514     case ENOTDIR: return "not a directory";
515 #endif
516 #ifdef ENOTEMPTY
517     case ENOTEMPTY: return "directory not empty";
518 #endif
519 #ifdef ENOTNAM
520     case ENOTNAM: return "not a name file";
521 #endif
522 #ifdef ENOTSOCK
523     case ENOTSOCK: return "socket operation on non-socket";
524 #endif
525 #ifdef ENOTTY
526     case ENOTTY: return "inappropriate device for ioctl";
527 #endif
528 #ifdef ENOTUNIQ
529     case ENOTUNIQ: return "name not unique on network";
530 #endif
531 #ifdef ENXIO
532     case ENXIO: return "no such device or address";
533 #endif
534 #ifdef EOPNOTSUPP
535     case EOPNOTSUPP: return "operation not supported on socket";
536 #endif
537 #ifdef EPERM
538     case EPERM: return "not owner";
539 #endif
540 #ifdef EPFNOSUPPORT
541     case EPFNOSUPPORT: return "protocol family not supported";
542 #endif
543 #ifdef EPIPE
544     case EPIPE: return "broken pipe";
545 #endif
546 #ifdef EPROCLIM
547     case EPROCLIM: return "too many processes";
548 #endif
549 #ifdef EPROCUNAVAIL
550     case EPROCUNAVAIL: return "bad procedure for program";
551 #endif
552 #ifdef EPROGMISMATCH
553     case EPROGMISMATCH: return "program version wrong";
554 #endif
555 #ifdef EPROGUNAVAIL
556     case EPROGUNAVAIL: return "RPC program not available";
557 #endif
558 #ifdef EPROTO
559     case EPROTO: return "protocol error";
560 #endif
561 #ifdef EPROTONOSUPPORT
562     case EPROTONOSUPPORT: return "protocol not suppored";
563 #endif
564 #ifdef EPROTOTYPE
565     case EPROTOTYPE: return "protocol wrong type for socket";
566 #endif
567 #ifdef ERANGE
568     case ERANGE: return "math result unrepresentable";
569 #endif
570 #if defined(EREFUSED) && (!defined(ECONNREFUSED) || (EREFUSED != ECONNREFUSED))
571     case EREFUSED: return "EREFUSED";
572 #endif
573 #ifdef EREMCHG
574     case EREMCHG: return "remote address changed";
575 #endif
576 #ifdef EREMDEV
577     case EREMDEV: return "remote device";
578 #endif
579 #ifdef EREMOTE
580     case EREMOTE: return "pathname hit remote file system";
581 #endif
582 #ifdef EREMOTEIO
583     case EREMOTEIO: return "remote i/o error";
584 #endif
585 #ifdef EREMOTERELEASE
586     case EREMOTERELEASE: return "EREMOTERELEASE";
587 #endif
588 #ifdef EROFS
589     case EROFS: return "read-only file system";
590 #endif
591 #ifdef ERPCMISMATCH
592     case ERPCMISMATCH: return "RPC version is wrong";
593 #endif
594 #ifdef ERREMOTE
595     case ERREMOTE: return "object is remote";
596 #endif
597 #ifdef ESHUTDOWN
598     case ESHUTDOWN: return "can't send afer socket shutdown";
599 #endif
600 #ifdef ESOCKTNOSUPPORT
601     case ESOCKTNOSUPPORT: return "socket type not supported";
602 #endif
603 #ifdef ESPIPE
604     case ESPIPE: return "invalid seek";
605 #endif
606 #ifdef ESRCH
607     case ESRCH: return "no such process";
608 #endif
609 #ifdef ESRMNT
610     case ESRMNT: return "srmount error";
611 #endif
612 #ifdef ESTALE
613     case ESTALE: return "stale remote file handle";
614 #endif
615 #ifdef ESUCCESS
616     case ESUCCESS: return "Error 0";
617 #endif
618 #ifdef ETIME
619     case ETIME: return "timer expired";
620 #endif
621 #ifdef ETIMEDOUT
622     case ETIMEDOUT: return "connection timed out";
623 #endif
624 #ifdef ETOOMANYREFS
625     case ETOOMANYREFS: return "too many references: can't splice";
626 #endif
627 #ifdef ETXTBSY
628     case ETXTBSY: return "text file or pseudo-device busy";
629 #endif
630 #ifdef EUCLEAN
631     case EUCLEAN: return "structure needs cleaning";
632 #endif
633 #ifdef EUNATCH
634     case EUNATCH: return "protocol driver not attached";
635 #endif
636 #ifdef EUSERS
637     case EUSERS: return "too many users";
638 #endif
639 #ifdef EVERSION
640     case EVERSION: return "version mismatch";
641 #endif
642 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
643     case EWOULDBLOCK: return "operation would block";
644 #endif
645 #ifdef EXDEV
646     case EXDEV: return "cross-domain link";
647 #endif
648 #ifdef EXFULL
649     case EXFULL: return "message tables full";
650 #endif
651     }
652 #else /* NO_SYS_ERRLIST */
653   extern int sys_nerr;
654   extern char *sys_errlist[];
655
656   if ((errnum > 0) && (errnum <= sys_nerr))
657     return sys_errlist [errnum];
658 #endif /* NO_SYS_ERRLIST */
659
660   msg = g_static_private_get (&msg_private);
661   if (!msg)
662     {
663       msg = g_new (gchar, 64);
664       g_static_private_set (&msg_private, msg, g_free);
665     }
666
667   sprintf (msg, "unknown error (%d)", errnum);
668
669   return msg;
670 }
671
672 gchar*
673 g_strsignal (gint signum)
674 {
675   static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
676   char *msg;
677
678 #ifdef HAVE_STRSIGNAL
679 #ifdef G_OS_BEOS
680 extern const char * strsignal(int);
681 #else /* !G_OS_BEOS */
682   /* this is declared differently (const) in string.h on BeOS */
683   extern char *strsignal (int sig);
684 #endif /* !G_OS_BEOS */
685   return strsignal (signum);
686 #elif NO_SYS_SIGLIST
687   switch (signum)
688     {
689 #ifdef SIGHUP
690     case SIGHUP: return "Hangup";
691 #endif
692 #ifdef SIGINT
693     case SIGINT: return "Interrupt";
694 #endif
695 #ifdef SIGQUIT
696     case SIGQUIT: return "Quit";
697 #endif
698 #ifdef SIGILL
699     case SIGILL: return "Illegal instruction";
700 #endif
701 #ifdef SIGTRAP
702     case SIGTRAP: return "Trace/breakpoint trap";
703 #endif
704 #ifdef SIGABRT
705     case SIGABRT: return "IOT trap/Abort";
706 #endif
707 #ifdef SIGBUS
708     case SIGBUS: return "Bus error";
709 #endif
710 #ifdef SIGFPE
711     case SIGFPE: return "Floating point exception";
712 #endif
713 #ifdef SIGKILL
714     case SIGKILL: return "Killed";
715 #endif
716 #ifdef SIGUSR1
717     case SIGUSR1: return "User defined signal 1";
718 #endif
719 #ifdef SIGSEGV
720     case SIGSEGV: return "Segmentation fault";
721 #endif
722 #ifdef SIGUSR2
723     case SIGUSR2: return "User defined signal 2";
724 #endif
725 #ifdef SIGPIPE
726     case SIGPIPE: return "Broken pipe";
727 #endif
728 #ifdef SIGALRM
729     case SIGALRM: return "Alarm clock";
730 #endif
731 #ifdef SIGTERM
732     case SIGTERM: return "Terminated";
733 #endif
734 #ifdef SIGSTKFLT
735     case SIGSTKFLT: return "Stack fault";
736 #endif
737 #ifdef SIGCHLD
738     case SIGCHLD: return "Child exited";
739 #endif
740 #ifdef SIGCONT
741     case SIGCONT: return "Continued";
742 #endif
743 #ifdef SIGSTOP
744     case SIGSTOP: return "Stopped (signal)";
745 #endif
746 #ifdef SIGTSTP
747     case SIGTSTP: return "Stopped";
748 #endif
749 #ifdef SIGTTIN
750     case SIGTTIN: return "Stopped (tty input)";
751 #endif
752 #ifdef SIGTTOU
753     case SIGTTOU: return "Stopped (tty output)";
754 #endif
755 #ifdef SIGURG
756     case SIGURG: return "Urgent condition";
757 #endif
758 #ifdef SIGXCPU
759     case SIGXCPU: return "CPU time limit exceeded";
760 #endif
761 #ifdef SIGXFSZ
762     case SIGXFSZ: return "File size limit exceeded";
763 #endif
764 #ifdef SIGVTALRM
765     case SIGVTALRM: return "Virtual time alarm";
766 #endif
767 #ifdef SIGPROF
768     case SIGPROF: return "Profile signal";
769 #endif
770 #ifdef SIGWINCH
771     case SIGWINCH: return "Window size changed";
772 #endif
773 #ifdef SIGIO
774     case SIGIO: return "Possible I/O";
775 #endif
776 #ifdef SIGPWR
777     case SIGPWR: return "Power failure";
778 #endif
779 #ifdef SIGUNUSED
780     case SIGUNUSED: return "Unused signal";
781 #endif
782     }
783 #else /* NO_SYS_SIGLIST */
784
785 #ifdef NO_SYS_SIGLIST_DECL
786   extern char *sys_siglist[];   /*(see Tue Jan 19 00:44:24 1999 in changelog)*/
787 #endif
788
789   return (char*) /* this function should return const --josh */ sys_siglist [signum];
790 #endif /* NO_SYS_SIGLIST */
791
792   msg = g_static_private_get (&msg_private);
793   if (!msg)
794     {
795       msg = g_new (gchar, 64);
796       g_static_private_set (&msg_private, msg, g_free);
797     }
798
799   sprintf (msg, "unknown signal (%d)", signum);
800   
801   return msg;
802 }
803
804 /* Functions g_strlcpy and g_strlcat were originally developed by
805  * Todd C. Miller <Todd.Miller@courtesan.com> to simplify writing secure code.
806  * See ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3
807  * for more information.
808  */
809
810 #ifdef HAVE_STRLCPY
811 /* Use the native ones, if available; they might be implemented in assembly */
812 gsize
813 g_strlcpy (gchar       *dest,
814            const gchar *src,
815            gsize        dest_size)
816 {
817   g_return_val_if_fail (dest != NULL, NULL);
818   g_return_val_if_fail (src  != NULL, NULL);
819   
820   return strlcpy (dest, src, dest_size);
821 }
822
823 gsize
824 g_strlcat (gchar       *dest,
825            const gchar *src,
826            gsize        dest_size)
827 {
828   g_return_val_if_fail (dest != NULL, NULL);
829   g_return_val_if_fail (src  != NULL, NULL);
830   
831   return strlcat (dest, src, dest_size);
832 }
833
834 #else /* ! HAVE_STRLCPY */
835 /* g_strlcpy
836  *
837  * Copy string src to buffer dest (of buffer size dest_size).  At most
838  * dest_size-1 characters will be copied.  Always NUL terminates
839  * (unless dest_size == 0).  This function does NOT allocate memory.
840  * Unlike strncpy, this function doesn't pad dest (so it's often faster).
841  * Returns size of attempted result, strlen(src),
842  * so if retval >= dest_size, truncation occurred.
843  */
844 gsize
845 g_strlcpy (gchar       *dest,
846            const gchar *src,
847            gsize        dest_size)
848 {
849   register gchar *d = dest;
850   register const gchar *s = src;
851   register gsize n = dest_size;
852   
853   g_return_val_if_fail (dest != NULL, NULL);
854   g_return_val_if_fail (src  != NULL, NULL);
855   
856   /* Copy as many bytes as will fit */
857   if (n != 0 && --n != 0)
858     do
859       {
860         register gchar c = *s++;
861         
862         *d++ = c;
863         if (c == 0)
864           break;
865       }
866     while (--n != 0);
867   
868   /* If not enough room in dest, add NUL and traverse rest of src */
869   if (n == 0)
870     {
871       if (dest_size != 0)
872         *d = 0;
873       while (*s++)
874         ;
875     }
876   
877   return s - src - 1;  /* count does not include NUL */
878 }
879
880 /* g_strlcat
881  *
882  * Appends string src to buffer dest (of buffer size dest_size).
883  * At most dest_size-1 characters will be copied.
884  * Unlike strncat, dest_size is the full size of dest, not the space left over.
885  * This function does NOT allocate memory.
886  * This always NUL terminates (unless siz == 0 or there were no NUL characters
887  * in the dest_size characters of dest to start with).
888  * Returns size of attempted result, which is
889  * MIN (dest_size, strlen (original dest)) + strlen (src),
890  * so if retval >= dest_size, truncation occurred.
891  */
892 gsize
893 g_strlcat (gchar       *dest,
894            const gchar *src,
895            gsize        dest_size)
896 {
897   register gchar *d = dest;
898   register const gchar *s = src;
899   register gsize bytes_left = dest_size;
900   gsize dlength;  /* Logically, MIN (strlen (d), dest_size) */
901   
902   g_return_val_if_fail (dest != NULL, NULL);
903   g_return_val_if_fail (src  != NULL, NULL);
904   
905   /* Find the end of dst and adjust bytes left but don't go past end */
906   while (*d != 0 && bytes_left-- != 0)
907     d++;
908   dlength = d - dest;
909   bytes_left = dest_size - dlength;
910   
911   if (bytes_left == 0)
912     return dlength + strlen (s);
913   
914   while (*s != 0)
915     {
916       if (bytes_left != 1)
917         {
918           *d++ = *s;
919           bytes_left--;
920         }
921       s++;
922     }
923   *d = 0;
924   
925   return dlength + (s - src);  /* count does not include NUL */
926 }
927 #endif /* ! HAVE_STRLCPY */
928
929 gchar*
930 g_strdown (gchar *string)
931 {
932   register guchar *s;
933   
934   g_return_val_if_fail (string != NULL, NULL);
935   
936   s = string;
937   
938   while (*s)
939     {
940       *s = tolower (*s);
941       s++;
942     }
943   
944   return string;
945 }
946
947 gchar*
948 g_strup (gchar *string)
949 {
950   register guchar *s;
951
952   g_return_val_if_fail (string != NULL, NULL);
953
954   s = string;
955
956   while (*s)
957     {
958       *s = toupper (*s);
959       s++;
960     }
961
962   return string;
963 }
964
965 gchar*
966 g_strreverse (gchar *string)
967 {
968   g_return_val_if_fail (string != NULL, NULL);
969
970   if (*string)
971     {
972       register gchar *h, *t;
973
974       h = string;
975       t = string + strlen (string) - 1;
976
977       while (h < t)
978         {
979           register gchar c;
980
981           c = *h;
982           *h = *t;
983           h++;
984           *t = c;
985           t--;
986         }
987     }
988
989   return string;
990 }
991
992 gint
993 g_strcasecmp (const gchar *s1,
994               const gchar *s2)
995 {
996 #ifdef HAVE_STRCASECMP
997   g_return_val_if_fail (s1 != NULL, 0);
998   g_return_val_if_fail (s2 != NULL, 0);
999
1000   return strcasecmp (s1, s2);
1001 #else
1002   gint c1, c2;
1003
1004   g_return_val_if_fail (s1 != NULL, 0);
1005   g_return_val_if_fail (s2 != NULL, 0);
1006
1007   while (*s1 && *s2)
1008     {
1009       /* According to A. Cox, some platforms have islower's that
1010        * don't work right on non-uppercase
1011        */
1012       c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1;
1013       c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2;
1014       if (c1 != c2)
1015         return (c1 - c2);
1016       s1++; s2++;
1017     }
1018
1019   return (((gint)(guchar) *s1) - ((gint)(guchar) *s2));
1020 #endif
1021 }
1022
1023 gint
1024 g_strncasecmp (const gchar *s1,
1025                const gchar *s2,
1026                guint n)
1027 {
1028 #ifdef HAVE_STRNCASECMP
1029   return strncasecmp (s1, s2, n);
1030 #else
1031   gint c1, c2;
1032
1033   g_return_val_if_fail (s1 != NULL, 0);
1034   g_return_val_if_fail (s2 != NULL, 0);
1035
1036   while (n && *s1 && *s2)
1037     {
1038       n -= 1;
1039       /* According to A. Cox, some platforms have islower's that
1040        * don't work right on non-uppercase
1041        */
1042       c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1;
1043       c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2;
1044       if (c1 != c2)
1045         return (c1 - c2);
1046       s1++; s2++;
1047     }
1048
1049   if (n)
1050     return (((gint) (guchar) *s1) - ((gint) (guchar) *s2));
1051   else
1052     return 0;
1053 #endif
1054 }
1055
1056 gchar*
1057 g_strdelimit (gchar       *string,
1058               const gchar *delimiters,
1059               gchar        new_delim)
1060 {
1061   register gchar *c;
1062
1063   g_return_val_if_fail (string != NULL, NULL);
1064
1065   if (!delimiters)
1066     delimiters = G_STR_DELIMITERS;
1067
1068   for (c = string; *c; c++)
1069     {
1070       if (strchr (delimiters, *c))
1071         *c = new_delim;
1072     }
1073
1074   return string;
1075 }
1076
1077 gchar*
1078 g_strcanon (gchar       *string,
1079             const gchar *valid_chars,
1080             gchar        subsitutor)
1081 {
1082   register gchar *c;
1083
1084   g_return_val_if_fail (string != NULL, NULL);
1085   g_return_val_if_fail (valid_chars != NULL, NULL);
1086
1087   for (c = string; *c; c++)
1088     {
1089       if (!strchr (valid_chars, *c))
1090         *c = subsitutor;
1091     }
1092
1093   return string;
1094 }
1095
1096 gchar*
1097 g_strcompress (const gchar *source)
1098 {
1099   const gchar *p = source, *octal;
1100   gchar *dest = g_malloc (strlen (source) + 1);
1101   gchar *q = dest;
1102   
1103   while (*p)
1104     {
1105       if (*p == '\\')
1106         {
1107           p++;
1108           switch (*p)
1109             {
1110             case '0':  case '1':  case '2':  case '3':  case '4':
1111             case '5':  case '6':  case '7':
1112               *q = 0;
1113               octal = p;
1114               while ((p < octal + 3) && (*p >= '0') && (*p <= '7'))
1115                 {
1116                   *q = (*q * 8) + (*p - '0');
1117                   p++;
1118                 }
1119               q++;
1120               p--;
1121               break;
1122             case 'b':
1123               *q++ = '\b';
1124               break;
1125             case 'f':
1126               *q++ = '\f';
1127               break;
1128             case 'n':
1129               *q++ = '\n';
1130               break;
1131             case 'r':
1132               *q++ = '\r';
1133               break;
1134             case 't':
1135               *q++ = '\t';
1136               break;
1137             default:            /* Also handles \" and \\ */
1138               *q++ = *p;
1139               break;
1140             }
1141         }
1142       else
1143         *q++ = *p;
1144       p++;
1145     }
1146   *q = 0;
1147   
1148   return dest;
1149 }
1150
1151 gchar *
1152 g_strescape (const gchar *source,
1153              const gchar *exceptions)
1154 {
1155   const guchar *p = (guchar *) source;
1156   /* Each source byte needs maximally four destination chars (\777) */
1157   gchar *dest = g_malloc (strlen (source) * 4 + 1);
1158   gchar *q = dest;
1159   guchar excmap[256];
1160
1161   memset (excmap, 0, 256);
1162   if (exceptions)
1163     {
1164       guchar *e = (guchar *) exceptions;
1165
1166       while (*e)
1167         {
1168           excmap[*e] = 1;
1169           e++;
1170         }
1171     }
1172
1173   while (*p)
1174     {
1175       if (excmap[*p])
1176         *q++ = *p;
1177       else
1178         {
1179           switch (*p)
1180             {
1181             case '\b':
1182               *q++ = '\\';
1183               *q++ = 'b';
1184               break;
1185             case '\f':
1186               *q++ = '\\';
1187               *q++ = 'f';
1188               break;
1189             case '\n':
1190               *q++ = '\\';
1191               *q++ = 'n';
1192               break;
1193             case '\r':
1194               *q++ = '\\';
1195               *q++ = 'r';
1196               break;
1197             case '\t':
1198               *q++ = '\\';
1199               *q++ = 't';
1200               break;
1201             case '\\':
1202               *q++ = '\\';
1203               *q++ = '\\';
1204               break;
1205             case '"':
1206               *q++ = '\\';
1207               *q++ = '"';
1208               break;
1209             default:
1210               if ((*p < ' ') || (*p >= 0177))
1211                 {
1212                   *q++ = '\\';
1213                   *q++ = '0' + (((*p) >> 6) & 07);
1214                   *q++ = '0' + (((*p) >> 3) & 07);
1215                   *q++ = '0' + ((*p) & 07);
1216                 }
1217               else
1218                 *q++ = *p;
1219               break;
1220             }
1221         }
1222       p++;
1223     }
1224   *q = 0;
1225   return dest;
1226 }
1227
1228 /*
1229  * g_filename_to_utf8
1230  *
1231  * Converts a string which is in the encoding used for file names by
1232  * the C runtime (usually the same as that used by the operating
1233  * system) in the current locale into a UTF-8 string.
1234  */
1235
1236 gchar *
1237 g_filename_to_utf8 (const gchar *opsysstring)
1238 {
1239 #ifdef G_OS_WIN32
1240
1241   gint i, clen, wclen, first;
1242   const gint len = strlen (opsysstring);
1243   wchar_t *wcs, wc;
1244   gchar *result, *bp;
1245   const wchar_t *wcp;
1246
1247   wcs = g_new (wchar_t, len);
1248   wclen = MultiByteToWideChar (CP_ACP, 0, opsysstring, len, wcs, len);
1249
1250   wcp = wcs;
1251   clen = 0;
1252   for (i = 0; i < wclen; i++)
1253     {
1254       wc = *wcp++;
1255
1256       if (wc < 0x80)
1257         clen += 1;
1258       else if (wc < 0x800)
1259         clen += 2;
1260       else if (wc < 0x10000)
1261         clen += 3;
1262       else if (wc < 0x200000)
1263         clen += 4;
1264       else if (wc < 0x4000000)
1265         clen += 5;
1266       else
1267         clen += 6;
1268     }
1269
1270   result = g_malloc (clen + 1);
1271   
1272   wcp = wcs;
1273   bp = result;
1274   for (i = 0; i < wclen; i++)
1275     {
1276       wc = *wcp++;
1277
1278       if (wc < 0x80)
1279         {
1280           first = 0;
1281           clen = 1;
1282         }
1283       else if (wc < 0x800)
1284         {
1285           first = 0xc0;
1286           clen = 2;
1287         }
1288       else if (wc < 0x10000)
1289         {
1290           first = 0xe0;
1291           clen = 3;
1292         }
1293       else if (wc < 0x200000)
1294         {
1295           first = 0xf0;
1296           clen = 4;
1297         }
1298       else if (wc < 0x4000000)
1299         {
1300           first = 0xf8;
1301           clen = 5;
1302         }
1303       else
1304         {
1305           first = 0xfc;
1306           clen = 6;
1307         }
1308       
1309       /* Woo-hoo! */
1310       switch (clen)
1311         {
1312         case 6: bp[5] = (wc & 0x3f) | 0x80; wc >>= 6; /* Fall through */
1313         case 5: bp[4] = (wc & 0x3f) | 0x80; wc >>= 6; /* Fall through */
1314         case 4: bp[3] = (wc & 0x3f) | 0x80; wc >>= 6; /* Fall through */
1315         case 3: bp[2] = (wc & 0x3f) | 0x80; wc >>= 6; /* Fall through */
1316         case 2: bp[1] = (wc & 0x3f) | 0x80; wc >>= 6; /* Fall through */
1317         case 1: bp[0] = wc | first;
1318         }
1319
1320       bp += clen;
1321     }
1322   *bp = 0;
1323
1324   g_free (wcs);
1325
1326   return result;
1327
1328 #else
1329
1330   return g_strdup (opsysstring);
1331
1332 #endif
1333 }
1334
1335 /*
1336  * g_filename_from_utf8
1337  *
1338  * The reverse of g_filename_to_utf8.
1339  */
1340
1341 gchar *
1342 g_filename_from_utf8 (const gchar *utf8string)
1343 {
1344 #ifdef G_OS_WIN32
1345
1346   gint i, mask, clen, wclen, mblen;
1347   const gint len = strlen (utf8string);
1348   wchar_t *wcs, *wcp;
1349   gchar *result;
1350   guchar *cp, *end, c;
1351   gint n;
1352   
1353   /* First convert to wide chars */
1354   cp = (guchar *) utf8string;
1355   end = cp + len;
1356   n = 0;
1357   wcs = g_new (wchar_t, len + 1);
1358   wcp = wcs;
1359   while (cp != end)
1360     {
1361       mask = 0;
1362       c = *cp;
1363
1364       if (c < 0x80)
1365         {
1366           clen = 1;
1367           mask = 0x7f;
1368         }
1369       else if ((c & 0xe0) == 0xc0)
1370         {
1371           clen = 2;
1372           mask = 0x1f;
1373         }
1374       else if ((c & 0xf0) == 0xe0)
1375         {
1376           clen = 3;
1377           mask = 0x0f;
1378         }
1379       else if ((c & 0xf8) == 0xf0)
1380         {
1381           clen = 4;
1382           mask = 0x07;
1383         }
1384       else if ((c & 0xfc) == 0xf8)
1385         {
1386           clen = 5;
1387           mask = 0x03;
1388         }
1389       else if ((c & 0xfc) == 0xfc)
1390         {
1391           clen = 6;
1392           mask = 0x01;
1393         }
1394       else
1395         {
1396           g_free (wcs);
1397           return NULL;
1398         }
1399
1400       if (cp + clen > end)
1401         {
1402           g_free (wcs);
1403           return NULL;
1404         }
1405
1406       *wcp = (cp[0] & mask);
1407       for (i = 1; i < clen; i++)
1408         {
1409           if ((cp[i] & 0xc0) != 0x80)
1410             {
1411               g_free (wcs);
1412               return NULL;
1413             }
1414           *wcp <<= 6;
1415           *wcp |= (cp[i] & 0x3f);
1416         }
1417
1418       cp += clen;
1419       wcp++;
1420       n++;
1421     }
1422   if (cp != end)
1423     {
1424       g_free (wcs);
1425       return NULL;
1426     }
1427
1428   /* n is the number of wide chars constructed */
1429
1430   /* Convert to a string in the current ANSI codepage */
1431
1432   result = g_new (gchar, 3 * n + 1);
1433   mblen = WideCharToMultiByte (CP_ACP, 0, wcs, n, result, 3*n, NULL, NULL);
1434   result[mblen] = 0;
1435   g_free (wcs);
1436
1437   return result;
1438
1439 #else
1440
1441   return g_strdup (utf8string);
1442
1443 #endif
1444 }
1445
1446 gchar*
1447 g_strchug (gchar *string)
1448 {
1449   guchar *start;
1450
1451   g_return_val_if_fail (string != NULL, NULL);
1452
1453   for (start = string; *start && isspace (*start); start++)
1454     ;
1455
1456   g_memmove (string, start, strlen( start) + 1);
1457
1458   return string;
1459 }
1460
1461 gchar*
1462 g_strchomp (gchar *string)
1463 {
1464   gchar *s;
1465
1466   g_return_val_if_fail (string != NULL, NULL);
1467
1468   if (!*string)
1469     return string;
1470
1471   for (s = string + strlen (string) - 1; s >= string && isspace ((guchar)*s); 
1472        s--)
1473     *s = '\0';
1474
1475   return string;
1476 }
1477
1478 gchar**
1479 g_strsplit (const gchar *string,
1480             const gchar *delimiter,
1481             gint         max_tokens)
1482 {
1483   GSList *string_list = NULL, *slist;
1484   gchar **str_array, *s;
1485   guint i, n = 1;
1486
1487   g_return_val_if_fail (string != NULL, NULL);
1488   g_return_val_if_fail (delimiter != NULL, NULL);
1489
1490   if (max_tokens < 1)
1491     max_tokens = G_MAXINT;
1492
1493   s = strstr (string, delimiter);
1494   if (s)
1495     {
1496       guint delimiter_len = strlen (delimiter);
1497
1498       do
1499         {
1500           guint len;
1501           gchar *new_string;
1502
1503           len = s - string;
1504           new_string = g_new (gchar, len + 1);
1505           strncpy (new_string, string, len);
1506           new_string[len] = 0;
1507           string_list = g_slist_prepend (string_list, new_string);
1508           n++;
1509           string = s + delimiter_len;
1510           s = strstr (string, delimiter);
1511         }
1512       while (--max_tokens && s);
1513     }
1514   if (*string)
1515     {
1516       n++;
1517       string_list = g_slist_prepend (string_list, g_strdup (string));
1518     }
1519
1520   str_array = g_new (gchar*, n);
1521
1522   i = n - 1;
1523
1524   str_array[i--] = NULL;
1525   for (slist = string_list; slist; slist = slist->next)
1526     str_array[i--] = slist->data;
1527
1528   g_slist_free (string_list);
1529
1530   return str_array;
1531 }
1532
1533 void
1534 g_strfreev (gchar **str_array)
1535 {
1536   if (str_array)
1537     {
1538       int i;
1539
1540       for(i = 0; str_array[i] != NULL; i++)
1541         g_free(str_array[i]);
1542
1543       g_free (str_array);
1544     }
1545 }
1546
1547 gchar*
1548 g_strjoinv (const gchar  *separator,
1549             gchar       **str_array)
1550 {
1551   gchar *string;
1552
1553   g_return_val_if_fail (str_array != NULL, NULL);
1554
1555   if (separator == NULL)
1556     separator = "";
1557
1558   if (*str_array)
1559     {
1560       guint i, len;
1561       guint separator_len;
1562
1563       separator_len = strlen (separator);
1564       len = 1 + strlen (str_array[0]);
1565       for(i = 1; str_array[i] != NULL; i++)
1566         len += separator_len + strlen(str_array[i]);
1567
1568       string = g_new (gchar, len);
1569       *string = 0;
1570       strcat (string, *str_array);
1571       for (i = 1; str_array[i] != NULL; i++)
1572         {
1573           strcat (string, separator);
1574           strcat (string, str_array[i]);
1575         }
1576       }
1577   else
1578     string = g_strdup ("");
1579
1580   return string;
1581 }
1582
1583 gchar*
1584 g_strjoin (const gchar  *separator,
1585            ...)
1586 {
1587   gchar *string, *s;
1588   va_list args;
1589   guint len;
1590   guint separator_len;
1591
1592   if (separator == NULL)
1593     separator = "";
1594
1595   separator_len = strlen (separator);
1596
1597   va_start (args, separator);
1598
1599   s = va_arg (args, gchar*);
1600
1601   if (s)
1602     {
1603       len = strlen (s);
1604
1605       s = va_arg (args, gchar*);
1606       while (s)
1607         {
1608           len += separator_len + strlen (s);
1609           s = va_arg (args, gchar*);
1610         }
1611       va_end (args);
1612
1613       string = g_new (gchar, len + 1);
1614       *string = 0;
1615
1616       va_start (args, separator);
1617
1618       s = va_arg (args, gchar*);
1619       strcat (string, s);
1620
1621       s = va_arg (args, gchar*);
1622       while (s)
1623         {
1624           strcat (string, separator);
1625           strcat (string, s);
1626           s = va_arg (args, gchar*);
1627         }
1628     }
1629   else
1630     string = g_strdup ("");
1631
1632   va_end (args);
1633
1634   return string;
1635 }