added gobject
[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 Library 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  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library 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-1999.  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 gchar*
805 g_strdown (gchar *string)
806 {
807   register guchar *s;
808
809   g_return_val_if_fail (string != NULL, NULL);
810
811   s = string;
812
813   while (*s)
814     {
815       *s = tolower (*s);
816       s++;
817     }
818
819   return string;
820 }
821
822 gchar*
823 g_strup (gchar *string)
824 {
825   register guchar *s;
826
827   g_return_val_if_fail (string != NULL, NULL);
828
829   s = string;
830
831   while (*s)
832     {
833       *s = toupper (*s);
834       s++;
835     }
836
837   return string;
838 }
839
840 gchar*
841 g_strreverse (gchar *string)
842 {
843   g_return_val_if_fail (string != NULL, NULL);
844
845   if (*string)
846     {
847       register gchar *h, *t;
848
849       h = string;
850       t = string + strlen (string) - 1;
851
852       while (h < t)
853         {
854           register gchar c;
855
856           c = *h;
857           *h = *t;
858           h++;
859           *t = c;
860           t--;
861         }
862     }
863
864   return string;
865 }
866
867 gint
868 g_strcasecmp (const gchar *s1,
869               const gchar *s2)
870 {
871 #ifdef HAVE_STRCASECMP
872   g_return_val_if_fail (s1 != NULL, 0);
873   g_return_val_if_fail (s2 != NULL, 0);
874
875   return strcasecmp (s1, s2);
876 #else
877   gint c1, c2;
878
879   g_return_val_if_fail (s1 != NULL, 0);
880   g_return_val_if_fail (s2 != NULL, 0);
881
882   while (*s1 && *s2)
883     {
884       /* According to A. Cox, some platforms have islower's that
885        * don't work right on non-uppercase
886        */
887       c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1;
888       c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2;
889       if (c1 != c2)
890         return (c1 - c2);
891       s1++; s2++;
892     }
893
894   return (((gint)(guchar) *s1) - ((gint)(guchar) *s2));
895 #endif
896 }
897
898 gint
899 g_strncasecmp (const gchar *s1,
900                const gchar *s2,
901                guint n)
902 {
903 #ifdef HAVE_STRNCASECMP
904   return strncasecmp (s1, s2, n);
905 #else
906   gint c1, c2;
907
908   g_return_val_if_fail (s1 != NULL, 0);
909   g_return_val_if_fail (s2 != NULL, 0);
910
911   while (n-- && *s1 && *s2)
912     {
913       /* According to A. Cox, some platforms have islower's that
914        * don't work right on non-uppercase
915        */
916       c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1;
917       c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2;
918       if (c1 != c2)
919         return (c1 - c2);
920       s1++; s2++;
921     }
922
923   if (n)
924     return (((gint)(guchar) *s1) - ((gint)(guchar) *s2));
925   else
926     return 0;
927 #endif
928 }
929
930 gchar*
931 g_strdelimit (gchar       *string,
932               const gchar *delimiters,
933               gchar        new_delim)
934 {
935   register gchar *c;
936
937   g_return_val_if_fail (string != NULL, NULL);
938
939   if (!delimiters)
940     delimiters = G_STR_DELIMITERS;
941
942   for (c = string; *c; c++)
943     {
944       if (strchr (delimiters, *c))
945         *c = new_delim;
946     }
947
948   return string;
949 }
950
951 gchar*
952 g_strcanon (gchar       *string,
953             const gchar *valid_chars,
954             gchar        subsitutor)
955 {
956   register gchar *c;
957
958   g_return_val_if_fail (string != NULL, NULL);
959   g_return_val_if_fail (valid_chars != NULL, NULL);
960
961   for (c = string; *c; c++)
962     {
963       if (!strchr (valid_chars, *c))
964         *c = subsitutor;
965     }
966
967   return string;
968 }
969
970 gchar*
971 g_strcompress (const gchar *source)
972 {
973   const gchar *p = source, *octal;
974   gchar *dest = g_malloc (strlen (source) + 1);
975   gchar *q = dest;
976   
977   while (*p)
978     {
979       if (*p == '\\')
980         {
981           p++;
982           switch (*p)
983             {
984             case '0':  case '1':  case '2':  case '3':  case '4':
985             case '5':  case '6':  case '7':
986               *q = 0;
987               octal = p;
988               while ((p < octal + 3) && (*p >= '0') && (*p <= '7'))
989                 {
990                   *q = (*q * 8) + (*p - '0');
991                   p++;
992                 }
993               q++;
994               p--;
995               break;
996             case 'b':
997               *q++ = '\b';
998               break;
999             case 'f':
1000               *q++ = '\f';
1001               break;
1002             case 'n':
1003               *q++ = '\n';
1004               break;
1005             case 'r':
1006               *q++ = '\r';
1007               break;
1008             case 't':
1009               *q++ = '\t';
1010               break;
1011             default:            /* Also handles \" and \\ */
1012               *q++ = *p;
1013               break;
1014             }
1015         }
1016       else
1017         *q++ = *p;
1018       p++;
1019     }
1020   *q = 0;
1021   
1022   return dest;
1023 }
1024
1025 gchar *
1026 g_strescape (const gchar *source,
1027              const gchar *exceptions)
1028 {
1029   const guchar *p = (guchar *) source;
1030   /* Each source byte needs maximally four destination chars (\777) */
1031   gchar *dest = g_malloc (strlen (source) * 4 + 1);
1032   gchar *q = dest;
1033   guchar excmap[256];
1034
1035   memset (excmap, 0, 256);
1036   if (exceptions)
1037     {
1038       guchar *e = (guchar *) exceptions;
1039
1040       while (*e)
1041         {
1042           excmap[*e] = 1;
1043           e++;
1044         }
1045     }
1046
1047   while (*p)
1048     {
1049       if (excmap[*p])
1050         *q++ = *p;
1051       else
1052         {
1053           switch (*p)
1054             {
1055             case '\b':
1056               *q++ = '\\';
1057               *q++ = 'b';
1058               break;
1059             case '\f':
1060               *q++ = '\\';
1061               *q++ = 'f';
1062               break;
1063             case '\n':
1064               *q++ = '\\';
1065               *q++ = 'n';
1066               break;
1067             case '\r':
1068               *q++ = '\\';
1069               *q++ = 'r';
1070               break;
1071             case '\t':
1072               *q++ = '\\';
1073               *q++ = 't';
1074               break;
1075             case '\\':
1076               *q++ = '\\';
1077               *q++ = '\\';
1078               break;
1079             case '"':
1080               *q++ = '\\';
1081               *q++ = '"';
1082               break;
1083             default:
1084               if ((*p < ' ') || (*p >= 0177))
1085                 {
1086                   *q++ = '\\';
1087                   *q++ = '0' + (((*p) >> 6) & 07);
1088                   *q++ = '0' + (((*p) >> 3) & 07);
1089                   *q++ = '0' + ((*p) & 07);
1090                 }
1091               else
1092                 *q++ = *p;
1093               break;
1094             }
1095         }
1096       p++;
1097     }
1098   *q = 0;
1099   return dest;
1100 }
1101
1102 /*
1103  * g_filename_to_utf8
1104  *
1105  * Converts a string which is in the encoding used for file names by
1106  * the C runtime (usually the same as that used by the operating
1107  * system) in the current locale into a UTF-8 string.
1108  */
1109
1110 gchar *
1111 g_filename_to_utf8 (const gchar *opsysstring)
1112 {
1113 #ifdef G_OS_WIN32
1114
1115   gint i, clen, wclen, first;
1116   const gint len = strlen (opsysstring);
1117   wchar_t *wcs, wc;
1118   gchar *result, *bp;
1119   const wchar_t *wcp;
1120
1121   wcs = g_new (wchar_t, len);
1122   wclen = MultiByteToWideChar (CP_ACP, 0, opsysstring, len, wcs, len);
1123
1124   wcp = wcs;
1125   clen = 0;
1126   for (i = 0; i < wclen; i++)
1127     {
1128       wc = *wcp++;
1129
1130       if (wc < 0x80)
1131         clen += 1;
1132       else if (wc < 0x800)
1133         clen += 2;
1134       else if (wc < 0x10000)
1135         clen += 3;
1136       else if (wc < 0x200000)
1137         clen += 4;
1138       else if (wc < 0x4000000)
1139         clen += 5;
1140       else
1141         clen += 6;
1142     }
1143
1144   result = g_malloc (clen + 1);
1145   
1146   wcp = wcs;
1147   bp = result;
1148   for (i = 0; i < wclen; i++)
1149     {
1150       wc = *wcp++;
1151
1152       if (wc < 0x80)
1153         {
1154           first = 0;
1155           clen = 1;
1156         }
1157       else if (wc < 0x800)
1158         {
1159           first = 0xc0;
1160           clen = 2;
1161         }
1162       else if (wc < 0x10000)
1163         {
1164           first = 0xe0;
1165           clen = 3;
1166         }
1167       else if (wc < 0x200000)
1168         {
1169           first = 0xf0;
1170           clen = 4;
1171         }
1172       else if (wc < 0x4000000)
1173         {
1174           first = 0xf8;
1175           clen = 5;
1176         }
1177       else
1178         {
1179           first = 0xfc;
1180           clen = 6;
1181         }
1182       
1183       /* Woo-hoo! */
1184       switch (clen)
1185         {
1186         case 6: bp[5] = (wc & 0x3f) | 0x80; wc >>= 6; /* Fall through */
1187         case 5: bp[4] = (wc & 0x3f) | 0x80; wc >>= 6; /* Fall through */
1188         case 4: bp[3] = (wc & 0x3f) | 0x80; wc >>= 6; /* Fall through */
1189         case 3: bp[2] = (wc & 0x3f) | 0x80; wc >>= 6; /* Fall through */
1190         case 2: bp[1] = (wc & 0x3f) | 0x80; wc >>= 6; /* Fall through */
1191         case 1: bp[0] = wc | first;
1192         }
1193
1194       bp += clen;
1195     }
1196   *bp = 0;
1197
1198   g_free (wcs);
1199
1200   return result;
1201
1202 #else
1203
1204   return g_strdup (opsysstring);
1205
1206 #endif
1207 }
1208
1209 /*
1210  * g_filename_from_utf8
1211  *
1212  * The reverse of g_filename_to_utf8.
1213  */
1214
1215 gchar *
1216 g_filename_from_utf8 (const gchar *utf8string)
1217 {
1218 #ifdef G_OS_WIN32
1219
1220   gint i, mask, clen, wclen, mblen;
1221   const gint len = strlen (utf8string);
1222   wchar_t *wcs, *wcp;
1223   gchar *result;
1224   guchar *cp, *end, c;
1225   gint n;
1226   
1227   /* First convert to wide chars */
1228   cp = (guchar *) utf8string;
1229   end = cp + len;
1230   n = 0;
1231   wcs = g_new (wchar_t, len + 1);
1232   wcp = wcs;
1233   while (cp != end)
1234     {
1235       mask = 0;
1236       c = *cp;
1237
1238       if (c < 0x80)
1239         {
1240           clen = 1;
1241           mask = 0x7f;
1242         }
1243       else if ((c & 0xe0) == 0xc0)
1244         {
1245           clen = 2;
1246           mask = 0x1f;
1247         }
1248       else if ((c & 0xf0) == 0xe0)
1249         {
1250           clen = 3;
1251           mask = 0x0f;
1252         }
1253       else if ((c & 0xf8) == 0xf0)
1254         {
1255           clen = 4;
1256           mask = 0x07;
1257         }
1258       else if ((c & 0xfc) == 0xf8)
1259         {
1260           clen = 5;
1261           mask = 0x03;
1262         }
1263       else if ((c & 0xfc) == 0xfc)
1264         {
1265           clen = 6;
1266           mask = 0x01;
1267         }
1268       else
1269         {
1270           g_free (wcs);
1271           return NULL;
1272         }
1273
1274       if (cp + clen > end)
1275         {
1276           g_free (wcs);
1277           return NULL;
1278         }
1279
1280       *wcp = (cp[0] & mask);
1281       for (i = 1; i < clen; i++)
1282         {
1283           if ((cp[i] & 0xc0) != 0x80)
1284             {
1285               g_free (wcs);
1286               return NULL;
1287             }
1288           *wcp <<= 6;
1289           *wcp |= (cp[i] & 0x3f);
1290         }
1291
1292       cp += clen;
1293       wcp++;
1294       n++;
1295     }
1296   if (cp != end)
1297     {
1298       g_free (wcs);
1299       return NULL;
1300     }
1301
1302   /* n is the number of wide chars constructed */
1303
1304   /* Convert to a string in the current ANSI codepage */
1305
1306   result = g_new (gchar, 3 * n + 1);
1307   mblen = WideCharToMultiByte (CP_ACP, 0, wcs, n, result, 3*n, NULL, NULL);
1308   result[mblen] = 0;
1309   g_free (wcs);
1310
1311   return result;
1312
1313 #else
1314
1315   return g_strdup (utf8string);
1316
1317 #endif
1318 }
1319
1320 gchar*
1321 g_strchug (gchar *string)
1322 {
1323   guchar *start;
1324
1325   g_return_val_if_fail (string != NULL, NULL);
1326
1327   for (start = string; *start && isspace (*start); start++)
1328     ;
1329
1330   g_memmove (string, start, strlen( start) + 1);
1331
1332   return string;
1333 }
1334
1335 gchar*
1336 g_strchomp (gchar *string)
1337 {
1338   gchar *s;
1339
1340   g_return_val_if_fail (string != NULL, NULL);
1341
1342   if (!*string)
1343     return string;
1344
1345   for (s = string + strlen (string) - 1; s >= string && isspace ((guchar)*s); 
1346        s--)
1347     *s = '\0';
1348
1349   return string;
1350 }
1351
1352 gchar**
1353 g_strsplit (const gchar *string,
1354             const gchar *delimiter,
1355             gint         max_tokens)
1356 {
1357   GSList *string_list = NULL, *slist;
1358   gchar **str_array, *s;
1359   guint i, n = 1;
1360
1361   g_return_val_if_fail (string != NULL, NULL);
1362   g_return_val_if_fail (delimiter != NULL, NULL);
1363
1364   if (max_tokens < 1)
1365     max_tokens = G_MAXINT;
1366
1367   s = strstr (string, delimiter);
1368   if (s)
1369     {
1370       guint delimiter_len = strlen (delimiter);
1371
1372       do
1373         {
1374           guint len;
1375           gchar *new_string;
1376
1377           len = s - string;
1378           new_string = g_new (gchar, len + 1);
1379           strncpy (new_string, string, len);
1380           new_string[len] = 0;
1381           string_list = g_slist_prepend (string_list, new_string);
1382           n++;
1383           string = s + delimiter_len;
1384           s = strstr (string, delimiter);
1385         }
1386       while (--max_tokens && s);
1387     }
1388   if (*string)
1389     {
1390       n++;
1391       string_list = g_slist_prepend (string_list, g_strdup (string));
1392     }
1393
1394   str_array = g_new (gchar*, n);
1395
1396   i = n - 1;
1397
1398   str_array[i--] = NULL;
1399   for (slist = string_list; slist; slist = slist->next)
1400     str_array[i--] = slist->data;
1401
1402   g_slist_free (string_list);
1403
1404   return str_array;
1405 }
1406
1407 void
1408 g_strfreev (gchar **str_array)
1409 {
1410   if (str_array)
1411     {
1412       int i;
1413
1414       for(i = 0; str_array[i] != NULL; i++)
1415         g_free(str_array[i]);
1416
1417       g_free (str_array);
1418     }
1419 }
1420
1421 gchar*
1422 g_strjoinv (const gchar  *separator,
1423             gchar       **str_array)
1424 {
1425   gchar *string;
1426
1427   g_return_val_if_fail (str_array != NULL, NULL);
1428
1429   if (separator == NULL)
1430     separator = "";
1431
1432   if (*str_array)
1433     {
1434       guint i, len;
1435       guint separator_len;
1436
1437       separator_len = strlen (separator);
1438       len = 1 + strlen (str_array[0]);
1439       for(i = 1; str_array[i] != NULL; i++)
1440         len += separator_len + strlen(str_array[i]);
1441
1442       string = g_new (gchar, len);
1443       *string = 0;
1444       strcat (string, *str_array);
1445       for (i = 1; str_array[i] != NULL; i++)
1446         {
1447           strcat (string, separator);
1448           strcat (string, str_array[i]);
1449         }
1450       }
1451   else
1452     string = g_strdup ("");
1453
1454   return string;
1455 }
1456
1457 gchar*
1458 g_strjoin (const gchar  *separator,
1459            ...)
1460 {
1461   gchar *string, *s;
1462   va_list args;
1463   guint len;
1464   guint separator_len;
1465
1466   if (separator == NULL)
1467     separator = "";
1468
1469   separator_len = strlen (separator);
1470
1471   va_start (args, separator);
1472
1473   s = va_arg (args, gchar*);
1474
1475   if (s)
1476     {
1477       len = strlen (s);
1478
1479       s = va_arg (args, gchar*);
1480       while (s)
1481         {
1482           len += separator_len + strlen (s);
1483           s = va_arg (args, gchar*);
1484         }
1485       va_end (args);
1486
1487       string = g_new (gchar, len + 1);
1488       *string = 0;
1489
1490       va_start (args, separator);
1491
1492       s = va_arg (args, gchar*);
1493       strcat (string, s);
1494
1495       s = va_arg (args, gchar*);
1496       while (s)
1497         {
1498           strcat (string, separator);
1499           strcat (string, s);
1500           s = va_arg (args, gchar*);
1501         }
1502     }
1503   else
1504     string = g_strdup ("");
1505
1506   va_end (args);
1507
1508   return string;
1509 }