fixed errernerous code wrt to thread specific error string allocation
[platform/upstream/glib.git] / 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  * MT safe
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdarg.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <locale.h>
33 #include <ctype.h>              /* For tolower() */
34 #if !defined (HAVE_STRSIGNAL) || !defined(NO_SYS_SIGLIST_DECL)
35 #include <signal.h>
36 #endif
37 #include "glib.h"
38 /* do not include <unistd.h> in this place since it
39  * inteferes with g_strsignal() on some OSes
40  */
41
42 gchar*
43 g_strdup (const gchar *str)
44 {
45   gchar *new_str;
46
47   if (str)
48     {
49       new_str = g_new (char, strlen (str) + 1);
50       strcpy (new_str, str);
51     }
52   else
53     new_str = NULL;
54
55   return new_str;
56 }
57
58 gpointer
59 g_memdup (gconstpointer mem,
60           guint         byte_size)
61 {
62   gpointer new_mem;
63
64   if (mem)
65     {
66       new_mem = g_malloc (byte_size);
67       memcpy (new_mem, mem, byte_size);
68     }
69   else
70     new_mem = NULL;
71
72   return new_mem;
73 }
74
75 gchar*
76 g_strndup (const gchar *str,
77            guint        n)
78 {
79   gchar *new_str;
80
81   if (str)
82     {
83       new_str = g_new (gchar, n + 1);
84       strncpy (new_str, str, n);
85       new_str[n] = '\0';
86     }
87   else
88     new_str = NULL;
89
90   return new_str;
91 }
92
93 gchar*
94 g_strnfill (guint length,
95             gchar fill_char)
96 {
97   register gchar *str, *s, *end;
98
99   str = g_new (gchar, length + 1);
100   s = str;
101   end = str + length;
102   while (s < end)
103     *(s++) = fill_char;
104   *s = 0;
105
106   return str;
107 }
108
109 gchar*
110 g_strdup_vprintf (const gchar *format,
111                   va_list      args1)
112 {
113   gchar *buffer;
114   va_list args2;
115
116   G_VA_COPY (args2, args1);
117
118   buffer = g_new (gchar, g_printf_string_upper_bound (format, args1));
119
120   vsprintf (buffer, format, args2);
121   va_end (args2);
122
123   return buffer;
124 }
125
126 gchar*
127 g_strdup_printf (const gchar *format,
128                  ...)
129 {
130   gchar *buffer;
131   va_list args;
132
133   va_start (args, format);
134   buffer = g_strdup_vprintf (format, args);
135   va_end (args);
136
137   return buffer;
138 }
139
140 gchar*
141 g_strconcat (const gchar *string1, ...)
142 {
143   guint   l;
144   va_list args;
145   gchar   *s;
146   gchar   *concat;
147
148   g_return_val_if_fail (string1 != NULL, NULL);
149
150   l = 1 + strlen (string1);
151   va_start (args, string1);
152   s = va_arg (args, gchar*);
153   while (s)
154     {
155       l += strlen (s);
156       s = va_arg (args, gchar*);
157     }
158   va_end (args);
159
160   concat = g_new (gchar, l);
161   concat[0] = 0;
162
163   strcat (concat, string1);
164   va_start (args, string1);
165   s = va_arg (args, gchar*);
166   while (s)
167     {
168       strcat (concat, s);
169       s = va_arg (args, gchar*);
170     }
171   va_end (args);
172
173   return concat;
174 }
175
176 gdouble
177 g_strtod (const gchar *nptr,
178           gchar **endptr)
179 {
180   gchar *fail_pos_1;
181   gchar *fail_pos_2;
182   gdouble val_1;
183   gdouble val_2 = 0;
184
185   g_return_val_if_fail (nptr != NULL, 0);
186
187   fail_pos_1 = NULL;
188   fail_pos_2 = NULL;
189
190   val_1 = strtod (nptr, &fail_pos_1);
191
192   if (fail_pos_1 && fail_pos_1[0] != 0)
193     {
194       gchar *old_locale;
195
196       old_locale = setlocale (LC_NUMERIC, "C");
197       val_2 = strtod (nptr, &fail_pos_2);
198       setlocale (LC_NUMERIC, old_locale);
199     }
200
201   if (!fail_pos_1 || fail_pos_1[0] == 0 || fail_pos_1 >= fail_pos_2)
202     {
203       if (endptr)
204         *endptr = fail_pos_1;
205       return val_1;
206     }
207   else
208     {
209       if (endptr)
210         *endptr = fail_pos_2;
211       return val_2;
212     }
213 }
214
215 gchar*
216 g_strerror (gint errnum)
217 {
218   static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
219   char *msg;
220
221 #ifdef HAVE_STRERROR
222   return strerror (errnum);
223 #elif NO_SYS_ERRLIST
224   switch (errnum)
225     {
226 #ifdef E2BIG
227     case E2BIG: return "argument list too long";
228 #endif
229 #ifdef EACCES
230     case EACCES: return "permission denied";
231 #endif
232 #ifdef EADDRINUSE
233     case EADDRINUSE: return "address already in use";
234 #endif
235 #ifdef EADDRNOTAVAIL
236     case EADDRNOTAVAIL: return "can't assign requested address";
237 #endif
238 #ifdef EADV
239     case EADV: return "advertise error";
240 #endif
241 #ifdef EAFNOSUPPORT
242     case EAFNOSUPPORT: return "address family not supported by protocol family";
243 #endif
244 #ifdef EAGAIN
245     case EAGAIN: return "try again";
246 #endif
247 #ifdef EALIGN
248     case EALIGN: return "EALIGN";
249 #endif
250 #ifdef EALREADY
251     case EALREADY: return "operation already in progress";
252 #endif
253 #ifdef EBADE
254     case EBADE: return "bad exchange descriptor";
255 #endif
256 #ifdef EBADF
257     case EBADF: return "bad file number";
258 #endif
259 #ifdef EBADFD
260     case EBADFD: return "file descriptor in bad state";
261 #endif
262 #ifdef EBADMSG
263     case EBADMSG: return "not a data message";
264 #endif
265 #ifdef EBADR
266     case EBADR: return "bad request descriptor";
267 #endif
268 #ifdef EBADRPC
269     case EBADRPC: return "RPC structure is bad";
270 #endif
271 #ifdef EBADRQC
272     case EBADRQC: return "bad request code";
273 #endif
274 #ifdef EBADSLT
275     case EBADSLT: return "invalid slot";
276 #endif
277 #ifdef EBFONT
278     case EBFONT: return "bad font file format";
279 #endif
280 #ifdef EBUSY
281     case EBUSY: return "mount device busy";
282 #endif
283 #ifdef ECHILD
284     case ECHILD: return "no children";
285 #endif
286 #ifdef ECHRNG
287     case ECHRNG: return "channel number out of range";
288 #endif
289 #ifdef ECOMM
290     case ECOMM: return "communication error on send";
291 #endif
292 #ifdef ECONNABORTED
293     case ECONNABORTED: return "software caused connection abort";
294 #endif
295 #ifdef ECONNREFUSED
296     case ECONNREFUSED: return "connection refused";
297 #endif
298 #ifdef ECONNRESET
299     case ECONNRESET: return "connection reset by peer";
300 #endif
301 #if defined(EDEADLK) && (!defined(EWOULDBLOCK) || (EDEADLK != EWOULDBLOCK))
302     case EDEADLK: return "resource deadlock avoided";
303 #endif
304 #ifdef EDEADLOCK
305     case EDEADLOCK: return "resource deadlock avoided";
306 #endif
307 #ifdef EDESTADDRREQ
308     case EDESTADDRREQ: return "destination address required";
309 #endif
310 #ifdef EDIRTY
311     case EDIRTY: return "mounting a dirty fs w/o force";
312 #endif
313 #ifdef EDOM
314     case EDOM: return "math argument out of range";
315 #endif
316 #ifdef EDOTDOT
317     case EDOTDOT: return "cross mount point";
318 #endif
319 #ifdef EDQUOT
320     case EDQUOT: return "disk quota exceeded";
321 #endif
322 #ifdef EDUPPKG
323     case EDUPPKG: return "duplicate package name";
324 #endif
325 #ifdef EEXIST
326     case EEXIST: return "file already exists";
327 #endif
328 #ifdef EFAULT
329     case EFAULT: return "bad address in system call argument";
330 #endif
331 #ifdef EFBIG
332     case EFBIG: return "file too large";
333 #endif
334 #ifdef EHOSTDOWN
335     case EHOSTDOWN: return "host is down";
336 #endif
337 #ifdef EHOSTUNREACH
338     case EHOSTUNREACH: return "host is unreachable";
339 #endif
340 #ifdef EIDRM
341     case EIDRM: return "identifier removed";
342 #endif
343 #ifdef EINIT
344     case EINIT: return "initialization error";
345 #endif
346 #ifdef EINPROGRESS
347     case EINPROGRESS: return "operation now in progress";
348 #endif
349 #ifdef EINTR
350     case EINTR: return "interrupted system call";
351 #endif
352 #ifdef EINVAL
353     case EINVAL: return "invalid argument";
354 #endif
355 #ifdef EIO
356     case EIO: return "I/O error";
357 #endif
358 #ifdef EISCONN
359     case EISCONN: return "socket is already connected";
360 #endif
361 #ifdef EISDIR
362     case EISDIR: return "illegal operation on a directory";
363 #endif
364 #ifdef EISNAME
365     case EISNAM: return "is a name file";
366 #endif
367 #ifdef ELBIN
368     case ELBIN: return "ELBIN";
369 #endif
370 #ifdef EL2HLT
371     case EL2HLT: return "level 2 halted";
372 #endif
373 #ifdef EL2NSYNC
374     case EL2NSYNC: return "level 2 not synchronized";
375 #endif
376 #ifdef EL3HLT
377     case EL3HLT: return "level 3 halted";
378 #endif
379 #ifdef EL3RST
380     case EL3RST: return "level 3 reset";
381 #endif
382 #ifdef ELIBACC
383     case ELIBACC: return "can not access a needed shared library";
384 #endif
385 #ifdef ELIBBAD
386     case ELIBBAD: return "accessing a corrupted shared library";
387 #endif
388 #ifdef ELIBEXEC
389     case ELIBEXEC: return "can not exec a shared library directly";
390 #endif
391 #ifdef ELIBMAX
392     case ELIBMAX: return "attempting to link in more shared libraries than system limit";
393 #endif
394 #ifdef ELIBSCN
395     case ELIBSCN: return ".lib section in a.out corrupted";
396 #endif
397 #ifdef ELNRNG
398     case ELNRNG: return "link number out of range";
399 #endif
400 #ifdef ELOOP
401     case ELOOP: return "too many levels of symbolic links";
402 #endif
403 #ifdef EMFILE
404     case EMFILE: return "too many open files";
405 #endif
406 #ifdef EMLINK
407     case EMLINK: return "too many links";
408 #endif
409 #ifdef EMSGSIZE
410     case EMSGSIZE: return "message too long";
411 #endif
412 #ifdef EMULTIHOP
413     case EMULTIHOP: return "multihop attempted";
414 #endif
415 #ifdef ENAMETOOLONG
416     case ENAMETOOLONG: return "file name too long";
417 #endif
418 #ifdef ENAVAIL
419     case ENAVAIL: return "not available";
420 #endif
421 #ifdef ENET
422     case ENET: return "ENET";
423 #endif
424 #ifdef ENETDOWN
425     case ENETDOWN: return "network is down";
426 #endif
427 #ifdef ENETRESET
428     case ENETRESET: return "network dropped connection on reset";
429 #endif
430 #ifdef ENETUNREACH
431     case ENETUNREACH: return "network is unreachable";
432 #endif
433 #ifdef ENFILE
434     case ENFILE: return "file table overflow";
435 #endif
436 #ifdef ENOANO
437     case ENOANO: return "anode table overflow";
438 #endif
439 #if defined(ENOBUFS) && (!defined(ENOSR) || (ENOBUFS != ENOSR))
440     case ENOBUFS: return "no buffer space available";
441 #endif
442 #ifdef ENOCSI
443     case ENOCSI: return "no CSI structure available";
444 #endif
445 #ifdef ENODATA
446     case ENODATA: return "no data available";
447 #endif
448 #ifdef ENODEV
449     case ENODEV: return "no such device";
450 #endif
451 #ifdef ENOENT
452     case ENOENT: return "no such file or directory";
453 #endif
454 #ifdef ENOEXEC
455     case ENOEXEC: return "exec format error";
456 #endif
457 #ifdef ENOLCK
458     case ENOLCK: return "no locks available";
459 #endif
460 #ifdef ENOLINK
461     case ENOLINK: return "link has be severed";
462 #endif
463 #ifdef ENOMEM
464     case ENOMEM: return "not enough memory";
465 #endif
466 #ifdef ENOMSG
467     case ENOMSG: return "no message of desired type";
468 #endif
469 #ifdef ENONET
470     case ENONET: return "machine is not on the network";
471 #endif
472 #ifdef ENOPKG
473     case ENOPKG: return "package not installed";
474 #endif
475 #ifdef ENOPROTOOPT
476     case ENOPROTOOPT: return "bad proocol option";
477 #endif
478 #ifdef ENOSPC
479     case ENOSPC: return "no space left on device";
480 #endif
481 #ifdef ENOSR
482     case ENOSR: return "out of stream resources";
483 #endif
484 #ifdef ENOSTR
485     case ENOSTR: return "not a stream device";
486 #endif
487 #ifdef ENOSYM
488     case ENOSYM: return "unresolved symbol name";
489 #endif
490 #ifdef ENOSYS
491     case ENOSYS: return "function not implemented";
492 #endif
493 #ifdef ENOTBLK
494     case ENOTBLK: return "block device required";
495 #endif
496 #ifdef ENOTCONN
497     case ENOTCONN: return "socket is not connected";
498 #endif
499 #ifdef ENOTDIR
500     case ENOTDIR: return "not a directory";
501 #endif
502 #ifdef ENOTEMPTY
503     case ENOTEMPTY: return "directory not empty";
504 #endif
505 #ifdef ENOTNAM
506     case ENOTNAM: return "not a name file";
507 #endif
508 #ifdef ENOTSOCK
509     case ENOTSOCK: return "socket operation on non-socket";
510 #endif
511 #ifdef ENOTTY
512     case ENOTTY: return "inappropriate device for ioctl";
513 #endif
514 #ifdef ENOTUNIQ
515     case ENOTUNIQ: return "name not unique on network";
516 #endif
517 #ifdef ENXIO
518     case ENXIO: return "no such device or address";
519 #endif
520 #ifdef EOPNOTSUPP
521     case EOPNOTSUPP: return "operation not supported on socket";
522 #endif
523 #ifdef EPERM
524     case EPERM: return "not owner";
525 #endif
526 #ifdef EPFNOSUPPORT
527     case EPFNOSUPPORT: return "protocol family not supported";
528 #endif
529 #ifdef EPIPE
530     case EPIPE: return "broken pipe";
531 #endif
532 #ifdef EPROCLIM
533     case EPROCLIM: return "too many processes";
534 #endif
535 #ifdef EPROCUNAVAIL
536     case EPROCUNAVAIL: return "bad procedure for program";
537 #endif
538 #ifdef EPROGMISMATCH
539     case EPROGMISMATCH: return "program version wrong";
540 #endif
541 #ifdef EPROGUNAVAIL
542     case EPROGUNAVAIL: return "RPC program not available";
543 #endif
544 #ifdef EPROTO
545     case EPROTO: return "protocol error";
546 #endif
547 #ifdef EPROTONOSUPPORT
548     case EPROTONOSUPPORT: return "protocol not suppored";
549 #endif
550 #ifdef EPROTOTYPE
551     case EPROTOTYPE: return "protocol wrong type for socket";
552 #endif
553 #ifdef ERANGE
554     case ERANGE: return "math result unrepresentable";
555 #endif
556 #if defined(EREFUSED) && (!defined(ECONNREFUSED) || (EREFUSED != ECONNREFUSED))
557     case EREFUSED: return "EREFUSED";
558 #endif
559 #ifdef EREMCHG
560     case EREMCHG: return "remote address changed";
561 #endif
562 #ifdef EREMDEV
563     case EREMDEV: return "remote device";
564 #endif
565 #ifdef EREMOTE
566     case EREMOTE: return "pathname hit remote file system";
567 #endif
568 #ifdef EREMOTEIO
569     case EREMOTEIO: return "remote i/o error";
570 #endif
571 #ifdef EREMOTERELEASE
572     case EREMOTERELEASE: return "EREMOTERELEASE";
573 #endif
574 #ifdef EROFS
575     case EROFS: return "read-only file system";
576 #endif
577 #ifdef ERPCMISMATCH
578     case ERPCMISMATCH: return "RPC version is wrong";
579 #endif
580 #ifdef ERREMOTE
581     case ERREMOTE: return "object is remote";
582 #endif
583 #ifdef ESHUTDOWN
584     case ESHUTDOWN: return "can't send afer socket shutdown";
585 #endif
586 #ifdef ESOCKTNOSUPPORT
587     case ESOCKTNOSUPPORT: return "socket type not supported";
588 #endif
589 #ifdef ESPIPE
590     case ESPIPE: return "invalid seek";
591 #endif
592 #ifdef ESRCH
593     case ESRCH: return "no such process";
594 #endif
595 #ifdef ESRMNT
596     case ESRMNT: return "srmount error";
597 #endif
598 #ifdef ESTALE
599     case ESTALE: return "stale remote file handle";
600 #endif
601 #ifdef ESUCCESS
602     case ESUCCESS: return "Error 0";
603 #endif
604 #ifdef ETIME
605     case ETIME: return "timer expired";
606 #endif
607 #ifdef ETIMEDOUT
608     case ETIMEDOUT: return "connection timed out";
609 #endif
610 #ifdef ETOOMANYREFS
611     case ETOOMANYREFS: return "too many references: can't splice";
612 #endif
613 #ifdef ETXTBSY
614     case ETXTBSY: return "text file or pseudo-device busy";
615 #endif
616 #ifdef EUCLEAN
617     case EUCLEAN: return "structure needs cleaning";
618 #endif
619 #ifdef EUNATCH
620     case EUNATCH: return "protocol driver not attached";
621 #endif
622 #ifdef EUSERS
623     case EUSERS: return "too many users";
624 #endif
625 #ifdef EVERSION
626     case EVERSION: return "version mismatch";
627 #endif
628 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
629     case EWOULDBLOCK: return "operation would block";
630 #endif
631 #ifdef EXDEV
632     case EXDEV: return "cross-domain link";
633 #endif
634 #ifdef EXFULL
635     case EXFULL: return "message tables full";
636 #endif
637     }
638 #else /* NO_SYS_ERRLIST */
639   extern int sys_nerr;
640   extern char *sys_errlist[];
641
642   if ((errnum > 0) && (errnum <= sys_nerr))
643     return sys_errlist [errnum];
644 #endif /* NO_SYS_ERRLIST */
645
646   msg = g_static_private_get (&msg_private);
647   if (!msg)
648     {
649       msg = g_new (gchar, 64);
650       g_static_private_set (&msg_private, msg, g_free);
651     }
652
653   sprintf (msg, "unknown error (%d)", errnum);
654
655   return msg;
656 }
657
658 gchar*
659 g_strsignal (gint signum)
660 {
661   static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
662   char *msg;
663
664 #ifdef HAVE_STRSIGNAL
665   extern char *strsignal (int sig);
666   return strsignal (signum);
667 #elif NO_SYS_SIGLIST
668   switch (signum)
669     {
670 #ifdef SIGHUP
671     case SIGHUP: return "Hangup";
672 #endif
673 #ifdef SIGINT
674     case SIGINT: return "Interrupt";
675 #endif
676 #ifdef SIGQUIT
677     case SIGQUIT: return "Quit";
678 #endif
679 #ifdef SIGILL
680     case SIGILL: return "Illegal instruction";
681 #endif
682 #ifdef SIGTRAP
683     case SIGTRAP: return "Trace/breakpoint trap";
684 #endif
685 #ifdef SIGABRT
686     case SIGABRT: return "IOT trap/Abort";
687 #endif
688 #ifdef SIGBUS
689     case SIGBUS: return "Bus error";
690 #endif
691 #ifdef SIGFPE
692     case SIGFPE: return "Floating point exception";
693 #endif
694 #ifdef SIGKILL
695     case SIGKILL: return "Killed";
696 #endif
697 #ifdef SIGUSR1
698     case SIGUSR1: return "User defined signal 1";
699 #endif
700 #ifdef SIGSEGV
701     case SIGSEGV: return "Segmentation fault";
702 #endif
703 #ifdef SIGUSR2
704     case SIGUSR2: return "User defined signal 2";
705 #endif
706 #ifdef SIGPIPE
707     case SIGPIPE: return "Broken pipe";
708 #endif
709 #ifdef SIGALRM
710     case SIGALRM: return "Alarm clock";
711 #endif
712 #ifdef SIGTERM
713     case SIGTERM: return "Terminated";
714 #endif
715 #ifdef SIGSTKFLT
716     case SIGSTKFLT: return "Stack fault";
717 #endif
718 #ifdef SIGCHLD
719     case SIGCHLD: return "Child exited";
720 #endif
721 #ifdef SIGCONT
722     case SIGCONT: return "Continued";
723 #endif
724 #ifdef SIGSTOP
725     case SIGSTOP: return "Stopped (signal)";
726 #endif
727 #ifdef SIGTSTP
728     case SIGTSTP: return "Stopped";
729 #endif
730 #ifdef SIGTTIN
731     case SIGTTIN: return "Stopped (tty input)";
732 #endif
733 #ifdef SIGTTOU
734     case SIGTTOU: return "Stopped (tty output)";
735 #endif
736 #ifdef SIGURG
737     case SIGURG: return "Urgent condition";
738 #endif
739 #ifdef SIGXCPU
740     case SIGXCPU: return "CPU time limit exceeded";
741 #endif
742 #ifdef SIGXFSZ
743     case SIGXFSZ: return "File size limit exceeded";
744 #endif
745 #ifdef SIGVTALRM
746     case SIGVTALRM: return "Virtual time alarm";
747 #endif
748 #ifdef SIGPROF
749     case SIGPROF: return "Profile signal";
750 #endif
751 #ifdef SIGWINCH
752     case SIGWINCH: return "Window size changed";
753 #endif
754 #ifdef SIGIO
755     case SIGIO: return "Possible I/O";
756 #endif
757 #ifdef SIGPWR
758     case SIGPWR: return "Power failure";
759 #endif
760 #ifdef SIGUNUSED
761     case SIGUNUSED: return "Unused signal";
762 #endif
763     }
764 #else /* NO_SYS_SIGLIST */
765
766 #ifdef NO_SYS_SIGLIST_DECL
767   extern char *sys_siglist[];   /*(see Tue Jan 19 00:44:24 1999 in changelog)*/
768 #endif
769
770   return (char*) /* this function should return const --josh */ sys_siglist [signum];
771 #endif /* NO_SYS_SIGLIST */
772
773   msg = g_static_private_get (&msg_private);
774   if (!msg)
775     {
776       msg = g_new (gchar, 64);
777       g_static_private_set (&msg_private, msg, g_free);
778     }
779
780   sprintf (msg, "unknown signal (%d)", signum);
781
782   return msg;
783 }
784
785 guint
786 g_printf_string_upper_bound (const gchar* format,
787                              va_list      args)
788 {
789   guint len = 1;
790
791   while (*format)
792     {
793       gboolean long_int = FALSE;
794       gboolean extra_long = FALSE;
795       gchar c;
796
797       c = *format++;
798
799       if (c == '%')
800         {
801           gboolean done = FALSE;
802
803           while (*format && !done)
804             {
805               switch (*format++)
806                 {
807                   gchar *string_arg;
808
809                 case '*':
810                   len += va_arg (args, int);
811                   break;
812                 case '1':
813                 case '2':
814                 case '3':
815                 case '4':
816                 case '5':
817                 case '6':
818                 case '7':
819                 case '8':
820                 case '9':
821                   /* add specified format length, since it might exceed the
822                    * size we assume it to have.
823                    */
824                   format -= 1;
825                   len += strtol (format, (char**) &format, 10);
826                   break;
827                 case 'h':
828                   /* ignore short int flag, since all args have at least the
829                    * same size as an int
830                    */
831                   break;
832                 case 'l':
833                   if (long_int)
834                     extra_long = TRUE; /* linux specific */
835                   else
836                     long_int = TRUE;
837                   break;
838                 case 'q':
839                 case 'L':
840                   long_int = TRUE;
841                   extra_long = TRUE;
842                   break;
843                 case 's':
844                   string_arg = va_arg (args, char *);
845                   if (string_arg)
846                     len += strlen (string_arg);
847                   else
848                     {
849                       /* add enough padding to hold "(null)" identifier */
850                       len += 16;
851                     }
852                   done = TRUE;
853                   break;
854                 case 'd':
855                 case 'i':
856                 case 'o':
857                 case 'u':
858                 case 'x':
859                 case 'X':
860 #ifdef  G_HAVE_GINT64
861                   if (extra_long)
862                     (void) va_arg (args, gint64);
863                   else
864 #endif  /* G_HAVE_GINT64 */
865                     {
866                       if (long_int)
867                         (void) va_arg (args, long);
868                       else
869                         (void) va_arg (args, int);
870                     }
871                   len += extra_long ? 64 : 32;
872                   done = TRUE;
873                   break;
874                 case 'D':
875                 case 'O':
876                 case 'U':
877                   (void) va_arg (args, long);
878                   len += 32;
879                   done = TRUE;
880                   break;
881                 case 'e':
882                 case 'E':
883                 case 'f':
884                 case 'g':
885 #ifdef HAVE_LONG_DOUBLE
886                   if (extra_long)
887                     (void) va_arg (args, long double);
888                   else
889 #endif  /* HAVE_LONG_DOUBLE */
890                     (void) va_arg (args, double);
891                   len += extra_long ? 64 : 32;
892                   done = TRUE;
893                   break;
894                 case 'c':
895                   (void) va_arg (args, int);
896                   len += 1;
897                   done = TRUE;
898                   break;
899                 case 'p':
900                 case 'n':
901                   (void) va_arg (args, void*);
902                   len += 32;
903                   done = TRUE;
904                   break;
905                 case '%':
906                   len += 1;
907                   done = TRUE;
908                   break;
909                 default:
910                   /* ignore unknow/invalid flags */
911                   break;
912                 }
913             }
914         }
915       else
916         len += 1;
917     }
918
919   return len;
920 }
921
922 void
923 g_strdown (gchar  *string)
924 {
925   register gchar *s;
926
927   g_return_if_fail (string != NULL);
928
929   s = string;
930
931   while (*s)
932     {
933       *s = tolower (*s);
934       s++;
935     }
936 }
937
938 void
939 g_strup (gchar  *string)
940 {
941   register gchar *s;
942
943   g_return_if_fail (string != NULL);
944
945   s = string;
946
947   while (*s)
948     {
949       *s = toupper (*s);
950       s++;
951     }
952 }
953
954 void
955 g_strreverse (gchar       *string)
956 {
957   g_return_if_fail (string != NULL);
958
959   if (*string)
960     {
961       register gchar *h, *t;
962
963       h = string;
964       t = string + strlen (string) - 1;
965
966       while (h < t)
967         {
968           register gchar c;
969
970           c = *h;
971           *h = *t;
972           h++;
973           *t = c;
974           t--;
975         }
976     }
977 }
978
979 gint
980 g_strcasecmp (const gchar *s1,
981               const gchar *s2)
982 {
983 #ifdef HAVE_STRCASECMP
984   return strcasecmp (s1, s2);
985 #else
986   gint c1, c2;
987
988   g_return_val_if_fail (s1 != NULL, 0);
989   g_return_val_if_fail (s2 != NULL, 0);
990
991   while (*s1 && *s2)
992     {
993       /* According to A. Cox, some platforms have islower's that
994        * don't work right on non-uppercase
995        */
996       c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1;
997       c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2;
998       if (c1 != c2)
999         return (c1 - c2);
1000       s1++; s2++;
1001     }
1002
1003   return (((gint)(guchar) *s1) - ((gint)(guchar) *s2));
1004 #endif
1005 }
1006
1007 gint
1008 g_strncasecmp (const gchar *s1,
1009                const gchar *s2,
1010                guint n)
1011 {
1012 #ifdef HAVE_STRNCASECMP
1013   return strncasecmp (s1, s2, n);
1014 #else
1015   gint c1, c2;
1016
1017   g_return_val_if_fail (s1 != NULL, 0);
1018   g_return_val_if_fail (s2 != NULL, 0);
1019
1020   while (n-- && *s1 && *s2)
1021     {
1022       /* According to A. Cox, some platforms have islower's that
1023        * don't work right on non-uppercase
1024        */
1025       c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1;
1026       c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2;
1027       if (c1 != c2)
1028         return (c1 - c2);
1029       s1++; s2++;
1030     }
1031
1032   if (n)
1033     return (((gint)(guchar) *s1) - ((gint)(guchar) *s2));
1034   else
1035     return 0;
1036 #endif
1037 }
1038
1039 gchar*
1040 g_strdelimit (gchar       *string,
1041               const gchar *delimiters,
1042               gchar        new_delim)
1043 {
1044   register gchar *c;
1045
1046   g_return_val_if_fail (string != NULL, NULL);
1047
1048   if (!delimiters)
1049     delimiters = G_STR_DELIMITERS;
1050
1051   for (c = string; *c; c++)
1052     {
1053       if (strchr (delimiters, *c))
1054         *c = new_delim;
1055     }
1056
1057   return string;
1058 }
1059
1060 gchar*
1061 g_strescape (gchar *string)
1062 {
1063   gchar *q;
1064   gchar *escaped;
1065   guint backslashes = 0;
1066   gchar *p = string;
1067
1068   g_return_val_if_fail (string != NULL, NULL);
1069
1070   while (*p != '\000')
1071     backslashes += (*p++ == '\\');
1072
1073   if (!backslashes)
1074     return g_strdup (string);
1075
1076   escaped = g_new (gchar, strlen (string) + backslashes + 1);
1077
1078   p = string;
1079   q = escaped;
1080
1081   while (*p != '\000')
1082     {
1083       if (*p == '\\')
1084         *q++ = '\\';
1085       *q++ = *p++;
1086     }
1087   *q = '\000';
1088
1089   return escaped;
1090 }
1091
1092 /* blame Elliot for these next five routines */
1093 gchar*
1094 g_strchug (gchar *string)
1095 {
1096   gchar *start;
1097
1098   g_return_val_if_fail (string != NULL, NULL);
1099
1100   for (start = string; *start && isspace (*start); start++)
1101     ;
1102
1103   strcpy (string, start);
1104
1105   return string;
1106 }
1107
1108 gchar*
1109 g_strchomp (gchar *string)
1110 {
1111   gchar *s;
1112
1113   g_return_val_if_fail (string != NULL, NULL);
1114
1115   if (!*string)
1116     return string;
1117
1118   for (s = string + strlen (string) - 1; s >= string && isspace (*s); s--)
1119     *s = '\0';
1120
1121   return string;
1122 }
1123
1124 gchar**
1125 g_strsplit (const gchar *string,
1126             const gchar *delimiter,
1127             gint         max_tokens)
1128 {
1129   GSList *string_list = NULL, *slist;
1130   gchar **str_array, *s;
1131   guint i, n = 1;
1132
1133   g_return_val_if_fail (string != NULL, NULL);
1134   g_return_val_if_fail (delimiter != NULL, NULL);
1135
1136   if (max_tokens < 1)
1137     max_tokens = G_MAXINT;
1138
1139   s = strstr (string, delimiter);
1140   if (s)
1141     {
1142       guint delimiter_len = strlen (delimiter);
1143
1144       do
1145         {
1146           guint len;
1147           gchar *new_string;
1148
1149           len = s - string;
1150           new_string = g_new (gchar, len + 1);
1151           strncpy (new_string, string, len);
1152           new_string[len] = 0;
1153           string_list = g_slist_prepend (string_list, new_string);
1154           n++;
1155           string = s + delimiter_len;
1156           s = strstr (string, delimiter);
1157         }
1158       while (--max_tokens && s);
1159     }
1160   if (*string)
1161     {
1162       n++;
1163       string_list = g_slist_prepend (string_list, g_strdup (string));
1164     }
1165
1166   str_array = g_new (gchar*, n);
1167
1168   i = n - 1;
1169
1170   str_array[i--] = NULL;
1171   for (slist = string_list; slist; slist = slist->next)
1172     str_array[i--] = slist->data;
1173
1174   g_slist_free (string_list);
1175
1176   return str_array;
1177 }
1178
1179 void
1180 g_strfreev (gchar **str_array)
1181 {
1182   if (str_array)
1183     {
1184       int i;
1185
1186       for(i = 0; str_array[i] != NULL; i++)
1187         g_free(str_array[i]);
1188
1189       g_free (str_array);
1190     }
1191 }
1192
1193 gchar*
1194 g_strjoinv (const gchar  *separator,
1195             gchar       **str_array)
1196 {
1197   gchar *string;
1198
1199   g_return_val_if_fail (str_array != NULL, NULL);
1200
1201   if(separator == NULL)
1202     separator = "";
1203
1204   if (*str_array)
1205     {
1206       guint i, len;
1207       guint separator_len;
1208
1209       separator_len = strlen (separator);
1210       len = 1 + strlen (str_array[0]);
1211       for(i = 1; str_array[i] != NULL; i++)
1212         len += separator_len + strlen(str_array[i]);
1213
1214       string = g_new (gchar, len);
1215       *string = 0;
1216       strcat (string, *str_array);
1217       for (i = 1; str_array[i] != NULL; i++)
1218         {
1219           strcat (string, separator);
1220           strcat (string, str_array[i]);
1221         }
1222       }
1223   else
1224     string = g_strdup ("");
1225
1226   return string;
1227 }
1228
1229 gchar*
1230 g_strjoin (const gchar  *separator,
1231            ...)
1232 {
1233   gchar *string, *s;
1234   va_list args;
1235   guint len;
1236   guint separator_len;
1237
1238   if(separator == NULL)
1239     separator = "";
1240
1241   separator_len = strlen (separator);
1242
1243   va_start(args, separator);
1244
1245   s = va_arg(args, gchar *);
1246
1247   if(s) {
1248     len = strlen(s) + 1;
1249
1250     while((s = va_arg(args, gchar*)))
1251       {
1252         len += separator_len + strlen(s);
1253       }
1254     va_end(args);
1255
1256     string = g_new (gchar, len);
1257
1258     va_start(args, separator);
1259
1260     *string = 0;
1261     s = va_arg(args, gchar*);
1262     strcat (string, s);
1263
1264     while((s = va_arg(args, gchar*)))
1265       {
1266         strcat(string, separator);
1267         strcat(string, s);
1268       }
1269
1270   } else
1271     string = g_strdup("");
1272
1273   va_end(args);
1274
1275   return string;
1276 }