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
|
|
|
|
* 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"
|
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;
|
|
|
|
|
|
|
|
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;
|
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;
|
|
|
|
|
|
|
|
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;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
g_return_val_if_fail (nptr != NULL, 0);
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
fail_pos_1 = NULL;
|
|
|
|
fail_pos_2 = NULL;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
val_1 = strtod (nptr, &fail_pos_1);
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
if (fail_pos_1 && fail_pos_1[0] != 0)
|
|
|
|
{
|
|
|
|
gchar *old_locale;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
old_locale = setlocale (LC_NUMERIC, "C");
|
|
|
|
val_2 = strtod (nptr, &fail_pos_2);
|
|
|
|
setlocale (LC_NUMERIC, old_locale);
|
|
|
|
}
|
1998-07-25 05:03:01 +02: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)
|
|
|
|
{
|
|
|
|
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[];
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
if ((errnum > 0) && (errnum <= sys_nerr))
|
|
|
|
return sys_errlist [errnum];
|
|
|
|
#endif /* NO_SYS_ERRLIST */
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
sprintf (msg, "unknown error (%d)", errnum);
|
|
|
|
return msg;
|
|
|
|
}
|
|
|
|
|
|
|
|
gchar*
|
|
|
|
g_strsignal (gint signum)
|
|
|
|
{
|
|
|
|
static char msg[64];
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
#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 */
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
sprintf (msg, "unknown signal (%d)", signum);
|
|
|
|
return msg;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
void
|
|
|
|
g_strdown (gchar *string)
|
|
|
|
{
|
|
|
|
register gchar *s;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
g_return_if_fail (string != NULL);
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
s = string;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
while (*s)
|
|
|
|
{
|
|
|
|
*s = tolower (*s);
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
1998-07-25 05:03:01 +02:00
|
|
|
g_strup (gchar *string)
|
1998-07-10 07:51:57 +02:00
|
|
|
{
|
|
|
|
register gchar *s;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
g_return_if_fail (string != NULL);
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
s = string;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
while (*s)
|
|
|
|
{
|
|
|
|
*s = toupper (*s);
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
1998-07-25 05:03:01 +02:00
|
|
|
g_strreverse (gchar *string)
|
1998-07-10 07:51:57 +02:00
|
|
|
{
|
|
|
|
g_return_if_fail (string != NULL);
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
if (*string)
|
|
|
|
{
|
|
|
|
register gchar *h, *t;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
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;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
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++;
|
|
|
|
}
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
return (((gint)(guchar) *s1) - ((gint)(guchar) *s2));
|
|
|
|
#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;
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
g_return_val_if_fail (string != NULL, NULL);
|
1998-07-25 05:03:01 +02:00
|
|
|
|
1998-07-10 07:51:57 +02:00
|
|
|
if (!delimiters)
|
|
|
|
delimiters = G_STR_DELIMITERS;
|
1998-07-25 05:03:01 +02: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
|
|
|
|
|
|
|
/* blame Elliot for these next five routines */
|
1998-10-21 19:18:22 +02:00
|
|
|
gchar*
|
|
|
|
g_strchug (gchar *string)
|
1998-10-20 23:41:55 +02:00
|
|
|
{
|
1998-10-21 19:18:22 +02:00
|
|
|
gchar *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
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
strcpy (string, start);
|
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
|
|
|
|
1998-10-21 19:18:22 +02:00
|
|
|
for (s = string + strlen (string) - 1; s >= string && isspace (*s); s--)
|
|
|
|
*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**
|
|
|
|
g_str_array_split (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);
|
|
|
|
|
|
|
|
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);
|
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-21 19:18:22 +02:00
|
|
|
g_str_array_free (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-21 22:14:16 +02:00
|
|
|
g_str_array_joinv (const gchar *separator,
|
|
|
|
const gchar **str_array)
|
1998-10-20 23:41:55 +02:00
|
|
|
{
|
1998-10-21 19:18:22 +02:00
|
|
|
gchar *string;
|
1998-10-20 23:41:55 +02: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
|
|
|
|
|
|
|
if(separator == NULL)
|
|
|
|
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]);
|
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*
|
|
|
|
g_str_array_join (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;
|
|
|
|
}
|