1998-07-10 07:51:57 +02:00
|
|
|
/* 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
|
2000-07-26 13:02:02 +02:00
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
1998-07-10 07:51:57 +02:00
|
|
|
* 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
|
2000-07-26 13:02:02 +02:00
|
|
|
* Lesser General Public License for more details.
|
1998-07-10 07:51:57 +02:00
|
|
|
*
|
2000-07-26 13:02:02 +02:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
1998-07-10 07:51:57 +02:00
|
|
|
* License along with this library; if not, write to the
|
|
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
* Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
1998-11-01 02:32:59 +01:00
|
|
|
|
1999-02-24 07:14:27 +01:00
|
|
|
/*
|
2000-07-26 13:02:02 +02:00
|
|
|
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
|
1999-02-24 07:14:27 +01:00
|
|
|
* file for a list of people on the GLib Team. See the ChangeLog
|
|
|
|
* files for a list of changes. These files are distributed with
|
|
|
|
* GLib at ftp://ftp.gtk.org/pub/gtk/.
|
|
|
|
*/
|
|
|
|
|
1999-01-19 10:07:28 +01:00
|
|
|
/*
|
1998-12-15 06:28:02 +01:00
|
|
|
* MT safe
|
|
|
|
*/
|
|
|
|
|
1998-11-01 02:32:59 +01:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include <config.h>
|
|
|
|
#endif
|
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <locale.h>
|
|
|
|
#include <ctype.h> /* For tolower() */
|
1999-01-25 13:45:51 +01:00
|
|
|
#if !defined (HAVE_STRSIGNAL) || !defined(NO_SYS_SIGLIST_DECL)
|
Merge in current Win32 version. Almost no Unix code touched.
* README.win32: More text.
* config.h.win32 glibconfig.h.win32: Update to match the
corresponding generated files on Unix.
* makefile.msc: Update with new source files, and gthread
library. Use the compiler flag -MD instead of using -D_DLL and
"/nodefaultlib:libc msvcrt.lib" in the link phase.
* glib.def: Include new functions, drop removed ones.
* glib.h: Add comments about main loop and polling on Win32. (In
general, it's only for the GIMP's use.) Add Win32 IO Channel
functions. Remove the obsoleted old IO Channel stuff (which was
in #if 0 already).
* giowin32.c: New file.
* gmain.c: Include config.h, conditionalize <sys/time.h>
inclusion. Add g_poll implementation for Win32 (only for the
GIMP's needs for now, it's hard or even impossible to be as clean
and generic as on Unix). Implement g_get_current_time on Win32. If
threads aren't supported, don't try to wake up main thread's
loop. On Win32, use a semaphore and not a pipe to wake up the main
loop.
* gmessages.c: On Win32, allocate a console window if the standard
output handle is invalid before writing to stdout, and reopen stdout
to that console window.
* giochannel.c: Conditionalize unistd.h inclusion. Some indentation
cleanup.
* gstrfuncs.c: Include <signal.h>.
* gutils.c: On Win32, also check the HOMEDRIVE and HOMEPATH
environment variables.
* gmodule-dl.c gmodule-dld.c: In
_g_module_build_path, don't add the "lib" prefix and
".so" or ".sl" suffix if already there.
* gmodule-win32.c: Likewise for the ".dll" suffix.
* gthread-posix.c: Conditionalize <sys/time.h> inclusion.
1999-01-17 00:46:42 +01:00
|
|
|
#include <signal.h>
|
1999-01-21 06:43:40 +01:00
|
|
|
#endif
|
1998-07-10 07:51:57 +02:00
|
|
|
#include "glib.h"
|
2000-02-03 00:39:32 +01:00
|
|
|
|
|
|
|
#ifdef G_OS_WIN32
|
|
|
|
#include <windows.h>
|
|
|
|
#endif
|
|
|
|
|
1998-07-11 07:17:49 +02:00
|
|
|
/* do not include <unistd.h> in this place since it
|
1998-07-10 07:51:57 +02:00
|
|
|
* inteferes with g_strsignal() on some OSes
|
|
|
|
*/
|
|
|
|
|
|
|
|
gchar*
|
|
|
|
g_strdup (const gchar *str)
|
|
|
|
{
|
|
|
|
gchar *new_str;
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
if (str)
|
|
|
|
{
|
|
|
|
new_str = g_new (char, strlen (str) + 1);
|
|
|
|
strcpy (new_str, str);
|
|
|
|
}
|
1998-09-02 16:57:10 +02:00
|
|
|
else
|
|
|
|
new_str = NULL;
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
return new_str;
|
|
|
|
}
|
|
|
|
|
1998-09-19 03:12:06 +02:00
|
|
|
gpointer
|
|
|
|
g_memdup (gconstpointer mem,
|
|
|
|
guint byte_size)
|
1998-09-18 20:32:59 +02:00
|
|
|
{
|
1998-09-19 03:12:06 +02:00
|
|
|
gpointer new_mem;
|
|
|
|
|
|
|
|
if (mem)
|
|
|
|
{
|
|
|
|
new_mem = g_malloc (byte_size);
|
|
|
|
memcpy (new_mem, mem, byte_size);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
new_mem = NULL;
|
|
|
|
|
|
|
|
return new_mem;
|
1998-09-18 20:32:59 +02:00
|
|
|
}
|
|
|
|
|
1998-08-19 03:24:13 +02:00
|
|
|
gchar*
|
1998-09-02 16:57:10 +02:00
|
|
|
g_strndup (const gchar *str,
|
|
|
|
guint n)
|
1998-08-19 03:24:13 +02:00
|
|
|
{
|
1998-09-02 16:57:10 +02:00
|
|
|
gchar *new_str;
|
1998-08-19 03:24:13 +02:00
|
|
|
|
|
|
|
if (str)
|
|
|
|
{
|
1998-09-02 16:57:10 +02:00
|
|
|
new_str = g_new (gchar, n + 1);
|
1998-08-19 03:24:13 +02:00
|
|
|
strncpy (new_str, str, n);
|
|
|
|
new_str[n] = '\0';
|
|
|
|
}
|
1998-09-02 16:57:10 +02:00
|
|
|
else
|
|
|
|
new_str = NULL;
|
1998-08-19 03:24:13 +02:00
|
|
|
|
|
|
|
return new_str;
|
|
|
|
}
|
|
|
|
|
1998-09-02 16:57:10 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
removed this function which was not publically exported in glib.h. to
Mon Aug 24 02:08:56 1998 Tim Janik <timj@gtk.org>
* glib.h:
* gstring.c:
* gstrfuncs.c:
(g_vsprintf): removed this function which was not publically
exported in glib.h. to export it, it should have been named
differently in the first place, since its semantics differ from
vsprintf(). apart from that, it was a possible cause for
problems since it worked on a previously allocated memory area and
was used in a lot places of glib. exporting it would have been a
guararant for problems with threaded programs.
(g_printf_string_upper_bound): exported this function to return
a string size, guarranteed to be big enough to hold the fully
expanded format+args string. added 'q', 'L' and 'll' flag handling.
in fact, the newly allocated area is in most cases much bigger than
required.
(g_strdup_vprintf()): new function returning a newly allocated string
containing the contents of *format and associated args (size is
calculated with g_printf_string_upper_bound()).
(g_strdup_printf): new function which wraps g_strdup_vprintf().
* configure.in: check for va_copy() or __va_copy() alternatively.
check whether va_lists can be copyied by value.
* glib.h: provide a definition for G_VA_COPY.
* glib.h:
* gmessages.c:
(g_logv):
(g_vsnprintf):
pass va_lists by value, not by reference, since this causes problems
on platforms that implement va_list as as arrays. internaly, use
G_VA_COPY (new_arg, org_arg); va_end (new_arg); to produce a second
va_list variable, if multiple passes are required. changed all
callers.
* glib.h:
* gerror.h:
renamed g_debug() to g_on_error_query(), cleaned up a bit.
renamed g_stack_trace() to g_on_error_stack_trace() since both
functions cluttered different namespaces.
there is an appropriate comment in glib.h now that explains the
unix and gdb specific dependencies of both functions.
removed g_attach_process().
g_on_error_stack_trace() should probably be handled with caution,
i've seem several different linux versions (2.0.x) become unstable
after invokation of this function.
1998-08-24 07:26:53 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
gchar*
|
|
|
|
g_strconcat (const gchar *string1, ...)
|
|
|
|
{
|
|
|
|
guint l;
|
|
|
|
va_list args;
|
|
|
|
gchar *s;
|
|
|
|
gchar *concat;
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
g_return_val_if_fail (string1 != NULL, NULL);
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
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);
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
concat = g_new (gchar, l);
|
|
|
|
concat[0] = 0;
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
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);
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
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;
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
g_return_val_if_fail (nptr != NULL, 0);
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
fail_pos_1 = NULL;
|
|
|
|
fail_pos_2 = NULL;
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
val_1 = strtod (nptr, &fail_pos_1);
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
if (fail_pos_1 && fail_pos_1[0] != 0)
|
|
|
|
{
|
|
|
|
gchar *old_locale;
|
1999-01-19 10:07:28 +01:00
|
|
|
|
2000-01-09 11:58:55 +01:00
|
|
|
old_locale = g_strdup (setlocale (LC_NUMERIC, NULL));
|
|
|
|
setlocale (LC_NUMERIC, "C");
|
1998-07-10 07:51:57 +02:00
|
|
|
val_2 = strtod (nptr, &fail_pos_2);
|
|
|
|
setlocale (LC_NUMERIC, old_locale);
|
2000-01-09 11:58:55 +01:00
|
|
|
g_free (old_locale);
|
1998-07-10 07:51:57 +02:00
|
|
|
}
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
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)
|
|
|
|
{
|
1999-01-19 10:07:28 +01:00
|
|
|
static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
|
1998-12-15 06:28:02 +01:00
|
|
|
char *msg;
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
#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[];
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
if ((errnum > 0) && (errnum <= sys_nerr))
|
|
|
|
return sys_errlist [errnum];
|
|
|
|
#endif /* NO_SYS_ERRLIST */
|
1998-12-15 06:28:02 +01:00
|
|
|
|
|
|
|
msg = g_static_private_get (&msg_private);
|
1999-02-10 09:06:26 +01:00
|
|
|
if (!msg)
|
1998-12-15 06:28:02 +01:00
|
|
|
{
|
1999-02-10 09:06:26 +01:00
|
|
|
msg = g_new (gchar, 64);
|
1998-12-15 06:28:02 +01:00
|
|
|
g_static_private_set (&msg_private, msg, g_free);
|
|
|
|
}
|
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
sprintf (msg, "unknown error (%d)", errnum);
|
1999-02-10 09:06:26 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
return msg;
|
|
|
|
}
|
|
|
|
|
|
|
|
gchar*
|
|
|
|
g_strsignal (gint signum)
|
|
|
|
{
|
1999-01-19 10:07:28 +01:00
|
|
|
static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
|
1998-12-15 06:28:02 +01:00
|
|
|
char *msg;
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
#ifdef HAVE_STRSIGNAL
|
1999-10-04 04:32:50 +02:00
|
|
|
#ifdef G_OS_BEOS
|
1999-05-08 09:40:44 +02:00
|
|
|
extern const char * strsignal(int);
|
1999-10-04 04:32:50 +02:00
|
|
|
#else /* !G_OS_BEOS */
|
1999-05-08 09:40:44 +02:00
|
|
|
/* this is declared differently (const) in string.h on BeOS */
|
1998-07-10 07:51:57 +02:00
|
|
|
extern char *strsignal (int sig);
|
1999-10-04 04:32:50 +02:00
|
|
|
#endif /* !G_OS_BEOS */
|
1998-07-10 07:51:57 +02:00
|
|
|
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 */
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1999-01-25 13:45:51 +01:00
|
|
|
#ifdef NO_SYS_SIGLIST_DECL
|
|
|
|
extern char *sys_siglist[]; /*(see Tue Jan 19 00:44:24 1999 in changelog)*/
|
1999-01-19 10:07:28 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
return (char*) /* this function should return const --josh */ sys_siglist [signum];
|
1998-07-10 07:51:57 +02:00
|
|
|
#endif /* NO_SYS_SIGLIST */
|
1998-12-15 06:28:02 +01:00
|
|
|
|
|
|
|
msg = g_static_private_get (&msg_private);
|
1999-02-10 09:06:26 +01:00
|
|
|
if (!msg)
|
1998-12-15 06:28:02 +01:00
|
|
|
{
|
1999-02-10 09:06:26 +01:00
|
|
|
msg = g_new (gchar, 64);
|
1998-12-15 06:28:02 +01:00
|
|
|
g_static_private_set (&msg_private, msg, g_free);
|
|
|
|
}
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
sprintf (msg, "unknown signal (%d)", signum);
|
added g_strlcat() and g_strlcpy() wrappers, supplied by David Wheeler
Wed Jul 26 05:47:48 2000 Tim Janik <timj@gtk.org>
* configure.in:
* testglib.c:
* gstrfuncs.c:
* glib.h: added g_strlcat() and g_strlcpy() wrappers, supplied by
David Wheeler <dwheeler@ida.org>:
* glib.h, gstrfuncs.c: added g_strlcpy and g_strlcat to support
safe manipulation of fixed-length string buffers.
These functions were originally developed by Todd Miller to simplify
development of security-related programs, and
are available on many (but not all) Unix-like systems,
including OpenBSD, FreeBSD, and Solaris. See
ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3
and http://www.openbsd.org/security.html.
If there's a strlcpy/strlcat on the system, it's called, otherwise
an implementation is provided.
* testglib.c: Added tests for g_strlcpy, g_strlcat.
2000-07-26 05:51:07 +02:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
return msg;
|
|
|
|
}
|
|
|
|
|
added g_strlcat() and g_strlcpy() wrappers, supplied by David Wheeler
Wed Jul 26 05:47:48 2000 Tim Janik <timj@gtk.org>
* configure.in:
* testglib.c:
* gstrfuncs.c:
* glib.h: added g_strlcat() and g_strlcpy() wrappers, supplied by
David Wheeler <dwheeler@ida.org>:
* glib.h, gstrfuncs.c: added g_strlcpy and g_strlcat to support
safe manipulation of fixed-length string buffers.
These functions were originally developed by Todd Miller to simplify
development of security-related programs, and
are available on many (but not all) Unix-like systems,
including OpenBSD, FreeBSD, and Solaris. See
ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3
and http://www.openbsd.org/security.html.
If there's a strlcpy/strlcat on the system, it's called, otherwise
an implementation is provided.
* testglib.c: Added tests for g_strlcpy, g_strlcat.
2000-07-26 05:51:07 +02:00
|
|
|
/* Functions g_strlcpy and g_strlcat were originally developed by
|
|
|
|
* Todd C. Miller <Todd.Miller@courtesan.com> to simplify writing secure code.
|
|
|
|
* See ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3
|
|
|
|
* for more information.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_STRLCPY
|
|
|
|
/* Use the native ones, if available; they might be implemented in assembly */
|
|
|
|
gsize
|
|
|
|
g_strlcpy (gchar *dest,
|
|
|
|
const gchar *src,
|
|
|
|
gsize dest_size)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (dest != NULL, NULL);
|
|
|
|
g_return_val_if_fail (src != NULL, NULL);
|
|
|
|
|
|
|
|
return strlcpy (dest, src, dest_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
gsize
|
|
|
|
g_strlcat (gchar *dest,
|
|
|
|
const gchar *src,
|
|
|
|
gsize dest_size)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (dest != NULL, NULL);
|
|
|
|
g_return_val_if_fail (src != NULL, NULL);
|
|
|
|
|
|
|
|
return strlcat (dest, src, dest_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
#else /* ! HAVE_STRLCPY */
|
|
|
|
/* g_strlcpy
|
|
|
|
*
|
|
|
|
* Copy string src to buffer dest (of buffer size dest_size). At most
|
|
|
|
* dest_size-1 characters will be copied. Always NUL terminates
|
|
|
|
* (unless dest_size == 0). This function does NOT allocate memory.
|
|
|
|
* Unlike strncpy, this function doesn't pad dest (so it's often faster).
|
|
|
|
* Returns size of attempted result, strlen(src),
|
|
|
|
* so if retval >= dest_size, truncation occurred.
|
|
|
|
*/
|
|
|
|
gsize
|
|
|
|
g_strlcpy (gchar *dest,
|
|
|
|
const gchar *src,
|
|
|
|
gsize dest_size)
|
|
|
|
{
|
|
|
|
register gchar *d = dest;
|
|
|
|
register const gchar *s = src;
|
|
|
|
register gsize n = dest_size;
|
|
|
|
|
|
|
|
g_return_val_if_fail (dest != NULL, NULL);
|
|
|
|
g_return_val_if_fail (src != NULL, NULL);
|
|
|
|
|
|
|
|
/* Copy as many bytes as will fit */
|
|
|
|
if (n != 0 && --n != 0)
|
|
|
|
do
|
|
|
|
{
|
|
|
|
register gchar c = *s++;
|
|
|
|
|
|
|
|
*d++ = c;
|
|
|
|
if (c == 0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
while (--n != 0);
|
|
|
|
|
|
|
|
/* If not enough room in dest, add NUL and traverse rest of src */
|
|
|
|
if (n == 0)
|
|
|
|
{
|
|
|
|
if (dest_size != 0)
|
|
|
|
*d = 0;
|
|
|
|
while (*s++)
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
return s - src - 1; /* count does not include NUL */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* g_strlcat
|
|
|
|
*
|
|
|
|
* Appends string src to buffer dest (of buffer size dest_size).
|
|
|
|
* At most dest_size-1 characters will be copied.
|
|
|
|
* Unlike strncat, dest_size is the full size of dest, not the space left over.
|
|
|
|
* This function does NOT allocate memory.
|
|
|
|
* This always NUL terminates (unless siz == 0 or there were no NUL characters
|
|
|
|
* in the dest_size characters of dest to start with).
|
|
|
|
* Returns size of attempted result, which is
|
|
|
|
* MIN (dest_size, strlen (original dest)) + strlen (src),
|
|
|
|
* so if retval >= dest_size, truncation occurred.
|
|
|
|
*/
|
|
|
|
gsize
|
|
|
|
g_strlcat (gchar *dest,
|
|
|
|
const gchar *src,
|
|
|
|
gsize dest_size)
|
|
|
|
{
|
|
|
|
register gchar *d = dest;
|
|
|
|
register const gchar *s = src;
|
|
|
|
register gsize bytes_left = dest_size;
|
|
|
|
gsize dlength; /* Logically, MIN (strlen (d), dest_size) */
|
|
|
|
|
|
|
|
g_return_val_if_fail (dest != NULL, NULL);
|
|
|
|
g_return_val_if_fail (src != NULL, NULL);
|
|
|
|
|
|
|
|
/* Find the end of dst and adjust bytes left but don't go past end */
|
|
|
|
while (*d != 0 && bytes_left-- != 0)
|
|
|
|
d++;
|
|
|
|
dlength = d - dest;
|
|
|
|
bytes_left = dest_size - dlength;
|
|
|
|
|
|
|
|
if (bytes_left == 0)
|
|
|
|
return dlength + strlen (s);
|
|
|
|
|
|
|
|
while (*s != 0)
|
|
|
|
{
|
|
|
|
if (bytes_left != 1)
|
|
|
|
{
|
|
|
|
*d++ = *s;
|
|
|
|
bytes_left--;
|
|
|
|
}
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
*d = 0;
|
|
|
|
|
|
|
|
return dlength + (s - src); /* count does not include NUL */
|
|
|
|
}
|
|
|
|
#endif /* ! HAVE_STRLCPY */
|
|
|
|
|
2000-05-12 17:23:16 +02:00
|
|
|
gchar*
|
1999-07-24 20:50:58 +02:00
|
|
|
g_strdown (gchar *string)
|
1998-07-10 07:51:57 +02:00
|
|
|
{
|
1999-07-24 20:50:58 +02:00
|
|
|
register guchar *s;
|
added g_strlcat() and g_strlcpy() wrappers, supplied by David Wheeler
Wed Jul 26 05:47:48 2000 Tim Janik <timj@gtk.org>
* configure.in:
* testglib.c:
* gstrfuncs.c:
* glib.h: added g_strlcat() and g_strlcpy() wrappers, supplied by
David Wheeler <dwheeler@ida.org>:
* glib.h, gstrfuncs.c: added g_strlcpy and g_strlcat to support
safe manipulation of fixed-length string buffers.
These functions were originally developed by Todd Miller to simplify
development of security-related programs, and
are available on many (but not all) Unix-like systems,
including OpenBSD, FreeBSD, and Solaris. See
ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3
and http://www.openbsd.org/security.html.
If there's a strlcpy/strlcat on the system, it's called, otherwise
an implementation is provided.
* testglib.c: Added tests for g_strlcpy, g_strlcat.
2000-07-26 05:51:07 +02:00
|
|
|
|
2000-05-12 17:23:16 +02:00
|
|
|
g_return_val_if_fail (string != NULL, NULL);
|
added g_strlcat() and g_strlcpy() wrappers, supplied by David Wheeler
Wed Jul 26 05:47:48 2000 Tim Janik <timj@gtk.org>
* configure.in:
* testglib.c:
* gstrfuncs.c:
* glib.h: added g_strlcat() and g_strlcpy() wrappers, supplied by
David Wheeler <dwheeler@ida.org>:
* glib.h, gstrfuncs.c: added g_strlcpy and g_strlcat to support
safe manipulation of fixed-length string buffers.
These functions were originally developed by Todd Miller to simplify
development of security-related programs, and
are available on many (but not all) Unix-like systems,
including OpenBSD, FreeBSD, and Solaris. See
ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3
and http://www.openbsd.org/security.html.
If there's a strlcpy/strlcat on the system, it's called, otherwise
an implementation is provided.
* testglib.c: Added tests for g_strlcpy, g_strlcat.
2000-07-26 05:51:07 +02:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
s = string;
|
added g_strlcat() and g_strlcpy() wrappers, supplied by David Wheeler
Wed Jul 26 05:47:48 2000 Tim Janik <timj@gtk.org>
* configure.in:
* testglib.c:
* gstrfuncs.c:
* glib.h: added g_strlcat() and g_strlcpy() wrappers, supplied by
David Wheeler <dwheeler@ida.org>:
* glib.h, gstrfuncs.c: added g_strlcpy and g_strlcat to support
safe manipulation of fixed-length string buffers.
These functions were originally developed by Todd Miller to simplify
development of security-related programs, and
are available on many (but not all) Unix-like systems,
including OpenBSD, FreeBSD, and Solaris. See
ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3
and http://www.openbsd.org/security.html.
If there's a strlcpy/strlcat on the system, it's called, otherwise
an implementation is provided.
* testglib.c: Added tests for g_strlcpy, g_strlcat.
2000-07-26 05:51:07 +02:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
while (*s)
|
|
|
|
{
|
|
|
|
*s = tolower (*s);
|
|
|
|
s++;
|
|
|
|
}
|
added g_strlcat() and g_strlcpy() wrappers, supplied by David Wheeler
Wed Jul 26 05:47:48 2000 Tim Janik <timj@gtk.org>
* configure.in:
* testglib.c:
* gstrfuncs.c:
* glib.h: added g_strlcat() and g_strlcpy() wrappers, supplied by
David Wheeler <dwheeler@ida.org>:
* glib.h, gstrfuncs.c: added g_strlcpy and g_strlcat to support
safe manipulation of fixed-length string buffers.
These functions were originally developed by Todd Miller to simplify
development of security-related programs, and
are available on many (but not all) Unix-like systems,
including OpenBSD, FreeBSD, and Solaris. See
ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3
and http://www.openbsd.org/security.html.
If there's a strlcpy/strlcat on the system, it's called, otherwise
an implementation is provided.
* testglib.c: Added tests for g_strlcpy, g_strlcat.
2000-07-26 05:51:07 +02:00
|
|
|
|
2000-05-12 17:23:16 +02:00
|
|
|
return string;
|
1998-07-10 07:51:57 +02:00
|
|
|
}
|
|
|
|
|
2000-05-12 17:23:16 +02:00
|
|
|
gchar*
|
1999-07-24 20:50:58 +02:00
|
|
|
g_strup (gchar *string)
|
1998-07-10 07:51:57 +02:00
|
|
|
{
|
1999-07-24 20:50:58 +02:00
|
|
|
register guchar *s;
|
1999-01-19 10:07:28 +01:00
|
|
|
|
2000-05-12 17:23:16 +02:00
|
|
|
g_return_val_if_fail (string != NULL, NULL);
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
s = string;
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
while (*s)
|
|
|
|
{
|
|
|
|
*s = toupper (*s);
|
|
|
|
s++;
|
|
|
|
}
|
2000-05-12 17:23:16 +02:00
|
|
|
|
|
|
|
return string;
|
1998-07-10 07:51:57 +02:00
|
|
|
}
|
|
|
|
|
2000-05-12 17:23:16 +02:00
|
|
|
gchar*
|
1999-07-24 20:50:58 +02:00
|
|
|
g_strreverse (gchar *string)
|
1998-07-10 07:51:57 +02:00
|
|
|
{
|
2000-05-12 17:23:16 +02:00
|
|
|
g_return_val_if_fail (string != NULL, NULL);
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
if (*string)
|
|
|
|
{
|
|
|
|
register gchar *h, *t;
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
h = string;
|
|
|
|
t = string + strlen (string) - 1;
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
while (h < t)
|
|
|
|
{
|
|
|
|
register gchar c;
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
c = *h;
|
|
|
|
*h = *t;
|
|
|
|
h++;
|
|
|
|
*t = c;
|
|
|
|
t--;
|
|
|
|
}
|
|
|
|
}
|
2000-05-12 17:23:16 +02:00
|
|
|
|
|
|
|
return string;
|
1998-07-10 07:51:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
g_strcasecmp (const gchar *s1,
|
|
|
|
const gchar *s2)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_STRCASECMP
|
1999-07-24 20:50:58 +02:00
|
|
|
g_return_val_if_fail (s1 != NULL, 0);
|
|
|
|
g_return_val_if_fail (s2 != NULL, 0);
|
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
return strcasecmp (s1, s2);
|
|
|
|
#else
|
|
|
|
gint c1, c2;
|
1999-01-19 10:07:28 +01:00
|
|
|
|
removed dummy structure definitions for struct _GCache, _GTree, _GTimer,
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.
1998-10-27 05:11:34 +01:00
|
|
|
g_return_val_if_fail (s1 != NULL, 0);
|
|
|
|
g_return_val_if_fail (s2 != NULL, 0);
|
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
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)
|
1998-07-25 05:03:01 +02:00
|
|
|
return (c1 - c2);
|
1998-07-10 07:51:57 +02:00
|
|
|
s1++; s2++;
|
|
|
|
}
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
return (((gint)(guchar) *s1) - ((gint)(guchar) *s2));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
1998-11-05 02:36:36 +01:00
|
|
|
gint
|
|
|
|
g_strncasecmp (const gchar *s1,
|
|
|
|
const gchar *s2,
|
|
|
|
guint n)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_STRNCASECMP
|
|
|
|
return strncasecmp (s1, s2, n);
|
|
|
|
#else
|
|
|
|
gint c1, c2;
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-11-05 02:36:36 +01:00
|
|
|
g_return_val_if_fail (s1 != NULL, 0);
|
|
|
|
g_return_val_if_fail (s2 != NULL, 0);
|
|
|
|
|
2000-07-15 09:18:19 +02:00
|
|
|
while (n && *s1 && *s2)
|
1998-11-05 02:36:36 +01:00
|
|
|
{
|
2000-07-15 09:18:19 +02:00
|
|
|
n -= 1;
|
1998-11-05 02:36:36 +01:00
|
|
|
/* 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++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (n)
|
2000-07-15 09:18:19 +02:00
|
|
|
return (((gint) (guchar) *s1) - ((gint) (guchar) *s2));
|
1998-11-05 02:36:36 +01:00
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
gchar*
|
1998-07-25 05:03:01 +02:00
|
|
|
g_strdelimit (gchar *string,
|
1998-07-10 07:51:57 +02:00
|
|
|
const gchar *delimiters,
|
1998-07-25 05:03:01 +02:00
|
|
|
gchar new_delim)
|
1998-07-10 07:51:57 +02:00
|
|
|
{
|
|
|
|
register gchar *c;
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
g_return_val_if_fail (string != NULL, NULL);
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
if (!delimiters)
|
|
|
|
delimiters = G_STR_DELIMITERS;
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
for (c = string; *c; c++)
|
|
|
|
{
|
|
|
|
if (strchr (delimiters, *c))
|
|
|
|
*c = new_delim;
|
|
|
|
}
|
1998-10-21 19:18:22 +02:00
|
|
|
|
|
|
|
return string;
|
1998-07-10 07:51:57 +02:00
|
|
|
}
|
1998-10-20 23:41:55 +02:00
|
|
|
|
2000-05-12 17:23:16 +02:00
|
|
|
gchar*
|
|
|
|
g_strcanon (gchar *string,
|
|
|
|
const gchar *valid_chars,
|
|
|
|
gchar subsitutor)
|
|
|
|
{
|
|
|
|
register gchar *c;
|
|
|
|
|
|
|
|
g_return_val_if_fail (string != NULL, NULL);
|
|
|
|
g_return_val_if_fail (valid_chars != NULL, NULL);
|
|
|
|
|
|
|
|
for (c = string; *c; c++)
|
|
|
|
{
|
|
|
|
if (!strchr (valid_chars, *c))
|
|
|
|
*c = subsitutor;
|
|
|
|
}
|
|
|
|
|
|
|
|
return string;
|
|
|
|
}
|
|
|
|
|
1999-07-31 23:45:21 +02:00
|
|
|
gchar*
|
1999-08-03 01:16:32 +02:00
|
|
|
g_strcompress (const gchar *source)
|
1999-07-31 23:45:21 +02:00
|
|
|
{
|
1999-08-03 01:16:32 +02:00
|
|
|
const gchar *p = source, *octal;
|
|
|
|
gchar *dest = g_malloc (strlen (source) + 1);
|
1999-07-31 23:45:21 +02:00
|
|
|
gchar *q = dest;
|
2000-05-12 17:23:16 +02:00
|
|
|
|
1999-07-31 23:45:21 +02:00
|
|
|
while (*p)
|
|
|
|
{
|
|
|
|
if (*p == '\\')
|
|
|
|
{
|
|
|
|
p++;
|
|
|
|
switch (*p)
|
|
|
|
{
|
|
|
|
case '0': case '1': case '2': case '3': case '4':
|
|
|
|
case '5': case '6': case '7':
|
|
|
|
*q = 0;
|
1999-08-03 01:16:32 +02:00
|
|
|
octal = p;
|
|
|
|
while ((p < octal + 3) && (*p >= '0') && (*p <= '7'))
|
1999-07-31 23:45:21 +02:00
|
|
|
{
|
|
|
|
*q = (*q * 8) + (*p - '0');
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
q++;
|
|
|
|
p--;
|
|
|
|
break;
|
|
|
|
case 'b':
|
|
|
|
*q++ = '\b';
|
|
|
|
break;
|
|
|
|
case 'f':
|
|
|
|
*q++ = '\f';
|
|
|
|
break;
|
|
|
|
case 'n':
|
|
|
|
*q++ = '\n';
|
|
|
|
break;
|
|
|
|
case 'r':
|
|
|
|
*q++ = '\r';
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
*q++ = '\t';
|
|
|
|
break;
|
|
|
|
default: /* Also handles \" and \\ */
|
|
|
|
*q++ = *p;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
*q++ = *p;
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
*q = 0;
|
2000-05-12 17:23:16 +02:00
|
|
|
|
1999-07-31 23:45:21 +02:00
|
|
|
return dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
gchar *
|
1999-08-03 01:16:32 +02:00
|
|
|
g_strescape (const gchar *source,
|
|
|
|
const gchar *exceptions)
|
1999-07-31 23:45:21 +02:00
|
|
|
{
|
1999-08-03 01:16:32 +02:00
|
|
|
const guchar *p = (guchar *) source;
|
|
|
|
/* Each source byte needs maximally four destination chars (\777) */
|
|
|
|
gchar *dest = g_malloc (strlen (source) * 4 + 1);
|
1999-07-31 23:45:21 +02:00
|
|
|
gchar *q = dest;
|
|
|
|
guchar excmap[256];
|
|
|
|
|
|
|
|
memset (excmap, 0, 256);
|
|
|
|
if (exceptions)
|
|
|
|
{
|
|
|
|
guchar *e = (guchar *) exceptions;
|
|
|
|
|
|
|
|
while (*e)
|
|
|
|
{
|
|
|
|
excmap[*e] = 1;
|
|
|
|
e++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
while (*p)
|
|
|
|
{
|
|
|
|
if (excmap[*p])
|
|
|
|
*q++ = *p;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (*p)
|
|
|
|
{
|
|
|
|
case '\b':
|
|
|
|
*q++ = '\\';
|
|
|
|
*q++ = 'b';
|
|
|
|
break;
|
|
|
|
case '\f':
|
|
|
|
*q++ = '\\';
|
|
|
|
*q++ = 'f';
|
|
|
|
break;
|
|
|
|
case '\n':
|
|
|
|
*q++ = '\\';
|
|
|
|
*q++ = 'n';
|
|
|
|
break;
|
|
|
|
case '\r':
|
|
|
|
*q++ = '\\';
|
|
|
|
*q++ = 'r';
|
|
|
|
break;
|
|
|
|
case '\t':
|
|
|
|
*q++ = '\\';
|
|
|
|
*q++ = 't';
|
|
|
|
break;
|
|
|
|
case '\\':
|
|
|
|
*q++ = '\\';
|
|
|
|
*q++ = '\\';
|
|
|
|
break;
|
|
|
|
case '"':
|
|
|
|
*q++ = '\\';
|
|
|
|
*q++ = '"';
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if ((*p < ' ') || (*p >= 0177))
|
|
|
|
{
|
|
|
|
*q++ = '\\';
|
1999-08-01 02:54:14 +02:00
|
|
|
*q++ = '0' + (((*p) >> 6) & 07);
|
|
|
|
*q++ = '0' + (((*p) >> 3) & 07);
|
|
|
|
*q++ = '0' + ((*p) & 07);
|
1999-07-31 23:45:21 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
*q++ = *p;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
*q = 0;
|
|
|
|
return dest;
|
|
|
|
}
|
|
|
|
|
2000-02-03 00:39:32 +01:00
|
|
|
/*
|
|
|
|
* g_filename_to_utf8
|
|
|
|
*
|
|
|
|
* Converts a string which is in the encoding used for file names by
|
|
|
|
* the C runtime (usually the same as that used by the operating
|
|
|
|
* system) in the current locale into a UTF-8 string.
|
|
|
|
*/
|
|
|
|
|
|
|
|
gchar *
|
|
|
|
g_filename_to_utf8 (const gchar *opsysstring)
|
|
|
|
{
|
|
|
|
#ifdef G_OS_WIN32
|
|
|
|
|
|
|
|
gint i, clen, wclen, first;
|
|
|
|
const gint len = strlen (opsysstring);
|
|
|
|
wchar_t *wcs, wc;
|
|
|
|
gchar *result, *bp;
|
|
|
|
const wchar_t *wcp;
|
|
|
|
|
|
|
|
wcs = g_new (wchar_t, len);
|
|
|
|
wclen = MultiByteToWideChar (CP_ACP, 0, opsysstring, len, wcs, len);
|
|
|
|
|
|
|
|
wcp = wcs;
|
|
|
|
clen = 0;
|
|
|
|
for (i = 0; i < wclen; i++)
|
|
|
|
{
|
|
|
|
wc = *wcp++;
|
|
|
|
|
|
|
|
if (wc < 0x80)
|
|
|
|
clen += 1;
|
|
|
|
else if (wc < 0x800)
|
|
|
|
clen += 2;
|
|
|
|
else if (wc < 0x10000)
|
|
|
|
clen += 3;
|
|
|
|
else if (wc < 0x200000)
|
|
|
|
clen += 4;
|
|
|
|
else if (wc < 0x4000000)
|
|
|
|
clen += 5;
|
|
|
|
else
|
|
|
|
clen += 6;
|
|
|
|
}
|
|
|
|
|
|
|
|
result = g_malloc (clen + 1);
|
|
|
|
|
|
|
|
wcp = wcs;
|
|
|
|
bp = result;
|
|
|
|
for (i = 0; i < wclen; i++)
|
|
|
|
{
|
|
|
|
wc = *wcp++;
|
|
|
|
|
|
|
|
if (wc < 0x80)
|
|
|
|
{
|
|
|
|
first = 0;
|
|
|
|
clen = 1;
|
|
|
|
}
|
|
|
|
else if (wc < 0x800)
|
|
|
|
{
|
|
|
|
first = 0xc0;
|
|
|
|
clen = 2;
|
|
|
|
}
|
|
|
|
else if (wc < 0x10000)
|
|
|
|
{
|
|
|
|
first = 0xe0;
|
|
|
|
clen = 3;
|
|
|
|
}
|
|
|
|
else if (wc < 0x200000)
|
|
|
|
{
|
|
|
|
first = 0xf0;
|
|
|
|
clen = 4;
|
|
|
|
}
|
|
|
|
else if (wc < 0x4000000)
|
|
|
|
{
|
|
|
|
first = 0xf8;
|
|
|
|
clen = 5;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
first = 0xfc;
|
|
|
|
clen = 6;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Woo-hoo! */
|
|
|
|
switch (clen)
|
|
|
|
{
|
|
|
|
case 6: bp[5] = (wc & 0x3f) | 0x80; wc >>= 6; /* Fall through */
|
|
|
|
case 5: bp[4] = (wc & 0x3f) | 0x80; wc >>= 6; /* Fall through */
|
|
|
|
case 4: bp[3] = (wc & 0x3f) | 0x80; wc >>= 6; /* Fall through */
|
|
|
|
case 3: bp[2] = (wc & 0x3f) | 0x80; wc >>= 6; /* Fall through */
|
|
|
|
case 2: bp[1] = (wc & 0x3f) | 0x80; wc >>= 6; /* Fall through */
|
|
|
|
case 1: bp[0] = wc | first;
|
|
|
|
}
|
|
|
|
|
|
|
|
bp += clen;
|
|
|
|
}
|
|
|
|
*bp = 0;
|
|
|
|
|
|
|
|
g_free (wcs);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
return g_strdup (opsysstring);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* g_filename_from_utf8
|
|
|
|
*
|
|
|
|
* The reverse of g_filename_to_utf8.
|
|
|
|
*/
|
|
|
|
|
|
|
|
gchar *
|
|
|
|
g_filename_from_utf8 (const gchar *utf8string)
|
|
|
|
{
|
|
|
|
#ifdef G_OS_WIN32
|
|
|
|
|
|
|
|
gint i, mask, clen, wclen, mblen;
|
|
|
|
const gint len = strlen (utf8string);
|
|
|
|
wchar_t *wcs, *wcp;
|
|
|
|
gchar *result;
|
|
|
|
guchar *cp, *end, c;
|
|
|
|
gint n;
|
|
|
|
|
|
|
|
/* First convert to wide chars */
|
|
|
|
cp = (guchar *) utf8string;
|
|
|
|
end = cp + len;
|
|
|
|
n = 0;
|
|
|
|
wcs = g_new (wchar_t, len + 1);
|
|
|
|
wcp = wcs;
|
|
|
|
while (cp != end)
|
|
|
|
{
|
|
|
|
mask = 0;
|
|
|
|
c = *cp;
|
|
|
|
|
|
|
|
if (c < 0x80)
|
|
|
|
{
|
|
|
|
clen = 1;
|
|
|
|
mask = 0x7f;
|
|
|
|
}
|
|
|
|
else if ((c & 0xe0) == 0xc0)
|
|
|
|
{
|
|
|
|
clen = 2;
|
|
|
|
mask = 0x1f;
|
|
|
|
}
|
|
|
|
else if ((c & 0xf0) == 0xe0)
|
|
|
|
{
|
|
|
|
clen = 3;
|
|
|
|
mask = 0x0f;
|
|
|
|
}
|
|
|
|
else if ((c & 0xf8) == 0xf0)
|
|
|
|
{
|
|
|
|
clen = 4;
|
|
|
|
mask = 0x07;
|
|
|
|
}
|
|
|
|
else if ((c & 0xfc) == 0xf8)
|
|
|
|
{
|
|
|
|
clen = 5;
|
|
|
|
mask = 0x03;
|
|
|
|
}
|
|
|
|
else if ((c & 0xfc) == 0xfc)
|
|
|
|
{
|
|
|
|
clen = 6;
|
|
|
|
mask = 0x01;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_free (wcs);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cp + clen > end)
|
|
|
|
{
|
|
|
|
g_free (wcs);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
*wcp = (cp[0] & mask);
|
|
|
|
for (i = 1; i < clen; i++)
|
|
|
|
{
|
|
|
|
if ((cp[i] & 0xc0) != 0x80)
|
|
|
|
{
|
|
|
|
g_free (wcs);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
*wcp <<= 6;
|
|
|
|
*wcp |= (cp[i] & 0x3f);
|
|
|
|
}
|
|
|
|
|
|
|
|
cp += clen;
|
|
|
|
wcp++;
|
|
|
|
n++;
|
|
|
|
}
|
|
|
|
if (cp != end)
|
|
|
|
{
|
|
|
|
g_free (wcs);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* n is the number of wide chars constructed */
|
|
|
|
|
|
|
|
/* Convert to a string in the current ANSI codepage */
|
|
|
|
|
|
|
|
result = g_new (gchar, 3 * n + 1);
|
|
|
|
mblen = WideCharToMultiByte (CP_ACP, 0, wcs, n, result, 3*n, NULL, NULL);
|
|
|
|
result[mblen] = 0;
|
|
|
|
g_free (wcs);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
return g_strdup (utf8string);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
gchar*
|
|
|
|
g_strchug (gchar *string)
|
1998-10-20 23:41:55 +02:00
|
|
|
{
|
1999-07-24 20:50:58 +02:00
|
|
|
guchar *start;
|
1998-10-20 23:41:55 +02:00
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
g_return_val_if_fail (string != NULL, NULL);
|
1998-10-20 23:41:55 +02:00
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
for (start = string; *start && isspace (*start); start++)
|
|
|
|
;
|
1998-10-20 23:41:55 +02:00
|
|
|
|
2000-03-01 10:44:10 +01:00
|
|
|
g_memmove (string, start, strlen( start) + 1);
|
1998-10-20 23:41:55 +02:00
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
return string;
|
1998-10-20 23:41:55 +02:00
|
|
|
}
|
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
gchar*
|
|
|
|
g_strchomp (gchar *string)
|
1998-10-20 23:41:55 +02:00
|
|
|
{
|
1998-10-21 19:18:22 +02:00
|
|
|
gchar *s;
|
1998-10-20 23:41:55 +02:00
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
g_return_val_if_fail (string != NULL, NULL);
|
1998-10-20 23:41:55 +02:00
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
if (!*string)
|
|
|
|
return string;
|
1998-10-20 23:41:55 +02:00
|
|
|
|
1999-07-24 20:50:58 +02:00
|
|
|
for (s = string + strlen (string) - 1; s >= string && isspace ((guchar)*s);
|
|
|
|
s--)
|
1998-10-21 19:18:22 +02:00
|
|
|
*s = '\0';
|
1998-10-20 23:41:55 +02:00
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
return string;
|
1998-10-20 23:41:55 +02:00
|
|
|
}
|
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
gchar**
|
1998-10-25 07:44:49 +01:00
|
|
|
g_strsplit (const gchar *string,
|
|
|
|
const gchar *delimiter,
|
|
|
|
gint max_tokens)
|
1998-10-20 23:41:55 +02:00
|
|
|
{
|
1998-10-21 19:18:22 +02:00
|
|
|
GSList *string_list = NULL, *slist;
|
1998-10-21 22:14:16 +02:00
|
|
|
gchar **str_array, *s;
|
|
|
|
guint i, n = 1;
|
1998-10-20 23:41:55 +02:00
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
g_return_val_if_fail (string != NULL, NULL);
|
|
|
|
g_return_val_if_fail (delimiter != NULL, NULL);
|
1998-10-20 23:41:55 +02:00
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
if (max_tokens < 1)
|
|
|
|
max_tokens = G_MAXINT;
|
1998-10-20 23:41:55 +02:00
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
s = strstr (string, delimiter);
|
|
|
|
if (s)
|
|
|
|
{
|
|
|
|
guint delimiter_len = strlen (delimiter);
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
do
|
|
|
|
{
|
|
|
|
guint len;
|
|
|
|
gchar *new_string;
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
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));
|
|
|
|
}
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
str_array = g_new (gchar*, n);
|
1998-10-21 22:14:16 +02:00
|
|
|
|
|
|
|
i = n - 1;
|
|
|
|
|
|
|
|
str_array[i--] = NULL;
|
1998-10-21 19:18:22 +02:00
|
|
|
for (slist = string_list; slist; slist = slist->next)
|
1998-10-21 22:14:16 +02:00
|
|
|
str_array[i--] = slist->data;
|
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
g_slist_free (string_list);
|
1998-10-20 23:41:55 +02:00
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
return str_array;
|
1998-10-20 23:41:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
1998-10-25 07:44:49 +01:00
|
|
|
g_strfreev (gchar **str_array)
|
1998-10-20 23:41:55 +02:00
|
|
|
{
|
1998-10-21 19:18:22 +02:00
|
|
|
if (str_array)
|
|
|
|
{
|
1998-10-21 22:14:16 +02:00
|
|
|
int i;
|
|
|
|
|
|
|
|
for(i = 0; str_array[i] != NULL; i++)
|
|
|
|
g_free(str_array[i]);
|
1998-10-20 23:41:55 +02:00
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
g_free (str_array);
|
|
|
|
}
|
1998-10-20 23:41:55 +02:00
|
|
|
}
|
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
gchar*
|
1998-10-25 07:44:49 +01:00
|
|
|
g_strjoinv (const gchar *separator,
|
|
|
|
gchar **str_array)
|
1998-10-20 23:41:55 +02:00
|
|
|
{
|
1998-10-21 19:18:22 +02:00
|
|
|
gchar *string;
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
g_return_val_if_fail (str_array != NULL, NULL);
|
1998-10-21 22:14:16 +02:00
|
|
|
|
1999-07-24 20:50:58 +02:00
|
|
|
if (separator == NULL)
|
1998-10-21 22:14:16 +02:00
|
|
|
separator = "";
|
1998-10-20 23:41:55 +02:00
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
if (*str_array)
|
|
|
|
{
|
1998-10-21 22:14:16 +02:00
|
|
|
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]);
|
1999-01-19 10:07:28 +01:00
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
string = g_new (gchar, len);
|
|
|
|
*string = 0;
|
|
|
|
strcat (string, *str_array);
|
1998-10-21 22:14:16 +02:00
|
|
|
for (i = 1; str_array[i] != NULL; i++)
|
1998-10-21 19:18:22 +02:00
|
|
|
{
|
|
|
|
strcat (string, separator);
|
1998-10-21 22:14:16 +02:00
|
|
|
strcat (string, str_array[i]);
|
1998-10-21 19:18:22 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
string = g_strdup ("");
|
1998-10-20 23:41:55 +02:00
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
return string;
|
1998-10-20 23:41:55 +02:00
|
|
|
}
|
1998-10-21 22:14:16 +02:00
|
|
|
|
|
|
|
gchar*
|
1998-10-25 07:44:49 +01:00
|
|
|
g_strjoin (const gchar *separator,
|
|
|
|
...)
|
1998-10-21 22:14:16 +02:00
|
|
|
{
|
|
|
|
gchar *string, *s;
|
|
|
|
va_list args;
|
|
|
|
guint len;
|
|
|
|
guint separator_len;
|
|
|
|
|
1999-07-24 20:50:58 +02:00
|
|
|
if (separator == NULL)
|
1998-10-21 22:14:16 +02:00
|
|
|
separator = "";
|
|
|
|
|
|
|
|
separator_len = strlen (separator);
|
|
|
|
|
1999-07-24 20:50:58 +02:00
|
|
|
va_start (args, separator);
|
1998-10-21 22:14:16 +02:00
|
|
|
|
1999-07-24 20:50:58 +02:00
|
|
|
s = va_arg (args, gchar*);
|
1998-10-21 22:14:16 +02:00
|
|
|
|
1999-07-24 20:50:58 +02:00
|
|
|
if (s)
|
|
|
|
{
|
|
|
|
len = strlen (s);
|
1998-10-21 22:14:16 +02:00
|
|
|
|
1999-07-24 20:50:58 +02:00
|
|
|
s = va_arg (args, gchar*);
|
|
|
|
while (s)
|
|
|
|
{
|
|
|
|
len += separator_len + strlen (s);
|
|
|
|
s = va_arg (args, gchar*);
|
|
|
|
}
|
|
|
|
va_end (args);
|
1998-10-21 22:14:16 +02:00
|
|
|
|
1999-07-24 20:50:58 +02:00
|
|
|
string = g_new (gchar, len + 1);
|
|
|
|
*string = 0;
|
1998-10-21 22:14:16 +02:00
|
|
|
|
1999-07-24 20:50:58 +02:00
|
|
|
va_start (args, separator);
|
1998-10-21 22:14:16 +02:00
|
|
|
|
1999-07-24 20:50:58 +02:00
|
|
|
s = va_arg (args, gchar*);
|
|
|
|
strcat (string, s);
|
1998-10-21 22:14:16 +02:00
|
|
|
|
1999-07-24 20:50:58 +02:00
|
|
|
s = va_arg (args, gchar*);
|
|
|
|
while (s)
|
|
|
|
{
|
|
|
|
strcat (string, separator);
|
|
|
|
strcat (string, s);
|
|
|
|
s = va_arg (args, gchar*);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
string = g_strdup ("");
|
1998-10-21 22:14:16 +02:00
|
|
|
|
1999-07-24 20:50:58 +02:00
|
|
|
va_end (args);
|
1998-10-21 22:14:16 +02:00
|
|
|
|
|
|
|
return string;
|
|
|
|
}
|