cf9defb7c186117bed186926d5e2656eee4b9695
[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 G_CONST_RETURN 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 G_CONST_RETURN 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 #if defined(G_OS_BEOS) || defined(G_WITH_CYGWIN)
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, 0);
818   g_return_val_if_fail (src  != NULL, 0);
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, 0);
829   g_return_val_if_fail (src  != NULL, 0);
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, 0);
854   g_return_val_if_fail (src  != NULL, 0);
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, 0);
903   g_return_val_if_fail (src  != NULL, 0);
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 = (guchar *) string;
937   
938   while (*s)
939     {
940       *s = tolower (*s);
941       s++;
942     }
943   
944   return (gchar *) 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 = (guchar *) string;
955
956   while (*s)
957     {
958       *s = toupper (*s);
959       s++;
960     }
961
962   return (gchar *) 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;
1156   gchar *dest;
1157   gchar *q;
1158   guchar excmap[256];
1159   
1160   g_return_val_if_fail (source != NULL, NULL);
1161
1162   p = (guchar *) source;
1163   /* Each source byte needs maximally four destination chars (\777) */
1164   q = dest = g_malloc (strlen (source) * 4 + 1);
1165
1166   memset (excmap, 0, 256);
1167   if (exceptions)
1168     {
1169       guchar *e = (guchar *) exceptions;
1170
1171       while (*e)
1172         {
1173           excmap[*e] = 1;
1174           e++;
1175         }
1176     }
1177
1178   while (*p)
1179     {
1180       if (excmap[*p])
1181         *q++ = *p;
1182       else
1183         {
1184           switch (*p)
1185             {
1186             case '\b':
1187               *q++ = '\\';
1188               *q++ = 'b';
1189               break;
1190             case '\f':
1191               *q++ = '\\';
1192               *q++ = 'f';
1193               break;
1194             case '\n':
1195               *q++ = '\\';
1196               *q++ = 'n';
1197               break;
1198             case '\r':
1199               *q++ = '\\';
1200               *q++ = 'r';
1201               break;
1202             case '\t':
1203               *q++ = '\\';
1204               *q++ = 't';
1205               break;
1206             case '\\':
1207               *q++ = '\\';
1208               *q++ = '\\';
1209               break;
1210             case '"':
1211               *q++ = '\\';
1212               *q++ = '"';
1213               break;
1214             default:
1215               if ((*p < ' ') || (*p >= 0177))
1216                 {
1217                   *q++ = '\\';
1218                   *q++ = '0' + (((*p) >> 6) & 07);
1219                   *q++ = '0' + (((*p) >> 3) & 07);
1220                   *q++ = '0' + ((*p) & 07);
1221                 }
1222               else
1223                 *q++ = *p;
1224               break;
1225             }
1226         }
1227       p++;
1228     }
1229   *q = 0;
1230   return dest;
1231 }
1232
1233 gchar*
1234 g_strchug (gchar *string)
1235 {
1236   guchar *start;
1237
1238   g_return_val_if_fail (string != NULL, NULL);
1239
1240   for (start = (guchar*) string; *start && isspace (*start); start++)
1241     ;
1242
1243   g_memmove (string, start, strlen ((gchar *) start) + 1);
1244
1245   return string;
1246 }
1247
1248 gchar*
1249 g_strchomp (gchar *string)
1250 {
1251   gchar *s;
1252
1253   g_return_val_if_fail (string != NULL, NULL);
1254
1255   if (!*string)
1256     return string;
1257
1258   for (s = string + strlen (string) - 1; s >= string && isspace ((guchar)*s); 
1259        s--)
1260     *s = '\0';
1261
1262   return string;
1263 }
1264
1265 gchar**
1266 g_strsplit (const gchar *string,
1267             const gchar *delimiter,
1268             gint         max_tokens)
1269 {
1270   GSList *string_list = NULL, *slist;
1271   gchar **str_array, *s;
1272   guint n = 1;
1273
1274   g_return_val_if_fail (string != NULL, NULL);
1275   g_return_val_if_fail (delimiter != NULL, NULL);
1276
1277   if (max_tokens < 1)
1278     max_tokens = G_MAXINT;
1279
1280   s = strstr (string, delimiter);
1281   if (s)
1282     {
1283       guint delimiter_len = strlen (delimiter);
1284
1285       do
1286         {
1287           guint len;
1288           gchar *new_string;
1289
1290           len = s - string;
1291           new_string = g_new (gchar, len + 1);
1292           strncpy (new_string, string, len);
1293           new_string[len] = 0;
1294           string_list = g_slist_prepend (string_list, new_string);
1295           n++;
1296           string = s + delimiter_len;
1297           s = strstr (string, delimiter);
1298         }
1299       while (--max_tokens && s);
1300     }
1301   string_list = g_slist_prepend (string_list, g_strdup (string));
1302
1303   str_array = g_new (gchar*, n + 1);
1304
1305   str_array[n--] = NULL;
1306   for (slist = string_list; slist; slist = slist->next)
1307     str_array[n--] = slist->data;
1308
1309   g_slist_free (string_list);
1310
1311   return str_array;
1312 }
1313
1314 void
1315 g_strfreev (gchar **str_array)
1316 {
1317   if (str_array)
1318     {
1319       int i;
1320
1321       for(i = 0; str_array[i] != NULL; i++)
1322         g_free(str_array[i]);
1323
1324       g_free (str_array);
1325     }
1326 }
1327
1328 /**
1329  * g_strdupv:
1330  * @str_array: %NULL-terminated array of strings
1331  * 
1332  * Copies %NULL-terminated array of strings. The copy is a deep copy;
1333  * the new array should be freed by first freeing each string, then
1334  * the array itself. g_strfreev() does this for you. If called
1335  * on a %NULL value, g_strdupv() simply returns %NULL.
1336  * 
1337  * Return value: a new %NULL-terminated array of strings
1338  **/
1339 gchar**
1340 g_strdupv (gchar **str_array)
1341 {
1342   if (str_array)
1343     {
1344       gint i;
1345       gchar **retval;
1346
1347       i = 0;
1348       while (str_array[i])
1349         ++i;
1350           
1351       retval = g_new (gchar*, i + 1);
1352
1353       i = 0;
1354       while (str_array[i])
1355         {
1356           retval[i] = g_strdup (str_array[i]);
1357           ++i;
1358         }
1359       retval[i] = NULL;
1360
1361       return retval;
1362     }
1363   else
1364     return NULL;
1365 }
1366
1367 gchar*
1368 g_strjoinv (const gchar  *separator,
1369             gchar       **str_array)
1370 {
1371   gchar *string;
1372
1373   g_return_val_if_fail (str_array != NULL, NULL);
1374
1375   if (separator == NULL)
1376     separator = "";
1377
1378   if (*str_array)
1379     {
1380       guint i, len;
1381       guint separator_len;
1382
1383       separator_len = strlen (separator);
1384       len = 1 + strlen (str_array[0]);
1385       for(i = 1; str_array[i] != NULL; i++)
1386         len += separator_len + strlen(str_array[i]);
1387
1388       string = g_new (gchar, len);
1389       *string = 0;
1390       strcat (string, *str_array);
1391       for (i = 1; str_array[i] != NULL; i++)
1392         {
1393           strcat (string, separator);
1394           strcat (string, str_array[i]);
1395         }
1396       }
1397   else
1398     string = g_strdup ("");
1399
1400   return string;
1401 }
1402
1403 gchar*
1404 g_strjoin (const gchar  *separator,
1405            ...)
1406 {
1407   gchar *string, *s;
1408   va_list args;
1409   guint len;
1410   guint separator_len;
1411
1412   if (separator == NULL)
1413     separator = "";
1414
1415   separator_len = strlen (separator);
1416
1417   va_start (args, separator);
1418
1419   s = va_arg (args, gchar*);
1420
1421   if (s)
1422     {
1423       len = strlen (s);
1424
1425       s = va_arg (args, gchar*);
1426       while (s)
1427         {
1428           len += separator_len + strlen (s);
1429           s = va_arg (args, gchar*);
1430         }
1431       va_end (args);
1432
1433       string = g_new (gchar, len + 1);
1434       *string = 0;
1435
1436       va_start (args, separator);
1437
1438       s = va_arg (args, gchar*);
1439       strcat (string, s);
1440
1441       s = va_arg (args, gchar*);
1442       while (s)
1443         {
1444           strcat (string, separator);
1445           strcat (string, s);
1446           s = va_arg (args, gchar*);
1447         }
1448     }
1449   else
1450     string = g_strdup ("");
1451
1452   va_end (args);
1453
1454   return string;
1455 }