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