mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-26 07:26:15 +01:00
a6149403de
Tue Oct 27 03:00:50 1998 Tim Janik <timj@gtk.org> * glib.h: removed dummy structure definitions for struct _GCache, _GTree, _GTimer, _GMemChunk, _GListAllocator and _GStringChunk. * gutils.c: implement glib's inline functions _after_ all include statements have been processed. removed Tor's MAXPATHLEN check since there already was one supplied further down in this file. (LibMain): special cased the #ifdef __LCC__ case for NATIVE_WIN32, since lcc maybe used on other platforms as well. why in hell is this stuff required? (g_get_any_init): for windows, if the user name is supplied, use it as realname also. in general, if there is no homedir specified, use the tmpdir that we already figured. * gtimer.c (g_timer_elapsed): changed a g_assert() statement to g_return_if_fail(). * applied glib-tml-981020-0.patch for WIN32 portability, added some comments and g_return_if_fail() statements, minor indentation fixes. ChangeLog entry from Tor Lillqvist is appended. * glib.h (struct dirent): use lower case structure members. * glib.h: * makefile.lcc: * makefile.msc: s/COMPILING_GLIB/GLIB_COMPILATION/ 1998-10-20: Tor Lillqvist <tml@iki.fi> * README.win32 glib.def gmodule.def * glibconfig.h.win32 gmodule/gmoduleconf.h.win32: New files for the Windows port. The .def files list exported symbols for the Microsoft linker and compatibles. * configure.in: Added checks for some platform-dependent headers: pwd.h sys/param.h sys/select.h sys/time.h sys/times.h unistd.h, and the function lstat. * gerror.c: Conditionalized inclusion of system-dependent headers. Changes for Windows: no gdb to do a stack trace. Just call abort(). * glib.h: Changes for Windows: Added macros G_DIR_SEPARATOR, G_DIR_SEPARATOR_S for platform-dependent file name syntax elements. Added macros G_SEARCHPATH_SEPARATOR, G_SEARCHPATH_SEPARATOR_S for platform-dependent search path syntax conventions. Added pragmas for Microsoft C to make it more pedantic. Marked GLib's global variables for export from DLL. Added the function g_strescape that escapes backslashes. Added functions g_path_is_absolute and g_path_skip_root to handle platform-dependent file name syntax. Added the function g_getenv that expands environment variables that contain references to other environment variables, as is typical on Windows NT. Added the GIOChannel structure which is used to encapsulate the IPC mechanism used by the GIMP's plug-ins, and possibly other things later. On Unix a GIOChannel encapsulates just a file descriptor. On Windows it contains a file handle from _pipe() and a few other things related to the implementation of gdk_input_add and GIMP plug-in communication. Subject to change. Removed duplicate declarations of the version variables. For the Microsoft compiler, declare own implementation of ftruncate and the <dirent.h> functions. * gmem.c: Define a symbolic name for the profiling table size. * gmessages.c: Conditionalized inclusion of unistd.h. On Windows, output using stdio to stdout. * gscanner.c: Conditionalized inclusion of unistd.h. Added changes for Microsoft C. Added CR to the skipped character set. Added small workaround for MSC compiler bug in g_scanner_cur_value. * gstrfuncs.c: Added the function g_strescape, which escapes the backslash character. Needed especially when printing Windows filenames. * gtimer.c: Conditionalized inclusion of unistd.h and sys/time.h. Added implementations for Windows. * gutils.c: Conditionalized inclusion of platform-dependent headers. Use the platform-independent file name syntax macros. Conditionalize code on platform-dependent features. Added the functions g_path_is_absolute g_path_skip_root and g_getenv. Added the GIOChannel-related functions. Added compiler-dependent Unix compatibility functions for Windows. * makefile.lcc makefile.msc: New files. Compiler-specific makefiles for LCC-Win32 and Microsoft C. Only Microsoft C is actually supported currently. * testglib.c: Added pathname check cases for Windows. Added workaround for bug in the Microsoft runtime library. Improved some tests a bit. Tue Oct 27 04:00:11 1998 Tim Janik <timj@gtk.org> * testgmodule.c (main): changed the #ifdef WIN32 test to NATIVE_WIN32, this needs to be more constistent throughout the code, do we go for NATIVE_WIN32 or WIN32? * gmodule.c (LibMain): special cased the #ifdef __LCC__ case for NATIVE_WIN32, since lcc maybe used on other platforms as well. * libgplugin_a.c (LibMain): * libgplugin_b.c (LibMain): likewise. not sure i like this special requirement for lcc in here. * gmodule-dl.c (_g_module_build_path): feature empty "" directories and prepend the module name with "lib". * gmodule-dld.c (_g_module_build_path): * gmodule-win32.c (_g_module_build_path): feature empty "" directories. * we need some more magic in the _g_module_build_path variants so we don't append/prepend lib and .so, .sl or .dll for those names that already contain it. * applied patch from Tor Lillqvist for g_module_build_path() and windows support. 1998-10-20: Tor Lillqvist <tml@iki.fi> * gmodule/gmodule-win32.c: New file. * gmodule/gmodule.c gmodule/gmodule.h: Added the funcion g_module_build_path that builds the path to a module file, decorating the name according to the system's conventions. Added the Windows implementation. * gmodule/libgplugin_a.c gmodule/libgplugin_b.c: Added LibMain for LCC-Win32. * gmodule/testgmodule.c: Handle Windows dll names.
1211 lines
24 KiB
C
1211 lines
24 KiB
C
/* GLIB - Library of useful routines for C programming
|
|
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Library General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public
|
|
* License along with this library; if not, write to the
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
* Boston, MA 02111-1307, USA.
|
|
*/
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <locale.h>
|
|
#include <ctype.h> /* For tolower() */
|
|
#include "glib.h"
|
|
/* do not include <unistd.h> in this place since it
|
|
* inteferes with g_strsignal() on some OSes
|
|
*/
|
|
|
|
gchar*
|
|
g_strdup (const gchar *str)
|
|
{
|
|
gchar *new_str;
|
|
|
|
if (str)
|
|
{
|
|
new_str = g_new (char, strlen (str) + 1);
|
|
strcpy (new_str, str);
|
|
}
|
|
else
|
|
new_str = NULL;
|
|
|
|
return new_str;
|
|
}
|
|
|
|
gpointer
|
|
g_memdup (gconstpointer mem,
|
|
guint byte_size)
|
|
{
|
|
gpointer new_mem;
|
|
|
|
if (mem)
|
|
{
|
|
new_mem = g_malloc (byte_size);
|
|
memcpy (new_mem, mem, byte_size);
|
|
}
|
|
else
|
|
new_mem = NULL;
|
|
|
|
return new_mem;
|
|
}
|
|
|
|
gchar*
|
|
g_strndup (const gchar *str,
|
|
guint n)
|
|
{
|
|
gchar *new_str;
|
|
|
|
if (str)
|
|
{
|
|
new_str = g_new (gchar, n + 1);
|
|
strncpy (new_str, str, n);
|
|
new_str[n] = '\0';
|
|
}
|
|
else
|
|
new_str = NULL;
|
|
|
|
return new_str;
|
|
}
|
|
|
|
gchar*
|
|
g_strnfill (guint length,
|
|
gchar fill_char)
|
|
{
|
|
register gchar *str, *s, *end;
|
|
|
|
str = g_new (gchar, length + 1);
|
|
s = str;
|
|
end = str + length;
|
|
while (s < end)
|
|
*(s++) = fill_char;
|
|
*s = 0;
|
|
|
|
return str;
|
|
}
|
|
|
|
gchar*
|
|
g_strdup_vprintf (const gchar *format,
|
|
va_list args1)
|
|
{
|
|
gchar *buffer;
|
|
va_list args2;
|
|
|
|
G_VA_COPY (args2, args1);
|
|
|
|
buffer = g_new (gchar, g_printf_string_upper_bound (format, args1));
|
|
|
|
vsprintf (buffer, format, args2);
|
|
va_end (args2);
|
|
|
|
return buffer;
|
|
}
|
|
|
|
gchar*
|
|
g_strdup_printf (const gchar *format,
|
|
...)
|
|
{
|
|
gchar *buffer;
|
|
va_list args;
|
|
|
|
va_start (args, format);
|
|
buffer = g_strdup_vprintf (format, args);
|
|
va_end (args);
|
|
|
|
return buffer;
|
|
}
|
|
|
|
gchar*
|
|
g_strconcat (const gchar *string1, ...)
|
|
{
|
|
guint l;
|
|
va_list args;
|
|
gchar *s;
|
|
gchar *concat;
|
|
|
|
g_return_val_if_fail (string1 != NULL, NULL);
|
|
|
|
l = 1 + strlen (string1);
|
|
va_start (args, string1);
|
|
s = va_arg (args, gchar*);
|
|
while (s)
|
|
{
|
|
l += strlen (s);
|
|
s = va_arg (args, gchar*);
|
|
}
|
|
va_end (args);
|
|
|
|
concat = g_new (gchar, l);
|
|
concat[0] = 0;
|
|
|
|
strcat (concat, string1);
|
|
va_start (args, string1);
|
|
s = va_arg (args, gchar*);
|
|
while (s)
|
|
{
|
|
strcat (concat, s);
|
|
s = va_arg (args, gchar*);
|
|
}
|
|
va_end (args);
|
|
|
|
return concat;
|
|
}
|
|
|
|
gdouble
|
|
g_strtod (const gchar *nptr,
|
|
gchar **endptr)
|
|
{
|
|
gchar *fail_pos_1;
|
|
gchar *fail_pos_2;
|
|
gdouble val_1;
|
|
gdouble val_2 = 0;
|
|
|
|
g_return_val_if_fail (nptr != NULL, 0);
|
|
|
|
fail_pos_1 = NULL;
|
|
fail_pos_2 = NULL;
|
|
|
|
val_1 = strtod (nptr, &fail_pos_1);
|
|
|
|
if (fail_pos_1 && fail_pos_1[0] != 0)
|
|
{
|
|
gchar *old_locale;
|
|
|
|
old_locale = setlocale (LC_NUMERIC, "C");
|
|
val_2 = strtod (nptr, &fail_pos_2);
|
|
setlocale (LC_NUMERIC, old_locale);
|
|
}
|
|
|
|
if (!fail_pos_1 || fail_pos_1[0] == 0 || fail_pos_1 >= fail_pos_2)
|
|
{
|
|
if (endptr)
|
|
*endptr = fail_pos_1;
|
|
return val_1;
|
|
}
|
|
else
|
|
{
|
|
if (endptr)
|
|
*endptr = fail_pos_2;
|
|
return val_2;
|
|
}
|
|
}
|
|
|
|
gchar*
|
|
g_strerror (gint errnum)
|
|
{
|
|
static char msg[64];
|
|
|
|
#ifdef HAVE_STRERROR
|
|
return strerror (errnum);
|
|
#elif NO_SYS_ERRLIST
|
|
switch (errnum)
|
|
{
|
|
#ifdef E2BIG
|
|
case E2BIG: return "argument list too long";
|
|
#endif
|
|
#ifdef EACCES
|
|
case EACCES: return "permission denied";
|
|
#endif
|
|
#ifdef EADDRINUSE
|
|
case EADDRINUSE: return "address already in use";
|
|
#endif
|
|
#ifdef EADDRNOTAVAIL
|
|
case EADDRNOTAVAIL: return "can't assign requested address";
|
|
#endif
|
|
#ifdef EADV
|
|
case EADV: return "advertise error";
|
|
#endif
|
|
#ifdef EAFNOSUPPORT
|
|
case EAFNOSUPPORT: return "address family not supported by protocol family";
|
|
#endif
|
|
#ifdef EAGAIN
|
|
case EAGAIN: return "try again";
|
|
#endif
|
|
#ifdef EALIGN
|
|
case EALIGN: return "EALIGN";
|
|
#endif
|
|
#ifdef EALREADY
|
|
case EALREADY: return "operation already in progress";
|
|
#endif
|
|
#ifdef EBADE
|
|
case EBADE: return "bad exchange descriptor";
|
|
#endif
|
|
#ifdef EBADF
|
|
case EBADF: return "bad file number";
|
|
#endif
|
|
#ifdef EBADFD
|
|
case EBADFD: return "file descriptor in bad state";
|
|
#endif
|
|
#ifdef EBADMSG
|
|
case EBADMSG: return "not a data message";
|
|
#endif
|
|
#ifdef EBADR
|
|
case EBADR: return "bad request descriptor";
|
|
#endif
|
|
#ifdef EBADRPC
|
|
case EBADRPC: return "RPC structure is bad";
|
|
#endif
|
|
#ifdef EBADRQC
|
|
case EBADRQC: return "bad request code";
|
|
#endif
|
|
#ifdef EBADSLT
|
|
case EBADSLT: return "invalid slot";
|
|
#endif
|
|
#ifdef EBFONT
|
|
case EBFONT: return "bad font file format";
|
|
#endif
|
|
#ifdef EBUSY
|
|
case EBUSY: return "mount device busy";
|
|
#endif
|
|
#ifdef ECHILD
|
|
case ECHILD: return "no children";
|
|
#endif
|
|
#ifdef ECHRNG
|
|
case ECHRNG: return "channel number out of range";
|
|
#endif
|
|
#ifdef ECOMM
|
|
case ECOMM: return "communication error on send";
|
|
#endif
|
|
#ifdef ECONNABORTED
|
|
case ECONNABORTED: return "software caused connection abort";
|
|
#endif
|
|
#ifdef ECONNREFUSED
|
|
case ECONNREFUSED: return "connection refused";
|
|
#endif
|
|
#ifdef ECONNRESET
|
|
case ECONNRESET: return "connection reset by peer";
|
|
#endif
|
|
#if defined(EDEADLK) && (!defined(EWOULDBLOCK) || (EDEADLK != EWOULDBLOCK))
|
|
case EDEADLK: return "resource deadlock avoided";
|
|
#endif
|
|
#ifdef EDEADLOCK
|
|
case EDEADLOCK: return "resource deadlock avoided";
|
|
#endif
|
|
#ifdef EDESTADDRREQ
|
|
case EDESTADDRREQ: return "destination address required";
|
|
#endif
|
|
#ifdef EDIRTY
|
|
case EDIRTY: return "mounting a dirty fs w/o force";
|
|
#endif
|
|
#ifdef EDOM
|
|
case EDOM: return "math argument out of range";
|
|
#endif
|
|
#ifdef EDOTDOT
|
|
case EDOTDOT: return "cross mount point";
|
|
#endif
|
|
#ifdef EDQUOT
|
|
case EDQUOT: return "disk quota exceeded";
|
|
#endif
|
|
#ifdef EDUPPKG
|
|
case EDUPPKG: return "duplicate package name";
|
|
#endif
|
|
#ifdef EEXIST
|
|
case EEXIST: return "file already exists";
|
|
#endif
|
|
#ifdef EFAULT
|
|
case EFAULT: return "bad address in system call argument";
|
|
#endif
|
|
#ifdef EFBIG
|
|
case EFBIG: return "file too large";
|
|
#endif
|
|
#ifdef EHOSTDOWN
|
|
case EHOSTDOWN: return "host is down";
|
|
#endif
|
|
#ifdef EHOSTUNREACH
|
|
case EHOSTUNREACH: return "host is unreachable";
|
|
#endif
|
|
#ifdef EIDRM
|
|
case EIDRM: return "identifier removed";
|
|
#endif
|
|
#ifdef EINIT
|
|
case EINIT: return "initialization error";
|
|
#endif
|
|
#ifdef EINPROGRESS
|
|
case EINPROGRESS: return "operation now in progress";
|
|
#endif
|
|
#ifdef EINTR
|
|
case EINTR: return "interrupted system call";
|
|
#endif
|
|
#ifdef EINVAL
|
|
case EINVAL: return "invalid argument";
|
|
#endif
|
|
#ifdef EIO
|
|
case EIO: return "I/O error";
|
|
#endif
|
|
#ifdef EISCONN
|
|
case EISCONN: return "socket is already connected";
|
|
#endif
|
|
#ifdef EISDIR
|
|
case EISDIR: return "illegal operation on a directory";
|
|
#endif
|
|
#ifdef EISNAME
|
|
case EISNAM: return "is a name file";
|
|
#endif
|
|
#ifdef ELBIN
|
|
case ELBIN: return "ELBIN";
|
|
#endif
|
|
#ifdef EL2HLT
|
|
case EL2HLT: return "level 2 halted";
|
|
#endif
|
|
#ifdef EL2NSYNC
|
|
case EL2NSYNC: return "level 2 not synchronized";
|
|
#endif
|
|
#ifdef EL3HLT
|
|
case EL3HLT: return "level 3 halted";
|
|
#endif
|
|
#ifdef EL3RST
|
|
case EL3RST: return "level 3 reset";
|
|
#endif
|
|
#ifdef ELIBACC
|
|
case ELIBACC: return "can not access a needed shared library";
|
|
#endif
|
|
#ifdef ELIBBAD
|
|
case ELIBBAD: return "accessing a corrupted shared library";
|
|
#endif
|
|
#ifdef ELIBEXEC
|
|
case ELIBEXEC: return "can not exec a shared library directly";
|
|
#endif
|
|
#ifdef ELIBMAX
|
|
case ELIBMAX: return "attempting to link in more shared libraries than system limit";
|
|
#endif
|
|
#ifdef ELIBSCN
|
|
case ELIBSCN: return ".lib section in a.out corrupted";
|
|
#endif
|
|
#ifdef ELNRNG
|
|
case ELNRNG: return "link number out of range";
|
|
#endif
|
|
#ifdef ELOOP
|
|
case ELOOP: return "too many levels of symbolic links";
|
|
#endif
|
|
#ifdef EMFILE
|
|
case EMFILE: return "too many open files";
|
|
#endif
|
|
#ifdef EMLINK
|
|
case EMLINK: return "too many links";
|
|
#endif
|
|
#ifdef EMSGSIZE
|
|
case EMSGSIZE: return "message too long";
|
|
#endif
|
|
#ifdef EMULTIHOP
|
|
case EMULTIHOP: return "multihop attempted";
|
|
#endif
|
|
#ifdef ENAMETOOLONG
|
|
case ENAMETOOLONG: return "file name too long";
|
|
#endif
|
|
#ifdef ENAVAIL
|
|
case ENAVAIL: return "not available";
|
|
#endif
|
|
#ifdef ENET
|
|
case ENET: return "ENET";
|
|
#endif
|
|
#ifdef ENETDOWN
|
|
case ENETDOWN: return "network is down";
|
|
#endif
|
|
#ifdef ENETRESET
|
|
case ENETRESET: return "network dropped connection on reset";
|
|
#endif
|
|
#ifdef ENETUNREACH
|
|
case ENETUNREACH: return "network is unreachable";
|
|
#endif
|
|
#ifdef ENFILE
|
|
case ENFILE: return "file table overflow";
|
|
#endif
|
|
#ifdef ENOANO
|
|
case ENOANO: return "anode table overflow";
|
|
#endif
|
|
#if defined(ENOBUFS) && (!defined(ENOSR) || (ENOBUFS != ENOSR))
|
|
case ENOBUFS: return "no buffer space available";
|
|
#endif
|
|
#ifdef ENOCSI
|
|
case ENOCSI: return "no CSI structure available";
|
|
#endif
|
|
#ifdef ENODATA
|
|
case ENODATA: return "no data available";
|
|
#endif
|
|
#ifdef ENODEV
|
|
case ENODEV: return "no such device";
|
|
#endif
|
|
#ifdef ENOENT
|
|
case ENOENT: return "no such file or directory";
|
|
#endif
|
|
#ifdef ENOEXEC
|
|
case ENOEXEC: return "exec format error";
|
|
#endif
|
|
#ifdef ENOLCK
|
|
case ENOLCK: return "no locks available";
|
|
#endif
|
|
#ifdef ENOLINK
|
|
case ENOLINK: return "link has be severed";
|
|
#endif
|
|
#ifdef ENOMEM
|
|
case ENOMEM: return "not enough memory";
|
|
#endif
|
|
#ifdef ENOMSG
|
|
case ENOMSG: return "no message of desired type";
|
|
#endif
|
|
#ifdef ENONET
|
|
case ENONET: return "machine is not on the network";
|
|
#endif
|
|
#ifdef ENOPKG
|
|
case ENOPKG: return "package not installed";
|
|
#endif
|
|
#ifdef ENOPROTOOPT
|
|
case ENOPROTOOPT: return "bad proocol option";
|
|
#endif
|
|
#ifdef ENOSPC
|
|
case ENOSPC: return "no space left on device";
|
|
#endif
|
|
#ifdef ENOSR
|
|
case ENOSR: return "out of stream resources";
|
|
#endif
|
|
#ifdef ENOSTR
|
|
case ENOSTR: return "not a stream device";
|
|
#endif
|
|
#ifdef ENOSYM
|
|
case ENOSYM: return "unresolved symbol name";
|
|
#endif
|
|
#ifdef ENOSYS
|
|
case ENOSYS: return "function not implemented";
|
|
#endif
|
|
#ifdef ENOTBLK
|
|
case ENOTBLK: return "block device required";
|
|
#endif
|
|
#ifdef ENOTCONN
|
|
case ENOTCONN: return "socket is not connected";
|
|
#endif
|
|
#ifdef ENOTDIR
|
|
case ENOTDIR: return "not a directory";
|
|
#endif
|
|
#ifdef ENOTEMPTY
|
|
case ENOTEMPTY: return "directory not empty";
|
|
#endif
|
|
#ifdef ENOTNAM
|
|
case ENOTNAM: return "not a name file";
|
|
#endif
|
|
#ifdef ENOTSOCK
|
|
case ENOTSOCK: return "socket operation on non-socket";
|
|
#endif
|
|
#ifdef ENOTTY
|
|
case ENOTTY: return "inappropriate device for ioctl";
|
|
#endif
|
|
#ifdef ENOTUNIQ
|
|
case ENOTUNIQ: return "name not unique on network";
|
|
#endif
|
|
#ifdef ENXIO
|
|
case ENXIO: return "no such device or address";
|
|
#endif
|
|
#ifdef EOPNOTSUPP
|
|
case EOPNOTSUPP: return "operation not supported on socket";
|
|
#endif
|
|
#ifdef EPERM
|
|
case EPERM: return "not owner";
|
|
#endif
|
|
#ifdef EPFNOSUPPORT
|
|
case EPFNOSUPPORT: return "protocol family not supported";
|
|
#endif
|
|
#ifdef EPIPE
|
|
case EPIPE: return "broken pipe";
|
|
#endif
|
|
#ifdef EPROCLIM
|
|
case EPROCLIM: return "too many processes";
|
|
#endif
|
|
#ifdef EPROCUNAVAIL
|
|
case EPROCUNAVAIL: return "bad procedure for program";
|
|
#endif
|
|
#ifdef EPROGMISMATCH
|
|
case EPROGMISMATCH: return "program version wrong";
|
|
#endif
|
|
#ifdef EPROGUNAVAIL
|
|
case EPROGUNAVAIL: return "RPC program not available";
|
|
#endif
|
|
#ifdef EPROTO
|
|
case EPROTO: return "protocol error";
|
|
#endif
|
|
#ifdef EPROTONOSUPPORT
|
|
case EPROTONOSUPPORT: return "protocol not suppored";
|
|
#endif
|
|
#ifdef EPROTOTYPE
|
|
case EPROTOTYPE: return "protocol wrong type for socket";
|
|
#endif
|
|
#ifdef ERANGE
|
|
case ERANGE: return "math result unrepresentable";
|
|
#endif
|
|
#if defined(EREFUSED) && (!defined(ECONNREFUSED) || (EREFUSED != ECONNREFUSED))
|
|
case EREFUSED: return "EREFUSED";
|
|
#endif
|
|
#ifdef EREMCHG
|
|
case EREMCHG: return "remote address changed";
|
|
#endif
|
|
#ifdef EREMDEV
|
|
case EREMDEV: return "remote device";
|
|
#endif
|
|
#ifdef EREMOTE
|
|
case EREMOTE: return "pathname hit remote file system";
|
|
#endif
|
|
#ifdef EREMOTEIO
|
|
case EREMOTEIO: return "remote i/o error";
|
|
#endif
|
|
#ifdef EREMOTERELEASE
|
|
case EREMOTERELEASE: return "EREMOTERELEASE";
|
|
#endif
|
|
#ifdef EROFS
|
|
case EROFS: return "read-only file system";
|
|
#endif
|
|
#ifdef ERPCMISMATCH
|
|
case ERPCMISMATCH: return "RPC version is wrong";
|
|
#endif
|
|
#ifdef ERREMOTE
|
|
case ERREMOTE: return "object is remote";
|
|
#endif
|
|
#ifdef ESHUTDOWN
|
|
case ESHUTDOWN: return "can't send afer socket shutdown";
|
|
#endif
|
|
#ifdef ESOCKTNOSUPPORT
|
|
case ESOCKTNOSUPPORT: return "socket type not supported";
|
|
#endif
|
|
#ifdef ESPIPE
|
|
case ESPIPE: return "invalid seek";
|
|
#endif
|
|
#ifdef ESRCH
|
|
case ESRCH: return "no such process";
|
|
#endif
|
|
#ifdef ESRMNT
|
|
case ESRMNT: return "srmount error";
|
|
#endif
|
|
#ifdef ESTALE
|
|
case ESTALE: return "stale remote file handle";
|
|
#endif
|
|
#ifdef ESUCCESS
|
|
case ESUCCESS: return "Error 0";
|
|
#endif
|
|
#ifdef ETIME
|
|
case ETIME: return "timer expired";
|
|
#endif
|
|
#ifdef ETIMEDOUT
|
|
case ETIMEDOUT: return "connection timed out";
|
|
#endif
|
|
#ifdef ETOOMANYREFS
|
|
case ETOOMANYREFS: return "too many references: can't splice";
|
|
#endif
|
|
#ifdef ETXTBSY
|
|
case ETXTBSY: return "text file or pseudo-device busy";
|
|
#endif
|
|
#ifdef EUCLEAN
|
|
case EUCLEAN: return "structure needs cleaning";
|
|
#endif
|
|
#ifdef EUNATCH
|
|
case EUNATCH: return "protocol driver not attached";
|
|
#endif
|
|
#ifdef EUSERS
|
|
case EUSERS: return "too many users";
|
|
#endif
|
|
#ifdef EVERSION
|
|
case EVERSION: return "version mismatch";
|
|
#endif
|
|
#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
|
|
case EWOULDBLOCK: return "operation would block";
|
|
#endif
|
|
#ifdef EXDEV
|
|
case EXDEV: return "cross-domain link";
|
|
#endif
|
|
#ifdef EXFULL
|
|
case EXFULL: return "message tables full";
|
|
#endif
|
|
}
|
|
#else /* NO_SYS_ERRLIST */
|
|
extern int sys_nerr;
|
|
extern char *sys_errlist[];
|
|
|
|
if ((errnum > 0) && (errnum <= sys_nerr))
|
|
return sys_errlist [errnum];
|
|
#endif /* NO_SYS_ERRLIST */
|
|
|
|
sprintf (msg, "unknown error (%d)", errnum);
|
|
return msg;
|
|
}
|
|
|
|
gchar*
|
|
g_strsignal (gint signum)
|
|
{
|
|
static char msg[64];
|
|
|
|
#ifdef HAVE_STRSIGNAL
|
|
extern char *strsignal (int sig);
|
|
return strsignal (signum);
|
|
#elif NO_SYS_SIGLIST
|
|
switch (signum)
|
|
{
|
|
#ifdef SIGHUP
|
|
case SIGHUP: return "Hangup";
|
|
#endif
|
|
#ifdef SIGINT
|
|
case SIGINT: return "Interrupt";
|
|
#endif
|
|
#ifdef SIGQUIT
|
|
case SIGQUIT: return "Quit";
|
|
#endif
|
|
#ifdef SIGILL
|
|
case SIGILL: return "Illegal instruction";
|
|
#endif
|
|
#ifdef SIGTRAP
|
|
case SIGTRAP: return "Trace/breakpoint trap";
|
|
#endif
|
|
#ifdef SIGABRT
|
|
case SIGABRT: return "IOT trap/Abort";
|
|
#endif
|
|
#ifdef SIGBUS
|
|
case SIGBUS: return "Bus error";
|
|
#endif
|
|
#ifdef SIGFPE
|
|
case SIGFPE: return "Floating point exception";
|
|
#endif
|
|
#ifdef SIGKILL
|
|
case SIGKILL: return "Killed";
|
|
#endif
|
|
#ifdef SIGUSR1
|
|
case SIGUSR1: return "User defined signal 1";
|
|
#endif
|
|
#ifdef SIGSEGV
|
|
case SIGSEGV: return "Segmentation fault";
|
|
#endif
|
|
#ifdef SIGUSR2
|
|
case SIGUSR2: return "User defined signal 2";
|
|
#endif
|
|
#ifdef SIGPIPE
|
|
case SIGPIPE: return "Broken pipe";
|
|
#endif
|
|
#ifdef SIGALRM
|
|
case SIGALRM: return "Alarm clock";
|
|
#endif
|
|
#ifdef SIGTERM
|
|
case SIGTERM: return "Terminated";
|
|
#endif
|
|
#ifdef SIGSTKFLT
|
|
case SIGSTKFLT: return "Stack fault";
|
|
#endif
|
|
#ifdef SIGCHLD
|
|
case SIGCHLD: return "Child exited";
|
|
#endif
|
|
#ifdef SIGCONT
|
|
case SIGCONT: return "Continued";
|
|
#endif
|
|
#ifdef SIGSTOP
|
|
case SIGSTOP: return "Stopped (signal)";
|
|
#endif
|
|
#ifdef SIGTSTP
|
|
case SIGTSTP: return "Stopped";
|
|
#endif
|
|
#ifdef SIGTTIN
|
|
case SIGTTIN: return "Stopped (tty input)";
|
|
#endif
|
|
#ifdef SIGTTOU
|
|
case SIGTTOU: return "Stopped (tty output)";
|
|
#endif
|
|
#ifdef SIGURG
|
|
case SIGURG: return "Urgent condition";
|
|
#endif
|
|
#ifdef SIGXCPU
|
|
case SIGXCPU: return "CPU time limit exceeded";
|
|
#endif
|
|
#ifdef SIGXFSZ
|
|
case SIGXFSZ: return "File size limit exceeded";
|
|
#endif
|
|
#ifdef SIGVTALRM
|
|
case SIGVTALRM: return "Virtual time alarm";
|
|
#endif
|
|
#ifdef SIGPROF
|
|
case SIGPROF: return "Profile signal";
|
|
#endif
|
|
#ifdef SIGWINCH
|
|
case SIGWINCH: return "Window size changed";
|
|
#endif
|
|
#ifdef SIGIO
|
|
case SIGIO: return "Possible I/O";
|
|
#endif
|
|
#ifdef SIGPWR
|
|
case SIGPWR: return "Power failure";
|
|
#endif
|
|
#ifdef SIGUNUSED
|
|
case SIGUNUSED: return "Unused signal";
|
|
#endif
|
|
}
|
|
#else /* NO_SYS_SIGLIST */
|
|
extern char *sys_siglist[];
|
|
return sys_siglist [signum];
|
|
#endif /* NO_SYS_SIGLIST */
|
|
|
|
sprintf (msg, "unknown signal (%d)", signum);
|
|
return msg;
|
|
}
|
|
|
|
guint
|
|
g_printf_string_upper_bound (const gchar* format,
|
|
va_list args)
|
|
{
|
|
guint len = 1;
|
|
|
|
while (*format)
|
|
{
|
|
gboolean long_int = FALSE;
|
|
gboolean extra_long = FALSE;
|
|
gchar c;
|
|
|
|
c = *format++;
|
|
|
|
if (c == '%')
|
|
{
|
|
gboolean done = FALSE;
|
|
|
|
while (*format && !done)
|
|
{
|
|
switch (*format++)
|
|
{
|
|
gchar *string_arg;
|
|
|
|
case '*':
|
|
len += va_arg (args, int);
|
|
break;
|
|
case '1':
|
|
case '2':
|
|
case '3':
|
|
case '4':
|
|
case '5':
|
|
case '6':
|
|
case '7':
|
|
case '8':
|
|
case '9':
|
|
/* add specified format length, since it might exceed the
|
|
* size we assume it to have.
|
|
*/
|
|
format -= 1;
|
|
len += strtol (format, (char**) &format, 10);
|
|
break;
|
|
case 'h':
|
|
/* ignore short int flag, since all args have at least the
|
|
* same size as an int
|
|
*/
|
|
break;
|
|
case 'l':
|
|
if (long_int)
|
|
extra_long = TRUE; /* linux specific */
|
|
else
|
|
long_int = TRUE;
|
|
break;
|
|
case 'q':
|
|
case 'L':
|
|
long_int = TRUE;
|
|
extra_long = TRUE;
|
|
break;
|
|
case 's':
|
|
string_arg = va_arg (args, char *);
|
|
if (string_arg)
|
|
len += strlen (string_arg);
|
|
else
|
|
{
|
|
/* add enough padding to hold "(null)" identifier */
|
|
len += 16;
|
|
}
|
|
done = TRUE;
|
|
break;
|
|
case 'd':
|
|
case 'i':
|
|
case 'o':
|
|
case 'u':
|
|
case 'x':
|
|
case 'X':
|
|
#ifdef HAVE_GINT64
|
|
if (extra_long)
|
|
(void) va_arg (args, gint64);
|
|
else
|
|
#endif /* HAVE_GINT64 */
|
|
{
|
|
if (long_int)
|
|
(void) va_arg (args, long);
|
|
else
|
|
(void) va_arg (args, int);
|
|
}
|
|
len += extra_long ? 64 : 32;
|
|
done = TRUE;
|
|
break;
|
|
case 'D':
|
|
case 'O':
|
|
case 'U':
|
|
(void) va_arg (args, long);
|
|
len += 32;
|
|
done = TRUE;
|
|
break;
|
|
case 'e':
|
|
case 'E':
|
|
case 'f':
|
|
case 'g':
|
|
#ifdef HAVE_LONG_DOUBLE
|
|
if (extra_long)
|
|
(void) va_arg (args, long double);
|
|
else
|
|
#endif /* HAVE_LONG_DOUBLE */
|
|
(void) va_arg (args, double);
|
|
len += extra_long ? 64 : 32;
|
|
done = TRUE;
|
|
break;
|
|
case 'c':
|
|
(void) va_arg (args, int);
|
|
len += 1;
|
|
done = TRUE;
|
|
break;
|
|
case 'p':
|
|
case 'n':
|
|
(void) va_arg (args, void*);
|
|
len += 32;
|
|
done = TRUE;
|
|
break;
|
|
case '%':
|
|
len += 1;
|
|
done = TRUE;
|
|
break;
|
|
default:
|
|
/* ignore unknow/invalid flags */
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
len += 1;
|
|
}
|
|
|
|
return len;
|
|
}
|
|
|
|
void
|
|
g_strdown (gchar *string)
|
|
{
|
|
register gchar *s;
|
|
|
|
g_return_if_fail (string != NULL);
|
|
|
|
s = string;
|
|
|
|
while (*s)
|
|
{
|
|
*s = tolower (*s);
|
|
s++;
|
|
}
|
|
}
|
|
|
|
void
|
|
g_strup (gchar *string)
|
|
{
|
|
register gchar *s;
|
|
|
|
g_return_if_fail (string != NULL);
|
|
|
|
s = string;
|
|
|
|
while (*s)
|
|
{
|
|
*s = toupper (*s);
|
|
s++;
|
|
}
|
|
}
|
|
|
|
void
|
|
g_strreverse (gchar *string)
|
|
{
|
|
g_return_if_fail (string != NULL);
|
|
|
|
if (*string)
|
|
{
|
|
register gchar *h, *t;
|
|
|
|
h = string;
|
|
t = string + strlen (string) - 1;
|
|
|
|
while (h < t)
|
|
{
|
|
register gchar c;
|
|
|
|
c = *h;
|
|
*h = *t;
|
|
h++;
|
|
*t = c;
|
|
t--;
|
|
}
|
|
}
|
|
}
|
|
|
|
gint
|
|
g_strcasecmp (const gchar *s1,
|
|
const gchar *s2)
|
|
{
|
|
#ifdef HAVE_STRCASECMP
|
|
return strcasecmp (s1, s2);
|
|
#else
|
|
gint c1, c2;
|
|
|
|
g_return_val_if_fail (s1 != NULL, 0);
|
|
g_return_val_if_fail (s2 != NULL, 0);
|
|
|
|
while (*s1 && *s2)
|
|
{
|
|
/* According to A. Cox, some platforms have islower's that
|
|
* don't work right on non-uppercase
|
|
*/
|
|
c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1;
|
|
c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2;
|
|
if (c1 != c2)
|
|
return (c1 - c2);
|
|
s1++; s2++;
|
|
}
|
|
|
|
return (((gint)(guchar) *s1) - ((gint)(guchar) *s2));
|
|
#endif
|
|
}
|
|
|
|
gchar*
|
|
g_strdelimit (gchar *string,
|
|
const gchar *delimiters,
|
|
gchar new_delim)
|
|
{
|
|
register gchar *c;
|
|
|
|
g_return_val_if_fail (string != NULL, NULL);
|
|
|
|
if (!delimiters)
|
|
delimiters = G_STR_DELIMITERS;
|
|
|
|
for (c = string; *c; c++)
|
|
{
|
|
if (strchr (delimiters, *c))
|
|
*c = new_delim;
|
|
}
|
|
|
|
return string;
|
|
}
|
|
|
|
gchar*
|
|
g_strescape (gchar *string)
|
|
{
|
|
gchar *q;
|
|
gchar *escaped;
|
|
guint backslashes = 0;
|
|
gchar *p = string;
|
|
|
|
g_return_val_if_fail (string != NULL, NULL);
|
|
|
|
while (*p != '\000')
|
|
backslashes += (*p++ == '\\');
|
|
|
|
if (!backslashes)
|
|
return g_strdup (string);
|
|
|
|
escaped = g_new (gchar, strlen (string) + backslashes + 1);
|
|
|
|
p = string;
|
|
q = escaped;
|
|
|
|
while (*p != '\000')
|
|
{
|
|
if (*p == '\\')
|
|
*q++ = '\\';
|
|
*q++ = *p++;
|
|
}
|
|
*q = '\000';
|
|
|
|
return escaped;
|
|
}
|
|
|
|
/* blame Elliot for these next five routines */
|
|
gchar*
|
|
g_strchug (gchar *string)
|
|
{
|
|
gchar *start;
|
|
|
|
g_return_val_if_fail (string != NULL, NULL);
|
|
|
|
for (start = string; *start && isspace (*start); start++)
|
|
;
|
|
|
|
strcpy (string, start);
|
|
|
|
return string;
|
|
}
|
|
|
|
gchar*
|
|
g_strchomp (gchar *string)
|
|
{
|
|
gchar *s;
|
|
|
|
g_return_val_if_fail (string != NULL, NULL);
|
|
|
|
if (!*string)
|
|
return string;
|
|
|
|
for (s = string + strlen (string) - 1; s >= string && isspace (*s); s--)
|
|
*s = '\0';
|
|
|
|
return string;
|
|
}
|
|
|
|
gchar**
|
|
g_strsplit (const gchar *string,
|
|
const gchar *delimiter,
|
|
gint max_tokens)
|
|
{
|
|
GSList *string_list = NULL, *slist;
|
|
gchar **str_array, *s;
|
|
guint i, n = 1;
|
|
|
|
g_return_val_if_fail (string != NULL, NULL);
|
|
g_return_val_if_fail (delimiter != NULL, NULL);
|
|
|
|
if (max_tokens < 1)
|
|
max_tokens = G_MAXINT;
|
|
|
|
s = strstr (string, delimiter);
|
|
if (s)
|
|
{
|
|
guint delimiter_len = strlen (delimiter);
|
|
|
|
do
|
|
{
|
|
guint len;
|
|
gchar *new_string;
|
|
|
|
len = s - string;
|
|
new_string = g_new (gchar, len + 1);
|
|
strncpy (new_string, string, len);
|
|
new_string[len] = 0;
|
|
string_list = g_slist_prepend (string_list, new_string);
|
|
n++;
|
|
string = s + delimiter_len;
|
|
s = strstr (string, delimiter);
|
|
}
|
|
while (--max_tokens && s);
|
|
}
|
|
if (*string)
|
|
{
|
|
n++;
|
|
string_list = g_slist_prepend (string_list, g_strdup (string));
|
|
}
|
|
|
|
str_array = g_new (gchar*, n);
|
|
|
|
i = n - 1;
|
|
|
|
str_array[i--] = NULL;
|
|
for (slist = string_list; slist; slist = slist->next)
|
|
str_array[i--] = slist->data;
|
|
|
|
g_slist_free (string_list);
|
|
|
|
return str_array;
|
|
}
|
|
|
|
void
|
|
g_strfreev (gchar **str_array)
|
|
{
|
|
if (str_array)
|
|
{
|
|
int i;
|
|
|
|
for(i = 0; str_array[i] != NULL; i++)
|
|
g_free(str_array[i]);
|
|
|
|
g_free (str_array);
|
|
}
|
|
}
|
|
|
|
gchar*
|
|
g_strjoinv (const gchar *separator,
|
|
gchar **str_array)
|
|
{
|
|
gchar *string;
|
|
|
|
g_return_val_if_fail (str_array != NULL, NULL);
|
|
|
|
if(separator == NULL)
|
|
separator = "";
|
|
|
|
if (*str_array)
|
|
{
|
|
guint i, len;
|
|
guint separator_len;
|
|
|
|
separator_len = strlen (separator);
|
|
len = 1 + strlen (str_array[0]);
|
|
for(i = 1; str_array[i] != NULL; i++)
|
|
len += separator_len + strlen(str_array[i]);
|
|
|
|
string = g_new (gchar, len);
|
|
*string = 0;
|
|
strcat (string, *str_array);
|
|
for (i = 1; str_array[i] != NULL; i++)
|
|
{
|
|
strcat (string, separator);
|
|
strcat (string, str_array[i]);
|
|
}
|
|
}
|
|
else
|
|
string = g_strdup ("");
|
|
|
|
return string;
|
|
}
|
|
|
|
gchar*
|
|
g_strjoin (const gchar *separator,
|
|
...)
|
|
{
|
|
gchar *string, *s;
|
|
va_list args;
|
|
guint len;
|
|
guint separator_len;
|
|
|
|
if(separator == NULL)
|
|
separator = "";
|
|
|
|
separator_len = strlen (separator);
|
|
|
|
va_start(args, separator);
|
|
|
|
s = va_arg(args, gchar *);
|
|
|
|
if(s) {
|
|
len = strlen(s) + 1;
|
|
|
|
while((s = va_arg(args, gchar*)))
|
|
{
|
|
len += separator_len + strlen(s);
|
|
}
|
|
va_end(args);
|
|
|
|
string = g_new (gchar, len);
|
|
|
|
va_start(args, separator);
|
|
|
|
*string = 0;
|
|
s = va_arg(args, gchar*);
|
|
strcat (string, s);
|
|
|
|
while((s = va_arg(args, gchar*)))
|
|
{
|
|
strcat(string, separator);
|
|
strcat(string, s);
|
|
}
|
|
|
|
} else
|
|
string = g_strdup("");
|
|
|
|
va_end(args);
|
|
|
|
return string;
|
|
}
|