Move glib library into a subdirectory, make all GLib include files include

Tue Jun 26 11:43:46 2001  Owen Taylor  <otaylor@redhat.com>

	* configure.in Makefile.am *.[ch] glib/*.[ch] glib/Makefile.am:
	Move glib library into a subdirectory, make all GLib include
	files include as <glib/glist.h>

	* tests/testglib.c tests/testgdate.c tests/testgdateparser.c
	  tests/timeloop.c tests/timeloop-basic.c: Move all tests into
	the tests/ subdirectory.
This commit is contained in:
Owen Taylor 2001-06-26 16:01:21 +00:00 committed by Owen Taylor
parent 2c9c0fabc8
commit 2fd6b001fb
162 changed files with 221 additions and 59167 deletions

View File

@ -1,10 +1,3 @@
*.lo
*.obj
*.lib
*.dll
*.exe
.deps
.libs
Makefile
Makefile.in
_libs
@ -20,7 +13,6 @@ glib.spec
glibconfig-sysdefs.h
glibconfig.h
glibconfig.h.win32
libglib-1.3.la
libtool
makefile.cygwin
makefile.mingw
@ -29,11 +21,6 @@ so_locations
stamp-gc-h
stamp-h
stamp-h.in
testgdate
testgdateparser
testglib
timeloop
timeloop-basic
annotations
logs
glib.rc

View File

@ -1,3 +1,13 @@
Tue Jun 26 11:43:46 2001 Owen Taylor <otaylor@redhat.com>
* configure.in Makefile.am *.[ch] glib/*.[ch] glib/Makefile.am:
Move glib library into a subdirectory, make all GLib include
files include as <glib/glist.h>
* tests/testglib.c tests/testgdate.c tests/testgdateparser.c
tests/timeloop.c tests/timeloop-basic.c: Move all tests into
the tests/ subdirectory.
Sat Jun 23 17:34:38 2001 Tim Janik <timj@gtk.org>
* gmessages.c (g_logv): use G_BREAKPOINT() instead of raise(5).

View File

@ -1,3 +1,13 @@
Tue Jun 26 11:43:46 2001 Owen Taylor <otaylor@redhat.com>
* configure.in Makefile.am *.[ch] glib/*.[ch] glib/Makefile.am:
Move glib library into a subdirectory, make all GLib include
files include as <glib/glist.h>
* tests/testglib.c tests/testgdate.c tests/testgdateparser.c
tests/timeloop.c tests/timeloop-basic.c: Move all tests into
the tests/ subdirectory.
Sat Jun 23 17:34:38 2001 Tim Janik <timj@gtk.org>
* gmessages.c (g_logv): use G_BREAKPOINT() instead of raise(5).

View File

@ -1,3 +1,13 @@
Tue Jun 26 11:43:46 2001 Owen Taylor <otaylor@redhat.com>
* configure.in Makefile.am *.[ch] glib/*.[ch] glib/Makefile.am:
Move glib library into a subdirectory, make all GLib include
files include as <glib/glist.h>
* tests/testglib.c tests/testgdate.c tests/testgdateparser.c
tests/timeloop.c tests/timeloop-basic.c: Move all tests into
the tests/ subdirectory.
Sat Jun 23 17:34:38 2001 Tim Janik <timj@gtk.org>
* gmessages.c (g_logv): use G_BREAKPOINT() instead of raise(5).

View File

@ -1,3 +1,13 @@
Tue Jun 26 11:43:46 2001 Owen Taylor <otaylor@redhat.com>
* configure.in Makefile.am *.[ch] glib/*.[ch] glib/Makefile.am:
Move glib library into a subdirectory, make all GLib include
files include as <glib/glist.h>
* tests/testglib.c tests/testgdate.c tests/testgdateparser.c
tests/timeloop.c tests/timeloop-basic.c: Move all tests into
the tests/ subdirectory.
Sat Jun 23 17:34:38 2001 Tim Janik <timj@gtk.org>
* gmessages.c (g_logv): use G_BREAKPOINT() instead of raise(5).

View File

@ -1,3 +1,13 @@
Tue Jun 26 11:43:46 2001 Owen Taylor <otaylor@redhat.com>
* configure.in Makefile.am *.[ch] glib/*.[ch] glib/Makefile.am:
Move glib library into a subdirectory, make all GLib include
files include as <glib/glist.h>
* tests/testglib.c tests/testgdate.c tests/testgdateparser.c
tests/timeloop.c tests/timeloop-basic.c: Move all tests into
the tests/ subdirectory.
Sat Jun 23 17:34:38 2001 Tim Janik <timj@gtk.org>
* gmessages.c (g_logv): use G_BREAKPOINT() instead of raise(5).

View File

@ -1,3 +1,13 @@
Tue Jun 26 11:43:46 2001 Owen Taylor <otaylor@redhat.com>
* configure.in Makefile.am *.[ch] glib/*.[ch] glib/Makefile.am:
Move glib library into a subdirectory, make all GLib include
files include as <glib/glist.h>
* tests/testglib.c tests/testgdate.c tests/testgdateparser.c
tests/timeloop.c tests/timeloop-basic.c: Move all tests into
the tests/ subdirectory.
Sat Jun 23 17:34:38 2001 Tim Janik <timj@gtk.org>
* gmessages.c (g_logv): use G_BREAKPOINT() instead of raise(5).

View File

@ -1,3 +1,13 @@
Tue Jun 26 11:43:46 2001 Owen Taylor <otaylor@redhat.com>
* configure.in Makefile.am *.[ch] glib/*.[ch] glib/Makefile.am:
Move glib library into a subdirectory, make all GLib include
files include as <glib/glist.h>
* tests/testglib.c tests/testgdate.c tests/testgdateparser.c
tests/timeloop.c tests/timeloop-basic.c: Move all tests into
the tests/ subdirectory.
Sat Jun 23 17:34:38 2001 Tim Janik <timj@gtk.org>
* gmessages.c (g_logv): use G_BREAKPOINT() instead of raise(5).

View File

@ -1,3 +1,13 @@
Tue Jun 26 11:43:46 2001 Owen Taylor <otaylor@redhat.com>
* configure.in Makefile.am *.[ch] glib/*.[ch] glib/Makefile.am:
Move glib library into a subdirectory, make all GLib include
files include as <glib/glist.h>
* tests/testglib.c tests/testgdate.c tests/testgdateparser.c
tests/timeloop.c tests/timeloop-basic.c: Move all tests into
the tests/ subdirectory.
Sat Jun 23 17:34:38 2001 Tim Janik <timj@gtk.org>
* gmessages.c (g_logv): use G_BREAKPOINT() instead of raise(5).

View File

@ -2,7 +2,7 @@
AUTOMAKE_OPTIONS = 1.4
SUBDIRS = . m4macros gobject gmodule gthread docs tests build
SUBDIRS = . m4macros glib gobject gmodule gthread docs tests build
INCLUDES = -DG_LOG_DOMAIN=g_log_domain_glib @GLIB_DEBUG_FLAGS@ \
-DG_DISABLE_DEPRECATED -DGLIB_COMPILATION
@ -41,107 +41,6 @@ BUILT_EXTRA_DIST = \
glib.rc \
glib.spec
lib_LTLIBRARIES = libglib-1.3.la
libglib_1_3_la_SOURCES = \
garray.c \
gasyncqueue.c \
gbacktrace.c \
gcache.c \
gcompletion.c \
gconvert.c \
gdataset.c \
gdate.c \
gerror.c \
gfileutils.c \
ghash.c \
ghook.c \
giochannel.c \
glibintl.h \
glist.c \
gmain.c \
gmarkup.c \
gmem.c \
gmessages.c \
gnode.c \
gpattern.c \
gprimes.c \
gqsort.c \
gqueue.c \
grel.c \
grand.c \
gscanner.c \
gshell.c \
gslist.c \
gstrfuncs.c \
gstring.c \
gthread.c \
gthreadpool.c \
gtimer.c \
gtree.c \
guniprop.c \
gutf8.c \
gunibreak.h \
gunibreak.c \
gunichartables.h \
gunidecomp.h \
gunidecomp.c \
gutils.c
EXTRA_libglib_1_3_la_SOURCES = \
giounix.c \
giowin32.c \
gspawn.c \
gspawn-win32.c \
gwin32.c
glibincludedir=$(includedir)/glib-2.0
glibinclude_HEADERS = \
galloca.h \
garray.h \
gasyncqueue.h \
gbacktrace.h \
gcache.h \
gcompletion.h \
gconvert.h \
gdataset.h \
gdate.h \
gerror.h \
gfileutils.h \
ghash.h \
ghook.h \
giochannel.h \
glib.h \
glib-object.h \
glist.h \
gmacros.h \
gmain.h \
gmarkup.h \
gmem.h \
gmessages.h \
gnode.h \
gpattern.h \
gprimes.h \
gqsort.h \
gquark.h \
gqueue.h \
grand.h \
grel.h \
gscanner.h \
gshell.h \
gslist.h \
gspawn.h \
gstrfuncs.h \
gstring.h \
gthread.h \
gthreadpool.h \
gtimer.h \
gtree.h \
gtypes.h \
gunicode.h \
gutils.h \
gwin32.h
configexecincludedir = $(libdir)/glib-2.0/include
#configexecinclude_DATA = glibconfig.h
@ -161,36 +60,6 @@ stamp-gc-h: config.status
CONFIG_FILES= CONFIG_HEADERS= CONFIG_OTHER=glibconfig.h ./config.status
echo timestamp > stamp-gc-h
libglib_1_3_la_LIBADD = @GIO@ @GSPAWN@ @PLATFORMDEP@ @ICONV_LIBS@ @G_LIBS_EXTRA@
libglib_1_3_la_DEPENDENCIES = @GIO@ @GSPAWN@ @PLATFORMDEP@
if PLATFORM_WIN32
no_undefined = -no-undefined
endif
if OS_WIN32
# This requires a very new libtool
export_symbols = -export-symbols glib.def
endif
libglib_1_3_la_LDFLAGS = \
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
-export-dynamic $(no_undefined) $(export_symbols)
if OS_WIN32
bin_PROGRAMS = gspawn-win32-helper
gspawn_win32_helper_LDADD = libglib-1.3.la
endif
if ENABLE_TIMELOOP
timeloop = timeloop
endif
noinst_PROGRAMS = testglib testgdate testgdateparser $(timeloop)
testglib_LDADD = libglib-1.3.la
testgdate_LDADD = libglib-1.3.la
testgdateparser_LDADD = libglib-1.3.la
if ENABLE_TIMELOOP
timeloop_LDADD = libglib-1.3.la
endif
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = glib-2.0.pc gobject-2.0.pc gmodule-2.0.pc gthread-2.0.pc

View File

@ -8,7 +8,7 @@ ORIGDIR=`pwd`
cd $srcdir
PROJECT=GLib
TEST_TYPE=-f
FILE=glib.h
FILE=glib/glib.h
DIE=0

View File

@ -7,7 +7,7 @@ builtin(include, acglib.m4)dnl
AC_PREREQ(2.13)
# Process this file with autoconf to produce a configure script.
AC_INIT(glist.c)
AC_INIT(glib/glib.h)
# Save this value here, since automake will set cflags later
cflags_set=${CFLAGS+set}
@ -1535,7 +1535,7 @@ case "$CONFIG_OTHER" in
#ifndef __G_LIBCONFIG_H__
#define __G_LIBCONFIG_H__
#include <gmacros.h>
#include <glib/gmacros.h>
_______EOF
@ -2039,6 +2039,7 @@ glib.spec
Makefile
build/Makefile
build/win32/Makefile
glib/Makefile
gmodule/gmoduleconf.h
gmodule/Makefile
gobject/Makefile

View File

@ -3,6 +3,7 @@ Makefile.in
glib-decl-list.txt
glib-decl.txt
glib-unused.txt
glib-undocumented.txt
html
sgml
*.stamp

View File

@ -7,7 +7,7 @@ DOC_MODULE=glib
DOC_MAIN_SGML_FILE=glib-docs.sgml
# The directory containing the source code. Relative to $(srcdir)
DOC_SOURCE_DIR=../../..
DOC_SOURCE_DIR=../../../glib
# Extra options to supply to gtkdoc-scan
SCAN_OPTIONS=--deprecated-guards="G_DISABLE_DEPRECATED"
@ -19,8 +19,8 @@ MKDB_OPTIONS=
FIXXREF_OPTIONS=
# Used for dependencies
HFILE_GLOB=$(top_srcdir)/*.h $(top_srcdir)/gmodule/*.h
CFILE_GLOB=$(top_srcdir)/*.c $(top_srcdir)/gmodule/*.c
HFILE_GLOB=$(top_srcdir)/glib/*.h $(top_srcdir)/gmodule/*.h
CFILE_GLOB=$(top_srcdir)/glib/*.c $(top_srcdir)/gmodule/*.c
# Headers to ignore
IGNORE_HFILES= \

View File

@ -3,6 +3,7 @@ Makefile.in
gobject-decl.txt
gobject-unused.txt
gobject-decl-list.txt
gobject-undocumented.txt
html
sgml
*.stamp

View File

@ -1,60 +0,0 @@
/* 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 Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
#ifndef __G_ALLOCA_H__
#define __G_ALLOCA_H__
#include <gtypes.h>
#ifdef __GNUC__
/* GCC does the right thing */
# undef alloca
# define alloca(size) __builtin_alloca (size)
#elif defined (GLIB_HAVE_ALLOCA_H)
/* a native and working alloca.h is there */
# include <alloca.h>
#else /* !__GNUC__ && !GLIB_HAVE_ALLOCA_H */
# ifdef _MSC_VER
# include <malloc.h>
# define alloca _alloca
# else /* !_MSC_VER */
# ifdef _AIX
#pragma alloca
# else /* !_AIX */
# ifndef alloca /* predefined by HP cc +Olibcalls */
G_BEGIN_DECLS
char *alloca ();
G_END_DECLS
# endif /* !alloca */
# endif /* !_AIX */
# endif /* !_MSC_VER */
#endif /* !__GNUC__ && !GLIB_HAVE_ALLOCA_H */
#define g_alloca(size) alloca (size)
#endif /* __G_ALLOCA_H__ */

670
garray.c
View File

@ -1,670 +0,0 @@
/* 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 Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
/*
* MT safe
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <string.h>
#include <stdlib.h>
#include "glib.h"
#define MIN_ARRAY_SIZE 16
typedef struct _GRealArray GRealArray;
struct _GRealArray
{
guint8 *data;
guint len;
guint alloc;
guint elt_size;
guint zero_terminated : 1;
guint clear : 1;
};
#define g_array_elt_len(array,i) ((array)->elt_size * (i))
#define g_array_elt_pos(array,i) ((array)->data + g_array_elt_len((array),(i)))
#define g_array_elt_zero(array, pos, len) \
(memset (g_array_elt_pos ((array), pos), 0, g_array_elt_len ((array), len)))
#define g_array_zero_terminate(array) G_STMT_START{ \
if ((array)->zero_terminated) \
g_array_elt_zero ((array), (array)->len, 1); \
}G_STMT_END
static gint g_nearest_pow (gint num) G_GNUC_CONST;
static void g_array_maybe_expand (GRealArray *array,
gint len);
static GMemChunk *array_mem_chunk = NULL;
G_LOCK_DEFINE_STATIC (array_mem_chunk);
GArray*
g_array_new (gboolean zero_terminated,
gboolean clear,
guint elt_size)
{
return (GArray*) g_array_sized_new (zero_terminated, clear, elt_size, 0);
}
GArray* g_array_sized_new (gboolean zero_terminated,
gboolean clear,
guint elt_size,
guint reserved_size)
{
GRealArray *array;
G_LOCK (array_mem_chunk);
if (!array_mem_chunk)
array_mem_chunk = g_mem_chunk_new ("array mem chunk",
sizeof (GRealArray),
1024, G_ALLOC_AND_FREE);
array = g_chunk_new (GRealArray, array_mem_chunk);
G_UNLOCK (array_mem_chunk);
array->data = NULL;
array->len = 0;
array->alloc = 0;
array->zero_terminated = (zero_terminated ? 1 : 0);
array->clear = (clear ? 1 : 0);
array->elt_size = elt_size;
if (array->zero_terminated || reserved_size != 0)
{
g_array_maybe_expand (array, reserved_size);
g_array_zero_terminate(array);
}
return (GArray*) array;
}
gchar*
g_array_free (GArray *array,
gboolean free_segment)
{
gchar* segment;
g_return_val_if_fail (array, NULL);
if (free_segment)
{
g_free (array->data);
segment = NULL;
}
else
segment = array->data;
G_LOCK (array_mem_chunk);
g_mem_chunk_free (array_mem_chunk, array);
G_UNLOCK (array_mem_chunk);
return segment;
}
GArray*
g_array_append_vals (GArray *farray,
gconstpointer data,
guint len)
{
GRealArray *array = (GRealArray*) farray;
g_array_maybe_expand (array, len);
memcpy (g_array_elt_pos (array, array->len), data,
g_array_elt_len (array, len));
array->len += len;
g_array_zero_terminate (array);
return farray;
}
GArray*
g_array_prepend_vals (GArray *farray,
gconstpointer data,
guint len)
{
GRealArray *array = (GRealArray*) farray;
g_array_maybe_expand (array, len);
g_memmove (g_array_elt_pos (array, len), g_array_elt_pos (array, 0),
g_array_elt_len (array, array->len));
memcpy (g_array_elt_pos (array, 0), data, g_array_elt_len (array, len));
array->len += len;
g_array_zero_terminate (array);
return farray;
}
GArray*
g_array_insert_vals (GArray *farray,
guint index,
gconstpointer data,
guint len)
{
GRealArray *array = (GRealArray*) farray;
g_array_maybe_expand (array, len);
g_memmove (g_array_elt_pos (array, len + index),
g_array_elt_pos (array, index),
g_array_elt_len (array, array->len - index));
memcpy (g_array_elt_pos (array, index), data, g_array_elt_len (array, len));
array->len += len;
g_array_zero_terminate (array);
return farray;
}
GArray*
g_array_set_size (GArray *farray,
guint length)
{
GRealArray *array = (GRealArray*) farray;
if (length > array->len)
{
g_array_maybe_expand (array, length - array->len);
if (array->clear)
g_array_elt_zero (array, array->len, length - array->len);
}
#ifdef ENABLE_GC_FRIENDLY
else if (length < array->len)
g_array_elt_zero (array, length, array->len - length);
#endif /* ENABLE_GC_FRIENDLY */
array->len = length;
g_array_zero_terminate (array);
return farray;
}
GArray*
g_array_remove_index (GArray* farray,
guint index)
{
GRealArray* array = (GRealArray*) farray;
g_return_val_if_fail (array, NULL);
g_return_val_if_fail (index < array->len, NULL);
if (index != array->len - 1)
g_memmove (g_array_elt_pos (array, index),
g_array_elt_pos (array, index + 1),
g_array_elt_len (array, array->len - index - 1));
array->len -= 1;
#ifdef ENABLE_GC_FRIENDLY
g_array_elt_zero (array, array->len, 1);
#else /* !ENABLE_GC_FRIENDLY */
g_array_zero_terminate (array);
#endif /* ENABLE_GC_FRIENDLY */
return farray;
}
GArray*
g_array_remove_index_fast (GArray* farray,
guint index)
{
GRealArray* array = (GRealArray*) farray;
g_return_val_if_fail (array, NULL);
g_return_val_if_fail (index < array->len, NULL);
if (index != array->len - 1)
memcpy (g_array_elt_pos (array, index),
g_array_elt_pos (array, array->len - 1),
g_array_elt_len (array, 1));
array->len -= 1;
#ifdef ENABLE_GC_FRIENDLY
g_array_elt_zero (array, array->len, 1);
#else /* !ENABLE_GC_FRIENDLY */
g_array_zero_terminate (array);
#endif /* ENABLE_GC_FRIENDLY */
return farray;
}
void
g_array_sort (GArray *farray,
GCompareFunc compare_func)
{
GRealArray *array = (GRealArray*) farray;
g_return_if_fail (array != NULL);
g_return_if_fail (array->data != NULL);
qsort (array->data,
array->len,
array->elt_size,
compare_func);
}
void
g_array_sort_with_data (GArray *farray,
GCompareDataFunc compare_func,
gpointer user_data)
{
GRealArray *array = (GRealArray*) farray;
g_return_if_fail (array != NULL);
g_return_if_fail (array->data != NULL);
g_qsort_with_data (array->data,
array->len,
array->elt_size,
compare_func,
user_data);
}
static gint
g_nearest_pow (gint num)
{
gint n = 1;
while (n < num)
n <<= 1;
return n;
}
static void
g_array_maybe_expand (GRealArray *array,
gint len)
{
guint want_alloc = g_array_elt_len (array, array->len + len +
array->zero_terminated);
if (want_alloc > array->alloc)
{
want_alloc = g_nearest_pow (want_alloc);
want_alloc = MAX (want_alloc, MIN_ARRAY_SIZE);
array->data = g_realloc (array->data, want_alloc);
#ifdef ENABLE_GC_FRIENDLY
memset (array->data + array->alloc, 0, want_alloc - array->alloc);
#endif /* ENABLE_GC_FRIENDLY */
array->alloc = want_alloc;
}
}
/* Pointer Array
*/
typedef struct _GRealPtrArray GRealPtrArray;
struct _GRealPtrArray
{
gpointer *pdata;
guint len;
guint alloc;
};
static void g_ptr_array_maybe_expand (GRealPtrArray *array,
gint len);
static GMemChunk *ptr_array_mem_chunk = NULL;
G_LOCK_DEFINE_STATIC (ptr_array_mem_chunk);
GPtrArray*
g_ptr_array_new (void)
{
return g_ptr_array_sized_new (0);
}
GPtrArray*
g_ptr_array_sized_new (guint reserved_size)
{
GRealPtrArray *array;
G_LOCK (ptr_array_mem_chunk);
if (!ptr_array_mem_chunk)
ptr_array_mem_chunk = g_mem_chunk_new ("array mem chunk",
sizeof (GRealPtrArray),
1024, G_ALLOC_AND_FREE);
array = g_chunk_new (GRealPtrArray, ptr_array_mem_chunk);
G_UNLOCK (ptr_array_mem_chunk);
array->pdata = NULL;
array->len = 0;
array->alloc = 0;
if (reserved_size != 0)
g_ptr_array_maybe_expand (array, reserved_size);
return (GPtrArray*) array;
}
gpointer*
g_ptr_array_free (GPtrArray *array,
gboolean free_segment)
{
gpointer* segment;
g_return_val_if_fail (array, NULL);
if (free_segment)
{
g_free (array->pdata);
segment = NULL;
}
else
segment = array->pdata;
G_LOCK (ptr_array_mem_chunk);
g_mem_chunk_free (ptr_array_mem_chunk, array);
G_UNLOCK (ptr_array_mem_chunk);
return segment;
}
static void
g_ptr_array_maybe_expand (GRealPtrArray *array,
gint len)
{
if ((array->len + len) > array->alloc)
{
#ifdef ENABLE_GC_FRIENDLY
guint old_alloc = array->alloc;
#endif /* ENABLE_GC_FRIENDLY */
array->alloc = g_nearest_pow (array->len + len);
array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
array->pdata = g_realloc (array->pdata, sizeof(gpointer) * array->alloc);
#ifdef ENABLE_GC_FRIENDLY
for ( ; old_alloc < array->alloc; old_alloc++)
array->pdata [old_alloc] = NULL;
#endif /* ENABLE_GC_FRIENDLY */
}
}
void
g_ptr_array_set_size (GPtrArray *farray,
gint length)
{
GRealPtrArray* array = (GRealPtrArray*) farray;
g_return_if_fail (array);
if (length > array->len)
{
int i;
g_ptr_array_maybe_expand (array, (length - array->len));
/* This is not
* memset (array->pdata + array->len, 0,
* sizeof (gpointer) * (length - array->len));
* to make it really portable. Remember (void*)NULL needn't be
* bitwise zero. It of course is silly not to use memset (..,0,..).
*/
for (i = array->len; i < length; i++)
array->pdata[i] = NULL;
}
#ifdef ENABLE_GC_FRIENDLY
else if (length < array->len)
{
int i;
for (i = length; i < array->len; i++)
array->pdata[i] = NULL;
}
#endif /* ENABLE_GC_FRIENDLY */
array->len = length;
}
gpointer
g_ptr_array_remove_index (GPtrArray* farray,
guint index)
{
GRealPtrArray* array = (GRealPtrArray*) farray;
gpointer result;
g_return_val_if_fail (array, NULL);
g_return_val_if_fail (index < array->len, NULL);
result = array->pdata[index];
if (index != array->len - 1)
g_memmove (array->pdata + index, array->pdata + index + 1,
sizeof (gpointer) * (array->len - index - 1));
array->len -= 1;
#ifdef ENABLE_GC_FRIENDLY
array->pdata[array->len] = NULL;
#endif /* ENABLE_GC_FRIENDLY */
return result;
}
gpointer
g_ptr_array_remove_index_fast (GPtrArray* farray,
guint index)
{
GRealPtrArray* array = (GRealPtrArray*) farray;
gpointer result;
g_return_val_if_fail (array, NULL);
g_return_val_if_fail (index < array->len, NULL);
result = array->pdata[index];
if (index != array->len - 1)
array->pdata[index] = array->pdata[array->len - 1];
array->len -= 1;
#ifdef ENABLE_GC_FRIENDLY
array->pdata[array->len] = NULL;
#endif /* ENABLE_GC_FRIENDLY */
return result;
}
gboolean
g_ptr_array_remove (GPtrArray* farray,
gpointer data)
{
GRealPtrArray* array = (GRealPtrArray*) farray;
guint i;
g_return_val_if_fail (array, FALSE);
for (i = 0; i < array->len; i += 1)
{
if (array->pdata[i] == data)
{
g_ptr_array_remove_index (farray, i);
return TRUE;
}
}
return FALSE;
}
gboolean
g_ptr_array_remove_fast (GPtrArray* farray,
gpointer data)
{
GRealPtrArray* array = (GRealPtrArray*) farray;
guint i;
g_return_val_if_fail (array, FALSE);
for (i = 0; i < array->len; i += 1)
{
if (array->pdata[i] == data)
{
g_ptr_array_remove_index_fast (farray, i);
return TRUE;
}
}
return FALSE;
}
void
g_ptr_array_add (GPtrArray* farray,
gpointer data)
{
GRealPtrArray* array = (GRealPtrArray*) farray;
g_return_if_fail (array);
g_ptr_array_maybe_expand (array, 1);
array->pdata[array->len++] = data;
}
void
g_ptr_array_sort (GPtrArray *array,
GCompareFunc compare_func)
{
g_return_if_fail (array != NULL);
g_return_if_fail (array->pdata != NULL);
qsort (array->pdata,
array->len,
sizeof (gpointer),
compare_func);
}
void
g_ptr_array_sort_with_data (GPtrArray *array,
GCompareDataFunc compare_func,
gpointer user_data)
{
g_return_if_fail (array != NULL);
g_return_if_fail (array->pdata != NULL);
g_qsort_with_data (array->pdata,
array->len,
sizeof (gpointer),
compare_func,
user_data);
}
/* Byte arrays
*/
GByteArray* g_byte_array_new (void)
{
return (GByteArray*) g_array_sized_new (FALSE, FALSE, 1, 0);
}
GByteArray* g_byte_array_sized_new (guint reserved_size)
{
return (GByteArray*) g_array_sized_new (FALSE, FALSE, 1, reserved_size);
}
guint8* g_byte_array_free (GByteArray *array,
gboolean free_segment)
{
return (guint8*) g_array_free ((GArray*) array, free_segment);
}
GByteArray* g_byte_array_append (GByteArray *array,
const guint8 *data,
guint len)
{
g_array_append_vals ((GArray*) array, (guint8*)data, len);
return array;
}
GByteArray* g_byte_array_prepend (GByteArray *array,
const guint8 *data,
guint len)
{
g_array_prepend_vals ((GArray*) array, (guint8*)data, len);
return array;
}
GByteArray* g_byte_array_set_size (GByteArray *array,
guint length)
{
g_array_set_size ((GArray*) array, length);
return array;
}
GByteArray* g_byte_array_remove_index (GByteArray *array,
guint index)
{
g_array_remove_index((GArray*) array, index);
return array;
}
GByteArray* g_byte_array_remove_index_fast (GByteArray *array,
guint index)
{
g_array_remove_index_fast((GArray*) array, index);
return array;
}
void
g_byte_array_sort (GByteArray *array,
GCompareFunc compare_func)
{
g_array_sort ((GArray *) array, compare_func);
}
void
g_byte_array_sort_with_data (GByteArray *array,
GCompareDataFunc compare_func,
gpointer user_data)
{
g_array_sort_with_data ((GArray *) array, compare_func, user_data);
}

156
garray.h
View File

@ -1,156 +0,0 @@
/* 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 Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
#ifndef __G_ARRAY_H__
#define __G_ARRAY_H__
#include <gtypes.h>
G_BEGIN_DECLS
typedef struct _GArray GArray;
typedef struct _GByteArray GByteArray;
typedef struct _GPtrArray GPtrArray;
struct _GArray
{
gchar *data;
guint len;
};
struct _GByteArray
{
guint8 *data;
guint len;
};
struct _GPtrArray
{
gpointer *pdata;
guint len;
};
/* Resizable arrays, remove fills any cleared spot and shortens the
* array, while preserving the order. remove_fast will distort the
* order by moving the last element to the position of the removed
*/
#define g_array_append_val(a,v) g_array_append_vals (a, &(v), 1)
#define g_array_prepend_val(a,v) g_array_prepend_vals (a, &(v), 1)
#define g_array_insert_val(a,i,v) g_array_insert_vals (a, i, &(v), 1)
#define g_array_index(a,t,i) (((t*) (a)->data) [(i)])
GArray* g_array_new (gboolean zero_terminated,
gboolean clear,
guint element_size);
GArray* g_array_sized_new (gboolean zero_terminated,
gboolean clear,
guint element_size,
guint reserved_size);
gchar* g_array_free (GArray *array,
gboolean free_segment);
GArray* g_array_append_vals (GArray *array,
gconstpointer data,
guint len);
GArray* g_array_prepend_vals (GArray *array,
gconstpointer data,
guint len);
GArray* g_array_insert_vals (GArray *array,
guint index,
gconstpointer data,
guint len);
GArray* g_array_set_size (GArray *array,
guint length);
GArray* g_array_remove_index (GArray *array,
guint index);
GArray* g_array_remove_index_fast (GArray *array,
guint index);
void g_array_sort (GArray *array,
GCompareFunc compare_func);
void g_array_sort_with_data (GArray *array,
GCompareDataFunc compare_func,
gpointer user_data);
/* Resizable pointer array. This interface is much less complicated
* than the above. Add appends appends a pointer. Remove fills any
* cleared spot and shortens the array. remove_fast will again distort
* order.
*/
#define g_ptr_array_index(array,index) (array->pdata)[index]
GPtrArray* g_ptr_array_new (void);
GPtrArray* g_ptr_array_sized_new (guint reserved_size);
gpointer* g_ptr_array_free (GPtrArray *array,
gboolean free_seg);
void g_ptr_array_set_size (GPtrArray *array,
gint length);
gpointer g_ptr_array_remove_index (GPtrArray *array,
guint index);
gpointer g_ptr_array_remove_index_fast (GPtrArray *array,
guint index);
gboolean g_ptr_array_remove (GPtrArray *array,
gpointer data);
gboolean g_ptr_array_remove_fast (GPtrArray *array,
gpointer data);
void g_ptr_array_add (GPtrArray *array,
gpointer data);
void g_ptr_array_sort (GPtrArray *array,
GCompareFunc compare_func);
void g_ptr_array_sort_with_data (GPtrArray *array,
GCompareDataFunc compare_func,
gpointer user_data);
/* Byte arrays, an array of guint8. Implemented as a GArray,
* but type-safe.
*/
GByteArray* g_byte_array_new (void);
GByteArray* g_byte_array_sized_new (guint reserved_size);
guint8* g_byte_array_free (GByteArray *array,
gboolean free_segment);
GByteArray* g_byte_array_append (GByteArray *array,
const guint8 *data,
guint len);
GByteArray* g_byte_array_prepend (GByteArray *array,
const guint8 *data,
guint len);
GByteArray* g_byte_array_set_size (GByteArray *array,
guint length);
GByteArray* g_byte_array_remove_index (GByteArray *array,
guint index);
GByteArray* g_byte_array_remove_index_fast (GByteArray *array,
guint index);
void g_byte_array_sort (GByteArray *array,
GCompareFunc compare_func);
void g_byte_array_sort_with_data (GByteArray *array,
GCompareDataFunc compare_func,
gpointer user_data);
G_END_DECLS
#endif /* __G_ARRAY_H__ */

View File

@ -1,443 +0,0 @@
/* GLIB - Library of useful routines for C programming
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* GAsyncQueue: asynchronous queue implementation, based on Gqueue.
* Copyright (C) 2000 Sebastian Wilhelmi; University of Karlsruhe
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* MT safe
*/
#include "glib.h"
struct _GAsyncQueue
{
GMutex *mutex;
GCond *cond;
GQueue *queue;
guint waiting_threads;
guint ref_count;
};
/**
* g_async_queue_new:
*
* Creates a new asynchronous queue with the initial reference count of 1.
*
* Return value: the new #GAsyncQueue.
**/
GAsyncQueue*
g_async_queue_new ()
{
GAsyncQueue* retval = g_new (GAsyncQueue, 1);
retval->mutex = g_mutex_new ();
retval->cond = g_cond_new ();
retval->queue = g_queue_new ();
retval->waiting_threads = 0;
retval->ref_count = 1;
return retval;
}
/**
* g_async_queue_ref:
* @queue: a #GAsyncQueue.
*
* Increases the reference count of the asynchronous @queue by 1.
**/
void
g_async_queue_ref (GAsyncQueue *queue)
{
g_return_if_fail (queue);
g_return_if_fail (queue->ref_count > 0);
g_mutex_lock (queue->mutex);
queue->ref_count++;
g_mutex_unlock (queue->mutex);
}
/**
* g_async_queue_ref_unlocked:
* @queue: a #GAsyncQueue.
*
* Increases the reference count of the asynchronous @queue by 1. This
* function must be called while holding the @queue's lock.
**/
void
g_async_queue_ref_unlocked (GAsyncQueue *queue)
{
g_return_if_fail (queue);
g_return_if_fail (queue->ref_count > 0);
queue->ref_count++;
}
/**
* g_async_queue_unref_and_unlock:
* @queue: a #GAsyncQueue.
*
* Decreases the reference count of the asynchronous @queue by 1 and
* releases the lock. This function must be called while holding the
* @queue's lock. If the reference count went to 0, the @queue will be
* destroyed and the memory allocated will be freed. So you are not
* allowed to use the @queue afterwards, as it might have disappeared.
* The obvious asymmetry (it is not named
* g_async_queue_unref_unlocked) is because the queue can't be
* unlocked after dereffing it, as it might already have disappeared.
**/
void
g_async_queue_unref_and_unlock (GAsyncQueue *queue)
{
gboolean stop;
g_return_if_fail (queue);
g_return_if_fail (queue->ref_count > 0);
queue->ref_count--;
stop = (queue->ref_count == 0);
g_mutex_unlock (queue->mutex);
if (stop)
{
g_return_if_fail (queue->waiting_threads == 0);
g_mutex_free (queue->mutex);
g_cond_free (queue->cond);
g_queue_free (queue->queue);
g_free (queue);
}
}
/**
* g_async_queue_unref:
* @queue: a #GAsyncQueue.
*
* Decreases the reference count of the asynchronous @queue by 1. If
* the reference count went to 0, the @queue will be destroyed and the
* memory allocated will be freed. So you are not allowed to use the
* @queue afterwards, as it might have disappeared.
**/
void
g_async_queue_unref (GAsyncQueue *queue)
{
g_return_if_fail (queue);
g_return_if_fail (queue->ref_count > 0);
g_mutex_lock (queue->mutex);
g_async_queue_unref_and_unlock (queue);
}
/**
* g_async_queue_lock:
* @queue: a #GAsyncQueue.
*
* Acquire the @queue's lock. After that you can only call the
* g_async_queue_*_unlocked function variants on that
* @queue. Otherwise it will deadlock.
**/
void
g_async_queue_lock (GAsyncQueue *queue)
{
g_return_if_fail (queue);
g_return_if_fail (queue->ref_count > 0);
g_mutex_lock (queue->mutex);
}
/**
* g_async_queue_unlock:
* @queue: a #GAsyncQueue.
*
* Release the queue's lock.
**/
void
g_async_queue_unlock (GAsyncQueue *queue)
{
g_return_if_fail (queue);
g_return_if_fail (queue->ref_count > 0);
g_mutex_unlock (queue->mutex);
}
/**
* g_async_queue_push:
* @queue: a #GAsyncQueue.
* @data: @data to push into the @queue.
*
* Push the @data into the @queue. @data must not be #NULL.
**/
void
g_async_queue_push (GAsyncQueue* queue, gpointer data)
{
g_return_if_fail (queue);
g_return_if_fail (queue->ref_count > 0);
g_return_if_fail (data);
g_mutex_lock (queue->mutex);
g_async_queue_push_unlocked (queue, data);
g_mutex_unlock (queue->mutex);
}
/**
* g_async_queue_push_unlocked:
* @queue: a #GAsyncQueue.
* @data: @data to push into the @queue.
*
* Push the @data into the @queue. @data must not be #NULL. This
* function must be called while holding the @queue's lock.
**/
void
g_async_queue_push_unlocked (GAsyncQueue* queue, gpointer data)
{
g_return_if_fail (queue);
g_return_if_fail (queue->ref_count > 0);
g_return_if_fail (data);
g_queue_push_head (queue->queue, data);
g_cond_signal (queue->cond);
}
static gpointer
g_async_queue_pop_intern_unlocked (GAsyncQueue* queue, gboolean try,
GTimeVal *end_time)
{
gpointer retval;
if (!g_queue_peek_tail (queue->queue))
{
if (try)
return NULL;
if (!end_time)
{
queue->waiting_threads++;
while (!g_queue_peek_tail (queue->queue))
g_cond_wait(queue->cond, queue->mutex);
queue->waiting_threads--;
}
else
{
queue->waiting_threads++;
while (!g_queue_peek_tail (queue->queue))
if (!g_cond_timed_wait (queue->cond, queue->mutex, end_time))
break;
queue->waiting_threads--;
if (!g_queue_peek_tail (queue->queue))
return NULL;
}
}
retval = g_queue_pop_tail (queue->queue);
g_assert (retval);
return retval;
}
/**
* g_async_queue_pop:
* @queue: a #GAsyncQueue.
*
* Pop data from the @queue. This function blocks until data become
* available.
*
* Return value: data from the queue.
**/
gpointer
g_async_queue_pop (GAsyncQueue* queue)
{
gpointer retval;
g_return_val_if_fail (queue, NULL);
g_return_val_if_fail (queue->ref_count > 0, NULL);
g_mutex_lock (queue->mutex);
retval = g_async_queue_pop_intern_unlocked (queue, FALSE, NULL);
g_mutex_unlock (queue->mutex);
return retval;
}
/**
* g_async_queue_pop_unlocked:
* @queue: a #GAsyncQueue.
*
* Pop data from the @queue. This function blocks until data become
* available. This function must be called while holding the @queue's
* lock.
*
* Return value: data from the queue.
**/
gpointer
g_async_queue_pop_unlocked (GAsyncQueue* queue)
{
g_return_val_if_fail (queue, NULL);
g_return_val_if_fail (queue->ref_count > 0, NULL);
return g_async_queue_pop_intern_unlocked (queue, FALSE, NULL);
}
/**
* g_async_queue_try_pop:
* @queue: a #GAsyncQueue.
*
* Try to pop data from the @queue. If no data is available, #NULL is
* returned.
*
* Return value: data from the queue or #NULL, when no data is
* available immediately.
**/
gpointer
g_async_queue_try_pop (GAsyncQueue* queue)
{
gpointer retval;
g_return_val_if_fail (queue, NULL);
g_return_val_if_fail (queue->ref_count > 0, NULL);
g_mutex_lock (queue->mutex);
retval = g_async_queue_pop_intern_unlocked (queue, TRUE, NULL);
g_mutex_unlock (queue->mutex);
return retval;
}
/**
* g_async_queue_try_pop_unlocked:
* @queue: a #GAsyncQueue.
*
* Try to pop data from the @queue. If no data is available, #NULL is
* returned. This function must be called while holding the @queue's
* lock.
*
* Return value: data from the queue or #NULL, when no data is
* available immediately.
**/
gpointer
g_async_queue_try_pop_unlocked (GAsyncQueue* queue)
{
g_return_val_if_fail (queue, NULL);
g_return_val_if_fail (queue->ref_count > 0, NULL);
return g_async_queue_pop_intern_unlocked (queue, TRUE, NULL);
}
/**
* g_async_queue_timed_pop:
* @queue: a #GAsyncQueue.
* @end_time: a #GTimeVal, determining the final time.
*
* Pop data from the @queue. If no data is received before @end_time,
* #NULL is returned.
*
* To easily calculate @end_time a combination of g_get_current_time()
* and g_time_val_add() can be used.
*
* Return value: data from the queue or #NULL, when no data is
* received before @end_time.
**/
gpointer
g_async_queue_timed_pop (GAsyncQueue* queue, GTimeVal *end_time)
{
gpointer retval;
g_return_val_if_fail (queue, NULL);
g_return_val_if_fail (queue->ref_count > 0, NULL);
g_mutex_lock (queue->mutex);
retval = g_async_queue_pop_intern_unlocked (queue, FALSE, end_time);
g_mutex_unlock (queue->mutex);
return retval;
}
/**
* g_async_queue_timed_pop_unlocked:
* @queue: a #GAsyncQueue.
* @end_time: a #GTimeVal, determining the final time.
*
* Pop data from the @queue. If no data is received before @end_time,
* #NULL is returned. This function must be called while holding the
* @queue's lock.
*
* To easily calculate @end_time a combination of g_get_current_time()
* and g_time_val_add() can be used.
*
* Return value: data from the queue or #NULL, when no data is
* received before @end_time.
**/
gpointer
g_async_queue_timed_pop_unlocked (GAsyncQueue* queue, GTimeVal *end_time)
{
g_return_val_if_fail (queue, NULL);
g_return_val_if_fail (queue->ref_count > 0, NULL);
return g_async_queue_pop_intern_unlocked (queue, FALSE, end_time);
}
/**
* g_async_queue_length:
* @queue: a #GAsyncQueue.
*
* Returns the length of the queue, negative values mean waiting
* threads, positive values mean available entries in the
* @queue. Actually this function returns the number of data items in
* the queue minus the number of waiting threads. Thus a return value
* of 0 could mean 'n' entries in the queue and 'n' thread waiting.
* That can happen due to locking of the queue or due to
* scheduling.
*
* Return value: the length of the @queue.
**/
gint
g_async_queue_length (GAsyncQueue* queue)
{
gint retval;
g_return_val_if_fail (queue, 0);
g_return_val_if_fail (queue->ref_count > 0, 0);
g_mutex_lock (queue->mutex);
retval = queue->queue->length - queue->waiting_threads;
g_mutex_unlock (queue->mutex);
return retval;
}
/**
* g_async_queue_length_unlocked:
* @queue: a #GAsyncQueue.
*
* Returns the length of the queue, negative values mean waiting
* threads, positive values mean available entries in the
* @queue. Actually this function returns the number of data items in
* the queue minus the number of waiting threads. Thus a return value
* of 0 could mean 'n' entries in the queue and 'n' thread waiting.
* That can happen due to locking of the queue or due to
* scheduling. This function must be called while holding the @queue's
* lock.
*
* Return value: the length of the @queue.
**/
gint
g_async_queue_length_unlocked (GAsyncQueue* queue)
{
g_return_val_if_fail (queue, 0);
g_return_val_if_fail (queue->ref_count > 0, 0);
return queue->queue->length - queue->waiting_threads;
}

View File

@ -1,95 +0,0 @@
/* 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 Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
#ifndef __G_ASYNCQUEUE_H__
#define __G_ASYNCQUEUE_H__
#include <gthread.h>
G_BEGIN_DECLS
typedef struct _GAsyncQueue GAsyncQueue;
/* Asyncronous Queues, can be used to communicate between threads
*/
/* Get a new GAsyncQueue with the ref_count 1 */
GAsyncQueue* g_async_queue_new (void);
/* Lock and unlock an GAsyncQueue, all functions lock the queue for
* themselves, but in certain cirumstances you want to hold the lock longer,
* thus you lock the queue, call the *_unlocked functions and unlock it again
*/
void g_async_queue_lock (GAsyncQueue *queue);
void g_async_queue_unlock (GAsyncQueue *queue);
/* Ref and unref the GAsyncQueue. g_async_queue_unref_unlocked makes
* no sense, as after the unreffing the Queue might be gone and can't
* be unlocked. So you have a function to call, if you don't hold the
* lock (g_async_queue_unref) and one to call, when you already hold
* the lock (g_async_queue_unref_and_unlock). After that however, you
* don't hold the lock anymore and the Queue might in fact be
* destroyed, if you unrefed to zero */
void g_async_queue_ref (GAsyncQueue *queue);
void g_async_queue_ref_unlocked (GAsyncQueue *queue);
void g_async_queue_unref (GAsyncQueue *queue);
void g_async_queue_unref_and_unlock (GAsyncQueue *queue);
/* Push data into the async queue. Must not be NULL */
void g_async_queue_push (GAsyncQueue *queue,
gpointer data);
void g_async_queue_push_unlocked (GAsyncQueue *queue,
gpointer data);
/* Pop data from the async queue, when no data is there, the thread is blocked
* until data arrives */
gpointer g_async_queue_pop (GAsyncQueue *queue);
gpointer g_async_queue_pop_unlocked (GAsyncQueue *queue);
/* Try to pop data, NULL is returned in case of empty queue */
gpointer g_async_queue_try_pop (GAsyncQueue *queue);
gpointer g_async_queue_try_pop_unlocked (GAsyncQueue *queue);
/* Wait for data until at maximum until end_time is reached, NULL is returned
* in case of empty queue*/
gpointer g_async_queue_timed_pop (GAsyncQueue *queue,
GTimeVal *end_time);
gpointer g_async_queue_timed_pop_unlocked (GAsyncQueue *queue,
GTimeVal *end_time);
/* Return the length of the queue, negative values mean, that threads
* are waiting, positve values mean, that there are entries in the
* queue. Actually this function returns the length of the queue minus
* the number of waiting threads, g_async_queue_length == 0 could also
* mean 'n' entries in the queue and 'n' thread waiting, such can
* happen due to locking of the queue or due to scheduling. */
gint g_async_queue_length (GAsyncQueue *queue);
gint g_async_queue_length_unlocked (GAsyncQueue *queue);
G_END_DECLS
#endif /* __G_ASYNCQUEUE_H__ */

View File

@ -1,300 +0,0 @@
/* 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 Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
/*
* MT safe ; except for g_on_error_stack_trace, but who wants thread safety
* then
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include "glib.h"
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_SYS_TIMES_H
#include <sys/times.h>
#endif
#include <sys/types.h>
#include <time.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif /* HAVE_SYS_SELECT_H */
#ifdef STDC_HEADERS
#include <string.h> /* for bzero on BSD systems */
#endif
#ifdef G_OS_WIN32
# define STRICT /* Strict typing, please */
# include <windows.h>
# undef STRICT
#endif
#ifndef NO_FD_SET
# define SELECT_MASK fd_set
#else
# if defined(_IBMR2)
# define SELECT_MASK void
# else
# define SELECT_MASK int
# endif
#endif
#ifndef G_OS_WIN32
static void stack_trace (char **args);
#endif
extern volatile gboolean glib_on_error_halt;
volatile gboolean glib_on_error_halt = TRUE;
void
g_on_error_query (const gchar *prg_name)
{
#ifndef G_OS_WIN32
static const gchar *query1 = "[E]xit, [H]alt";
static const gchar *query2 = ", show [S]tack trace";
static const gchar *query3 = " or [P]roceed";
gchar buf[16];
if (!prg_name)
prg_name = g_get_prgname ();
retry:
if (prg_name)
fprintf (stdout,
"%s (pid:%u): %s%s%s: ",
prg_name,
(guint) getpid (),
query1,
query2,
query3);
else
fprintf (stdout,
"(process:%u): %s%s: ",
(guint) getpid (),
query1,
query3);
fflush (stdout);
if (isatty(0) && isatty(1))
fgets (buf, 8, stdin);
else
strcpy (buf, "E\n");
if ((buf[0] == 'E' || buf[0] == 'e')
&& buf[1] == '\n')
_exit (0);
else if ((buf[0] == 'P' || buf[0] == 'p')
&& buf[1] == '\n')
return;
else if (prg_name
&& (buf[0] == 'S' || buf[0] == 's')
&& buf[1] == '\n')
{
g_on_error_stack_trace (prg_name);
goto retry;
}
else if ((buf[0] == 'H' || buf[0] == 'h')
&& buf[1] == '\n')
{
while (glib_on_error_halt)
;
glib_on_error_halt = TRUE;
return;
}
else
goto retry;
#else
if (!prg_name)
prg_name = g_get_prgname ();
MessageBox (NULL, "g_on_error_query called, program terminating",
(prg_name && *prg_name) ? prg_name : NULL,
MB_OK|MB_ICONERROR);
_exit(0);
#endif
}
void
g_on_error_stack_trace (const gchar *prg_name)
{
#ifdef G_OS_UNIX
pid_t pid;
gchar buf[16];
gchar *args[4] = { "gdb", NULL, NULL, NULL };
if (!prg_name)
return;
sprintf (buf, "%u", (guint) getpid ());
args[1] = (gchar*) prg_name;
args[2] = buf;
pid = fork ();
if (pid == 0)
{
stack_trace (args);
_exit (0);
}
else if (pid == (pid_t) -1)
{
perror ("unable to fork gdb");
return;
}
while (glib_on_error_halt)
;
glib_on_error_halt = TRUE;
#else
abort ();
#endif
}
#ifndef G_OS_WIN32
static gboolean stack_trace_done = FALSE;
static void
stack_trace_sigchld (int signum)
{
stack_trace_done = TRUE;
}
static void
stack_trace (char **args)
{
pid_t pid;
int in_fd[2];
int out_fd[2];
SELECT_MASK fdset;
SELECT_MASK readset;
struct timeval tv;
int sel, index, state;
char buffer[256];
char c;
stack_trace_done = FALSE;
signal (SIGCHLD, stack_trace_sigchld);
if ((pipe (in_fd) == -1) || (pipe (out_fd) == -1))
{
perror ("unable to open pipe");
_exit (0);
}
pid = fork ();
if (pid == 0)
{
close (0); dup (in_fd[0]); /* set the stdin to the in pipe */
close (1); dup (out_fd[1]); /* set the stdout to the out pipe */
close (2); dup (out_fd[1]); /* set the stderr to the out pipe */
execvp (args[0], args); /* exec gdb */
perror ("exec failed");
_exit (0);
}
else if (pid == (pid_t) -1)
{
perror ("unable to fork");
_exit (0);
}
FD_ZERO (&fdset);
FD_SET (out_fd[0], &fdset);
write (in_fd[1], "backtrace\n", 10);
write (in_fd[1], "p x = 0\n", 8);
write (in_fd[1], "quit\n", 5);
index = 0;
state = 0;
while (1)
{
readset = fdset;
tv.tv_sec = 1;
tv.tv_usec = 0;
sel = select (FD_SETSIZE, &readset, NULL, NULL, &tv);
if (sel == -1)
break;
if ((sel > 0) && (FD_ISSET (out_fd[0], &readset)))
{
if (read (out_fd[0], &c, 1))
{
switch (state)
{
case 0:
if (c == '#')
{
state = 1;
index = 0;
buffer[index++] = c;
}
break;
case 1:
buffer[index++] = c;
if ((c == '\n') || (c == '\r'))
{
buffer[index] = 0;
fprintf (stdout, "%s", buffer);
state = 0;
index = 0;
}
break;
default:
break;
}
}
}
else if (stack_trace_done)
break;
}
close (in_fd[0]);
close (in_fd[1]);
close (out_fd[0]);
close (out_fd[1]);
_exit (0);
}
#endif /* !G_OS_WIN32 */

View File

@ -1,61 +0,0 @@
/* 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 Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
#ifndef __G_BACKTRACE_H__
#define __G_BACKTRACE_H__
#include <gtypes.h>
G_BEGIN_DECLS
/* Fatal error handlers.
* g_on_error_query() will prompt the user to either
* [E]xit, [H]alt, [P]roceed or show [S]tack trace.
* g_on_error_stack_trace() invokes gdb, which attaches to the current
* process and shows a stack trace.
* These function may cause different actions on non-unix platforms.
* The prg_name arg is required by gdb to find the executable, if it is
* passed as NULL, g_on_error_query() will try g_get_prgname().
*/
void g_on_error_query (const gchar *prg_name);
void g_on_error_stack_trace (const gchar *prg_name);
/* Hacker macro to place breakpoints for elected machines.
* Actual use is strongly deprecated of course ;)
*/
#if defined (__i386__) && defined (__GNUC__) && __GNUC__ >= 2
# define G_BREAKPOINT() G_STMT_START{ __asm__ __volatile__ ("int $03"); }G_STMT_END
#elif defined (_MSC_VER) && defined (_M_IX86)
# define G_BREAKPOINT() G_STMT_START{ __asm int 3h }G_STMT_END
#elif defined (__alpha__) && defined (__GNUC__) && __GNUC__ >= 2
# define G_BREAKPOINT() G_STMT_START{ __asm__ __volatile__ ("bpt"); }G_STMT_END
#else /* !__i386__ && !__alpha__ */
# define G_BREAKPOINT() G_STMT_START{ raise (5 /* SIGTRAP */); }G_STMT_END
#endif /* __i386__ */
G_END_DECLS
#endif /* __G_BACKTRACE_H__ */

230
gcache.c
View File

@ -1,230 +0,0 @@
/* 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 Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
/*
* MT safe
*/
#include "glib.h"
typedef struct _GCacheNode GCacheNode;
typedef struct _GRealCache GRealCache;
struct _GCacheNode
{
/* A reference counted node */
gpointer value;
gint ref_count;
};
struct _GRealCache
{
/* Called to create a value from a key */
GCacheNewFunc value_new_func;
/* Called to destroy a value */
GCacheDestroyFunc value_destroy_func;
/* Called to duplicate a key */
GCacheDupFunc key_dup_func;
/* Called to destroy a key */
GCacheDestroyFunc key_destroy_func;
/* Associates keys with nodes */
GHashTable *key_table;
/* Associates nodes with keys */
GHashTable *value_table;
};
static GCacheNode* g_cache_node_new (gpointer value);
static void g_cache_node_destroy (GCacheNode *node);
static GMemChunk *node_mem_chunk = NULL;
G_LOCK_DEFINE_STATIC (node_mem_chunk);
GCache*
g_cache_new (GCacheNewFunc value_new_func,
GCacheDestroyFunc value_destroy_func,
GCacheDupFunc key_dup_func,
GCacheDestroyFunc key_destroy_func,
GHashFunc hash_key_func,
GHashFunc hash_value_func,
GEqualFunc key_equal_func)
{
GRealCache *cache;
g_return_val_if_fail (value_new_func != NULL, NULL);
g_return_val_if_fail (value_destroy_func != NULL, NULL);
g_return_val_if_fail (key_dup_func != NULL, NULL);
g_return_val_if_fail (key_destroy_func != NULL, NULL);
g_return_val_if_fail (hash_key_func != NULL, NULL);
g_return_val_if_fail (hash_value_func != NULL, NULL);
g_return_val_if_fail (key_equal_func != NULL, NULL);
cache = g_new (GRealCache, 1);
cache->value_new_func = value_new_func;
cache->value_destroy_func = value_destroy_func;
cache->key_dup_func = key_dup_func;
cache->key_destroy_func = key_destroy_func;
cache->key_table = g_hash_table_new (hash_key_func, key_equal_func);
cache->value_table = g_hash_table_new (hash_value_func, NULL);
return (GCache*) cache;
}
void
g_cache_destroy (GCache *cache)
{
GRealCache *rcache;
g_return_if_fail (cache != NULL);
rcache = (GRealCache*) cache;
g_hash_table_destroy (rcache->key_table);
g_hash_table_destroy (rcache->value_table);
g_free (rcache);
}
gpointer
g_cache_insert (GCache *cache,
gpointer key)
{
GRealCache *rcache;
GCacheNode *node;
gpointer value;
g_return_val_if_fail (cache != NULL, NULL);
rcache = (GRealCache*) cache;
node = g_hash_table_lookup (rcache->key_table, key);
if (node)
{
node->ref_count += 1;
return node->value;
}
key = (* rcache->key_dup_func) (key);
value = (* rcache->value_new_func) (key);
node = g_cache_node_new (value);
g_hash_table_insert (rcache->key_table, key, node);
g_hash_table_insert (rcache->value_table, value, key);
return node->value;
}
void
g_cache_remove (GCache *cache,
gconstpointer value)
{
GRealCache *rcache;
GCacheNode *node;
gpointer key;
g_return_if_fail (cache != NULL);
rcache = (GRealCache*) cache;
key = g_hash_table_lookup (rcache->value_table, value);
node = g_hash_table_lookup (rcache->key_table, key);
g_return_if_fail (node != NULL);
node->ref_count -= 1;
if (node->ref_count == 0)
{
g_hash_table_remove (rcache->value_table, value);
g_hash_table_remove (rcache->key_table, key);
(* rcache->key_destroy_func) (key);
(* rcache->value_destroy_func) (node->value);
g_cache_node_destroy (node);
}
}
void
g_cache_key_foreach (GCache *cache,
GHFunc func,
gpointer user_data)
{
GRealCache *rcache;
g_return_if_fail (cache != NULL);
g_return_if_fail (func != NULL);
rcache = (GRealCache*) cache;
g_hash_table_foreach (rcache->value_table, func, user_data);
}
void
g_cache_value_foreach (GCache *cache,
GHFunc func,
gpointer user_data)
{
GRealCache *rcache;
g_return_if_fail (cache != NULL);
g_return_if_fail (func != NULL);
rcache = (GRealCache*) cache;
g_hash_table_foreach (rcache->key_table, func, user_data);
}
static GCacheNode*
g_cache_node_new (gpointer value)
{
GCacheNode *node;
G_LOCK (node_mem_chunk);
if (!node_mem_chunk)
node_mem_chunk = g_mem_chunk_new ("cache node mem chunk", sizeof (GCacheNode),
1024, G_ALLOC_AND_FREE);
node = g_chunk_new (GCacheNode, node_mem_chunk);
G_UNLOCK (node_mem_chunk);
node->value = value;
node->ref_count = 1;
return node;
}
static void
g_cache_node_destroy (GCacheNode *node)
{
G_LOCK (node_mem_chunk);
g_mem_chunk_free (node_mem_chunk, node);
G_UNLOCK (node_mem_chunk);
}

View File

@ -1,66 +0,0 @@
/* 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 Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
#ifndef __G_CACHE_H__
#define __G_CACHE_H__
#include <glist.h>
G_BEGIN_DECLS
typedef struct _GCache GCache;
typedef gpointer (*GCacheNewFunc) (gpointer key);
typedef gpointer (*GCacheDupFunc) (gpointer value);
typedef void (*GCacheDestroyFunc) (gpointer value);
/* Caches
*/
GCache* g_cache_new (GCacheNewFunc value_new_func,
GCacheDestroyFunc value_destroy_func,
GCacheDupFunc key_dup_func,
GCacheDestroyFunc key_destroy_func,
GHashFunc hash_key_func,
GHashFunc hash_value_func,
GEqualFunc key_equal_func);
void g_cache_destroy (GCache *cache);
gpointer g_cache_insert (GCache *cache,
gpointer key);
void g_cache_remove (GCache *cache,
gconstpointer value);
void g_cache_key_foreach (GCache *cache,
GHFunc func,
gpointer user_data);
void g_cache_value_foreach (GCache *cache,
GHFunc func,
gpointer user_data);
G_END_DECLS
#endif /* __G_CACHE_H__ */

View File

@ -1,296 +0,0 @@
/* 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 Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
/*
* MT safe
*/
#include "glib.h"
#include <string.h>
static void completion_check_cache (GCompletion* cmp,
gchar** new_prefix);
GCompletion*
g_completion_new (GCompletionFunc func)
{
GCompletion* gcomp;
gcomp = g_new (GCompletion, 1);
gcomp->items = NULL;
gcomp->cache = NULL;
gcomp->prefix = NULL;
gcomp->func = func;
gcomp->strncmp_func = strncmp;
return gcomp;
}
void
g_completion_add_items (GCompletion* cmp,
GList* items)
{
GList* it;
g_return_if_fail (cmp != NULL);
g_return_if_fail (items != NULL);
/* optimize adding to cache? */
if (cmp->cache)
{
g_list_free (cmp->cache);
cmp->cache = NULL;
}
if (cmp->prefix)
{
g_free (cmp->prefix);
cmp->prefix = NULL;
}
it = items;
while (it)
{
cmp->items = g_list_prepend (cmp->items, it->data);
it = it->next;
}
}
void
g_completion_remove_items (GCompletion* cmp,
GList* items)
{
GList* it;
g_return_if_fail (cmp != NULL);
g_return_if_fail (items != NULL);
it = items;
while (cmp->items && it)
{
cmp->items = g_list_remove (cmp->items, it->data);
it = it->next;
}
it = items;
while (cmp->cache && it)
{
cmp->cache = g_list_remove(cmp->cache, it->data);
it = it->next;
}
}
void
g_completion_clear_items (GCompletion* cmp)
{
g_return_if_fail (cmp != NULL);
g_list_free (cmp->items);
cmp->items = NULL;
g_list_free (cmp->cache);
cmp->cache = NULL;
g_free (cmp->prefix);
cmp->prefix = NULL;
}
static void
completion_check_cache (GCompletion* cmp,
gchar** new_prefix)
{
register GList* list;
register gsize len;
register gsize i;
register gsize plen;
gchar* postfix;
gchar* s;
if (!new_prefix)
return;
if (!cmp->cache)
{
*new_prefix = NULL;
return;
}
len = strlen(cmp->prefix);
list = cmp->cache;
s = cmp->func ? cmp->func (list->data) : (gchar*) list->data;
postfix = s + len;
plen = strlen (postfix);
list = list->next;
while (list && plen)
{
s = cmp->func ? cmp->func (list->data) : (gchar*) list->data;
s += len;
for (i = 0; i < plen; ++i)
{
if (postfix[i] != s[i])
break;
}
plen = i;
list = list->next;
}
*new_prefix = g_new0 (gchar, len + plen + 1);
strncpy (*new_prefix, cmp->prefix, len);
strncpy (*new_prefix + len, postfix, plen);
}
GList*
g_completion_complete (GCompletion* cmp,
gchar* prefix,
gchar** new_prefix)
{
gsize plen, len;
gboolean done = FALSE;
GList* list;
g_return_val_if_fail (cmp != NULL, NULL);
g_return_val_if_fail (prefix != NULL, NULL);
len = strlen (prefix);
if (cmp->prefix && cmp->cache)
{
plen = strlen (cmp->prefix);
if (plen <= len && ! cmp->strncmp_func (prefix, cmp->prefix, plen))
{
/* use the cache */
list = cmp->cache;
while (list)
{
if (cmp->strncmp_func (prefix,
cmp->func ? cmp->func (list->data) : (gchar*) list->data,
len))
{
list = g_list_remove_link (cmp->cache, list);
if (list != cmp->cache)
cmp->cache = list;
}
else
list = list->next;
}
done = TRUE;
}
}
if (!done)
{
/* normal code */
g_list_free (cmp->cache);
cmp->cache = NULL;
list = cmp->items;
while (*prefix && list)
{
if (!cmp->strncmp_func (prefix,
cmp->func ? cmp->func (list->data) : (gchar*) list->data,
len))
cmp->cache = g_list_prepend (cmp->cache, list->data);
list = list->next;
}
}
if (cmp->prefix)
{
g_free (cmp->prefix);
cmp->prefix = NULL;
}
if (cmp->cache)
cmp->prefix = g_strdup (prefix);
completion_check_cache (cmp, new_prefix);
return *prefix ? cmp->cache : cmp->items;
}
void
g_completion_free (GCompletion* cmp)
{
g_return_if_fail (cmp != NULL);
g_completion_clear_items (cmp);
g_free (cmp);
}
void
g_completion_set_compare(GCompletion *cmp,
GCompletionStrncmpFunc strncmp_func)
{
cmp->strncmp_func = strncmp_func;
}
#ifdef TEST_COMPLETION
#include <stdio.h>
int
main (int argc,
char* argv[])
{
FILE *file;
gchar buf[1024];
GList *list;
GList *result;
GList *tmp;
GCompletion *cmp;
gint i;
gchar *longp = NULL;
if (argc < 3)
{
g_warning ("Usage: %s filename prefix1 [prefix2 ...]\n", argv[0]);
return 1;
}
file = fopen (argv[1], "r");
if (!file)
{
g_warning ("Cannot open %s\n", argv[1]);
return 1;
}
cmp = g_completion_new (NULL);
list = g_list_alloc ();
while (fgets (buf, 1024, file))
{
list->data = g_strdup (buf);
g_completion_add_items (cmp, list);
}
fclose (file);
for (i = 2; i < argc; ++i)
{
printf ("COMPLETING: %s\n", argv[i]);
result = g_completion_complete (cmp, argv[i], &longp);
g_list_foreach (result, (GFunc) printf, NULL);
printf ("LONG MATCH: %s\n", longp);
g_free (longp);
longp = NULL;
}
g_list_foreach (cmp->items, (GFunc) g_free, NULL);
g_completion_free (cmp);
g_list_free (list);
return 0;
}
#endif

View File

@ -1,71 +0,0 @@
/* 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 Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
#ifndef __G_COMPLETION_H__
#define __G_COMPLETION_H__
#include <glist.h>
G_BEGIN_DECLS
typedef struct _GCompletion GCompletion;
typedef gchar* (*GCompletionFunc) (gpointer);
/* GCompletion
*/
typedef gint (*GCompletionStrncmpFunc) (const gchar *s1,
const gchar *s2,
gsize n);
struct _GCompletion
{
GList* items;
GCompletionFunc func;
gchar* prefix;
GList* cache;
GCompletionStrncmpFunc strncmp_func;
};
GCompletion* g_completion_new (GCompletionFunc func);
void g_completion_add_items (GCompletion* cmp,
GList* items);
void g_completion_remove_items (GCompletion* cmp,
GList* items);
void g_completion_clear_items (GCompletion* cmp);
GList* g_completion_complete (GCompletion* cmp,
gchar* prefix,
gchar** new_prefix);
void g_completion_set_compare (GCompletion *cmp,
GCompletionStrncmpFunc strncmp_func);
void g_completion_free (GCompletion* cmp);
G_END_DECLS
#endif /* __G_COMPLETION_H__ */

View File

@ -1,916 +0,0 @@
/* GLIB - Library of useful routines for C programming
*
* gconvert.c: Convert between character sets using iconv
* Copyright Red Hat Inc., 2000
* Authors: Havoc Pennington <hp@redhat.com>, Owen Taylor <otaylor@redhat.com
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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 <iconv.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include "glib.h"
#include "config.h"
#ifdef G_PLATFORM_WIN32
#define STRICT
#include <windows.h>
#undef STRICT
#endif
#include "glibintl.h"
GQuark
g_convert_error_quark()
{
static GQuark quark;
if (!quark)
quark = g_quark_from_static_string ("g_convert_error");
return quark;
}
#if defined(USE_LIBICONV) && !defined (_LIBICONV_H)
#error libiconv in use but included iconv.h not from libiconv
#endif
#if !defined(USE_LIBICONV) && defined (_LIBICONV_H)
#error libiconv not in use but included iconv.h is from libiconv
#endif
/**
* g_iconv_open:
* @to_codeset: destination codeset
* @from_codeset: source codeset
*
* Same as the standard UNIX routine iconv_open(), but
* may be implemented via libiconv on UNIX flavors that lack
* a native implementation.
*
* GLib provides g_convert() and g_locale_to_utf8() which are likely
* more convenient than the raw iconv wrappers.
*
* Return value: a "conversion descriptor"
**/
GIConv
g_iconv_open (const gchar *to_codeset,
const gchar *from_codeset)
{
iconv_t cd = iconv_open (to_codeset, from_codeset);
return (GIConv)cd;
}
/**
* g_iconv:
* @converter: conversion descriptor from g_iconv_open()
* @inbuf: bytes to convert
* @inbytes_left: inout parameter, bytes remaining to convert in @inbuf
* @outbuf: converted output bytes
* @outbytes_left: inout parameter, bytes available to fill in @outbuf
*
* Same as the standard UNIX routine iconv(), but
* may be implemented via libiconv on UNIX flavors that lack
* a native implementation.
*
* GLib provides g_convert() and g_locale_to_utf8() which are likely
* more convenient than the raw iconv wrappers.
*
* Return value: count of non-reversible conversions, or -1 on error
**/
size_t
g_iconv (GIConv converter,
gchar **inbuf,
gsize *inbytes_left,
gchar **outbuf,
gsize *outbytes_left)
{
iconv_t cd = (iconv_t)converter;
return iconv (cd, inbuf, inbytes_left, outbuf, outbytes_left);
}
/**
* g_iconv_close:
* @converter: a conversion descriptor from g_iconv_open()
*
* Same as the standard UNIX routine iconv_close(), but
* may be implemented via libiconv on UNIX flavors that lack
* a native implementation. Should be called to clean up
* the conversion descriptor from iconv_open() when
* you are done converting things.
*
* GLib provides g_convert() and g_locale_to_utf8() which are likely
* more convenient than the raw iconv wrappers.
*
* Return value: -1 on error, 0 on success
**/
gint
g_iconv_close (GIConv converter)
{
iconv_t cd = (iconv_t)converter;
return iconv_close (cd);
}
static GIConv
open_converter (const gchar *to_codeset,
const gchar *from_codeset,
GError **error)
{
GIConv cd = g_iconv_open (to_codeset, from_codeset);
if (cd == (iconv_t) -1)
{
/* Something went wrong. */
if (errno == EINVAL)
g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_NO_CONVERSION,
_("Conversion from character set `%s' to `%s' is not supported"),
from_codeset, to_codeset);
else
g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
_("Could not open converter from `%s' to `%s': %s"),
from_codeset, to_codeset, strerror (errno));
}
return cd;
}
/**
* g_convert:
* @str: the string to convert
* @len: the length of the string
* @to_codeset: name of character set into which to convert @str
* @from_codeset: character set of @str.
* @bytes_read: location to store the number of bytes in the
* input string that were successfully converted, or %NULL.
* Even if the conversion was succesful, this may be
* less than len if there were partial characters
* at the end of the input. If the error
* G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value
* stored will the byte fofset after the last valid
* input sequence.
* @bytes_written: the stored in the output buffer (not including the
* terminating nul.
* @error: location to store the error occuring, or %NULL to ignore
* errors. Any of the errors in #GConvertError may occur.
*
* Convert a string from one character set to another.
*
* Return value: If the conversion was successful, a newly allocated
* NUL-terminated string, which must be freed with
* g_free. Otherwise %NULL and @error will be set.
**/
gchar*
g_convert (const gchar *str,
gssize len,
const gchar *to_codeset,
const gchar *from_codeset,
gsize *bytes_read,
gsize *bytes_written,
GError **error)
{
gchar *dest;
gchar *outp;
const gchar *p;
gsize inbytes_remaining;
gsize outbytes_remaining;
gsize err;
GIConv cd;
gsize outbuf_size;
gboolean have_error = FALSE;
g_return_val_if_fail (str != NULL, NULL);
g_return_val_if_fail (to_codeset != NULL, NULL);
g_return_val_if_fail (from_codeset != NULL, NULL);
cd = open_converter (to_codeset, from_codeset, error);
if (cd == (GIConv) -1)
{
if (bytes_read)
*bytes_read = 0;
if (bytes_written)
*bytes_written = 0;
return NULL;
}
if (len < 0)
len = strlen (str);
p = str;
inbytes_remaining = len;
outbuf_size = len + 1; /* + 1 for nul in case len == 1 */
outbytes_remaining = outbuf_size - 1; /* -1 for nul */
outp = dest = g_malloc (outbuf_size);
again:
err = g_iconv (cd, (char **)&p, &inbytes_remaining, &outp, &outbytes_remaining);
if (err == (size_t) -1)
{
switch (errno)
{
case EINVAL:
/* Incomplete text, do not report an error */
break;
case E2BIG:
{
size_t used = outp - dest;
outbuf_size *= 2;
dest = g_realloc (dest, outbuf_size);
outp = dest + used;
outbytes_remaining = outbuf_size - used - 1; /* -1 for nul */
goto again;
}
case EILSEQ:
g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
_("Invalid byte sequence in conversion input"));
have_error = TRUE;
break;
default:
g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
_("Error during conversion: %s"),
strerror (errno));
have_error = TRUE;
break;
}
}
*outp = '\0';
g_iconv_close (cd);
if (bytes_read)
*bytes_read = p - str;
else
{
if ((p - str) != len)
{
if (!have_error)
{
g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT,
_("Partial character sequence at end of input"));
have_error = TRUE;
}
}
}
if (bytes_written)
*bytes_written = outp - dest; /* Doesn't include '\0' */
if (have_error)
{
g_free (dest);
return NULL;
}
else
return dest;
}
/**
* g_convert_with_fallback:
* @str: the string to convert
* @len: the length of the string
* @to_codeset: name of character set into which to convert @str
* @from_codeset: character set of @str.
* @fallback: UTF-8 string to use in place of character not
* present in the target encoding. (This must be
* in the target encoding), if %NULL, characters
* not in the target encoding will be represented
* as Unicode escapes \x{XXXX} or \x{XXXXXX}.
* @bytes_read: location to store the number of bytes in the
* input string that were successfully converted, or %NULL.
* Even if the conversion was succesful, this may be
* less than len if there were partial characters
* at the end of the input.
* @bytes_written: the stored in the output buffer (not including the
* terminating nul.
* @error: location to store the error occuring, or %NULL to ignore
* errors. Any of the errors in #GConvertError may occur.
*
* Convert a string from one character set to another, possibly
* including fallback sequences for characters not representable
* in the output. Note that it is not guaranteed that the specification
* for the fallback sequences in @fallback will be honored. Some
* systems may do a approximate conversion from @from_codeset
* to @to_codeset in their iconv() functions, in which case GLib
* will simply return that approximate conversion.
*
* Return value: If the conversion was successful, a newly allocated
* NUL-terminated string, which must be freed with
* g_free. Otherwise %NULL and @error will be set.
**/
gchar*
g_convert_with_fallback (const gchar *str,
gssize len,
const gchar *to_codeset,
const gchar *from_codeset,
gchar *fallback,
gsize *bytes_read,
gsize *bytes_written,
GError **error)
{
gchar *utf8;
gchar *dest;
gchar *outp;
const gchar *insert_str = NULL;
const gchar *p;
gsize inbytes_remaining;
const gchar *save_p = NULL;
gsize save_inbytes = 0;
gsize outbytes_remaining;
gsize err;
GIConv cd;
gsize outbuf_size;
gboolean have_error = FALSE;
gboolean done = FALSE;
GError *local_error = NULL;
g_return_val_if_fail (str != NULL, NULL);
g_return_val_if_fail (to_codeset != NULL, NULL);
g_return_val_if_fail (from_codeset != NULL, NULL);
if (len < 0)
len = strlen (str);
/* Try an exact conversion; we only proceed if this fails
* due to an illegal sequence in the input string.
*/
dest = g_convert (str, len, to_codeset, from_codeset,
bytes_read, bytes_written, &local_error);
if (!local_error)
return dest;
if (!g_error_matches (local_error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE))
{
g_propagate_error (error, local_error);
return NULL;
}
else
g_error_free (local_error);
local_error = NULL;
/* No go; to proceed, we need a converter from "UTF-8" to
* to_codeset, and the string as UTF-8.
*/
cd = open_converter (to_codeset, "UTF-8", error);
if (cd == (GIConv) -1)
{
if (bytes_read)
*bytes_read = 0;
if (bytes_written)
*bytes_written = 0;
return NULL;
}
utf8 = g_convert (str, len, "UTF-8", from_codeset,
bytes_read, &inbytes_remaining, error);
if (!utf8)
return NULL;
/* Now the heart of the code. We loop through the UTF-8 string, and
* whenever we hit an offending character, we form fallback, convert
* the fallback to the target codeset, and then go back to
* converting the original string after finishing with the fallback.
*
* The variables save_p and save_inbytes store the input state
* for the original string while we are converting the fallback
*/
p = utf8;
outbuf_size = len + 1; /* + 1 for nul in case len == 1 */
outbytes_remaining = outbuf_size - 1; /* -1 for nul */
outp = dest = g_malloc (outbuf_size);
while (!done && !have_error)
{
size_t inbytes_tmp = inbytes_remaining;
err = g_iconv (cd, (char **)&p, &inbytes_tmp, &outp, &outbytes_remaining);
inbytes_remaining = inbytes_tmp;
if (err == (size_t) -1)
{
switch (errno)
{
case EINVAL:
g_assert_not_reached();
break;
case E2BIG:
{
size_t used = outp - dest;
outbuf_size *= 2;
dest = g_realloc (dest, outbuf_size);
outp = dest + used;
outbytes_remaining = outbuf_size - used - 1; /* -1 for nul */
break;
}
case EILSEQ:
if (save_p)
{
/* Error converting fallback string - fatal
*/
g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
_("Cannot convert fallback '%s' to codeset '%s'"),
insert_str, to_codeset);
have_error = TRUE;
break;
}
else
{
if (!fallback)
{
gunichar ch = g_utf8_get_char (p);
insert_str = g_strdup_printf ("\\x{%0*X}",
(ch < 0x10000) ? 4 : 6,
ch);
}
else
insert_str = fallback;
save_p = g_utf8_next_char (p);
save_inbytes = inbytes_remaining - (save_p - p);
p = insert_str;
inbytes_remaining = strlen (p);
}
break;
default:
g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
_("Error during conversion: %s"),
strerror (errno));
have_error = TRUE;
break;
}
}
else
{
if (save_p)
{
if (!fallback)
g_free ((gchar *)insert_str);
p = save_p;
inbytes_remaining = save_inbytes;
save_p = NULL;
}
else
done = TRUE;
}
}
/* Cleanup
*/
*outp = '\0';
g_iconv_close (cd);
if (bytes_written)
*bytes_written = outp - str; /* Doesn't include '\0' */
g_free (utf8);
if (have_error)
{
if (save_p && !fallback)
g_free ((gchar *)insert_str);
g_free (dest);
return NULL;
}
else
return dest;
}
/*
* g_locale_to_utf8
*
*
*/
static gchar *
strdup_len (const gchar *string,
gssize len,
gsize *bytes_written,
gsize *bytes_read)
{
gsize real_len;
if (len < 0)
real_len = strlen (string);
else
{
real_len = 0;
while (real_len < len && string[real_len])
real_len++;
}
if (bytes_read)
*bytes_read = real_len;
if (bytes_written)
*bytes_written = real_len;
return g_strndup (string, real_len);
}
/**
* g_locale_to_utf8:
* @opsysstring: a string in the encoding of the current locale
* @len: the length of the string, or -1 if the string is
* NULL-terminated.
* @bytes_read: location to store the number of bytes in the
* input string that were successfully converted, or %NULL.
* Even if the conversion was succesful, this may be
* less than len if there were partial characters
* at the end of the input. If the error
* G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value
* stored will the byte fofset after the last valid
* input sequence.
* @bytes_written: the stored in the output buffer (not including the
* terminating nul.
* @error: location to store the error occuring, or %NULL to ignore
* errors. Any of the errors in #GConvertError may occur.
*
* Converts a string which is in the encoding used for strings by
* the C runtime (usually the same as that used by the operating
* system) in the current locale into a UTF-8 string.
*
* Return value: The converted string, or %NULL on an error.
**/
gchar *
g_locale_to_utf8 (const gchar *opsysstring,
gssize len,
gsize *bytes_read,
gsize *bytes_written,
GError **error)
{
#ifdef G_PLATFORM_WIN32
gint i, clen, total_len, wclen, first;
wchar_t *wcs, wc;
gchar *result, *bp;
const wchar_t *wcp;
if (len == -1)
len = strlen (opsysstring);
wcs = g_new (wchar_t, len);
wclen = MultiByteToWideChar (CP_ACP, 0, opsysstring, len, wcs, len);
wcp = wcs;
total_len = 0;
for (i = 0; i < wclen; i++)
{
wc = *wcp++;
if (wc < 0x80)
total_len += 1;
else if (wc < 0x800)
total_len += 2;
else if (wc < 0x10000)
total_len += 3;
else if (wc < 0x200000)
total_len += 4;
else if (wc < 0x4000000)
total_len += 5;
else
total_len += 6;
}
result = g_malloc (total_len + 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);
if (bytes_read)
*bytes_read = len;
if (bytes_written)
*bytes_written = total_len;
return result;
#else /* !G_PLATFORM_WIN32 */
const char *charset;
if (g_get_charset (&charset))
return strdup_len (opsysstring, len, bytes_read, bytes_written);
else
return g_convert (opsysstring, len,
"UTF-8", charset, bytes_read, bytes_written, error);
#endif /* !G_PLATFORM_WIN32 */
}
/**
* g_locale_from_utf8:
* @utf8string: a UTF-8 encoded string
* @len: the length of the string, or -1 if the string is
* NULL-terminated.
* @bytes_read: location to store the number of bytes in the
* input string that were successfully converted, or %NULL.
* Even if the conversion was succesful, this may be
* less than len if there were partial characters
* at the end of the input. If the error
* G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value
* stored will the byte fofset after the last valid
* input sequence.
* @bytes_written: the stored in the output buffer (not including the
* terminating nul.
* @error: location to store the error occuring, or %NULL to ignore
* errors. Any of the errors in #GConvertError may occur.
*
* Converts a string from UTF-8 to the encoding used for strings by
* the C runtime (usually the same as that used by the operating
* system) in the current locale.
*
* Return value: The converted string, or %NULL on an error.
**/
gchar *
g_locale_from_utf8 (const gchar *utf8string,
gssize len,
gsize *bytes_read,
gsize *bytes_written,
GError **error)
{
#ifdef G_PLATFORM_WIN32
gint i, mask, clen, mblen;
wchar_t *wcs, *wcp;
gchar *result;
guchar *cp, *end, c;
gint n;
if (len == -1)
len = strlen (utf8string);
/* 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);
if (bytes_read)
*bytes_read = len;
if (bytes_written)
*bytes_written = mblen;
return result;
#else /* !G_PLATFORM_WIN32 */
const gchar *charset;
if (g_get_charset (&charset))
return strdup_len (utf8string, len, bytes_read, bytes_written);
else
return g_convert (utf8string, len,
charset, "UTF-8", bytes_read, bytes_written, error);
#endif /* !G_PLATFORM_WIN32 */
}
/**
* g_filename_to_utf8:
* @opsysstring: a string in the encoding for filenames
* @len: the length of the string, or -1 if the string is
* NULL-terminated.
* @bytes_read: location to store the number of bytes in the
* input string that were successfully converted, or %NULL.
* Even if the conversion was succesful, this may be
* less than len if there were partial characters
* at the end of the input. If the error
* G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value
* stored will the byte fofset after the last valid
* input sequence.
* @bytes_written: the stored in the output buffer (not including the
* terminating nul.
* @error: location to store the error occuring, or %NULL to ignore
* errors. Any of the errors in #GConvertError may occur.
*
* Converts a string which is in the encoding used for filenames
* into a UTF-8 string.
*
* Return value: The converted string, or %NULL on an error.
**/
gchar*
g_filename_to_utf8 (const gchar *opsysstring,
gssize len,
gsize *bytes_read,
gsize *bytes_written,
GError **error)
{
#ifdef G_PLATFORM_WIN32
return g_locale_to_utf8 (opsysstring, len,
bytes_read, bytes_written,
error);
#else /* !G_PLATFORM_WIN32 */
if (getenv ("G_BROKEN_FILENAMES"))
return g_locale_to_utf8 (opsysstring, len,
bytes_read, bytes_written,
error);
else
return strdup_len (opsysstring, len, bytes_read, bytes_written);
#endif /* !G_PLATFORM_WIN32 */
}
/**
* g_filename_from_utf8:
* @utf8string: a UTF-8 encoded string
* @len: the length of the string, or -1 if the string is
* NULL-terminated.
* @bytes_read: location to store the number of bytes in the
* input string that were successfully converted, or %NULL.
* Even if the conversion was succesful, this may be
* less than len if there were partial characters
* at the end of the input. If the error
* G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value
* stored will the byte fofset after the last valid
* input sequence.
* @bytes_written: the stored in the output buffer (not including the
* terminating nul.
* @error: location to store the error occuring, or %NULL to ignore
* errors. Any of the errors in #GConvertError may occur.
*
* Converts a string from UTF-8 to the encoding used for filenames.
*
* Return value: The converted string, or %NULL on an error.
**/
gchar*
g_filename_from_utf8 (const gchar *utf8string,
gssize len,
gsize *bytes_read,
gsize *bytes_written,
GError **error)
{
#ifdef G_PLATFORM_WIN32
return g_locale_from_utf8 (utf8string, len,
bytes_read, bytes_written,
error);
#else /* !G_PLATFORM_WIN32 */
if (getenv ("G_BROKEN_FILENAMES"))
return g_locale_from_utf8 (utf8string, len,
bytes_read, bytes_written,
error);
else
return strdup_len (utf8string, len, bytes_read, bytes_written);
#endif /* !G_PLATFORM_WIN32 */
}

View File

@ -1,106 +0,0 @@
/* 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 Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
#ifndef __G_CONVERT_H__
#define __G_CONVERT_H__
#include <stddef.h> /* For size_t */
#include <gerror.h>
G_BEGIN_DECLS
typedef enum
{
G_CONVERT_ERROR_NO_CONVERSION,
G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
G_CONVERT_ERROR_FAILED,
G_CONVERT_ERROR_PARTIAL_INPUT
} GConvertError;
#define G_CONVERT_ERROR g_convert_error_quark()
GQuark g_convert_error_quark (void);
/* Thin wrappers around iconv
*/
typedef struct _GIConv *GIConv;
GIConv g_iconv_open (const gchar *to_codeset,
const gchar *from_codeset);
size_t g_iconv (GIConv converter,
gchar **inbuf,
gsize *inbytes_left,
gchar **outbuf,
gsize *outbytes_left);
gint g_iconv_close (GIConv converter);
gchar* g_convert (const gchar *str,
gssize len,
const gchar *to_codeset,
const gchar *from_codeset,
gsize *bytes_read,
gsize *bytes_written,
GError **error);
gchar* g_convert_with_fallback (const gchar *str,
gssize len,
const gchar *to_codeset,
const gchar *from_codeset,
gchar *fallback,
gsize *bytes_read,
gsize *bytes_written,
GError **error);
/* Convert between libc's idea of strings and UTF-8.
*/
gchar* g_locale_to_utf8 (const gchar *opsysstring,
gssize len,
gsize *bytes_read,
gsize *bytes_written,
GError **error);
gchar* g_locale_from_utf8 (const gchar *utf8string,
gssize len,
gsize *bytes_read,
gsize *bytes_written,
GError **error);
/* Convert between the operating system (or C runtime)
* representation of file names and UTF-8.
*/
gchar* g_filename_to_utf8 (const gchar *opsysstring,
gssize len,
gsize *bytes_read,
gsize *bytes_written,
GError **error);
gchar* g_filename_from_utf8 (const gchar *utf8string,
gssize len,
gsize *bytes_read,
gsize *bytes_written,
GError **error);
G_END_DECLS
#endif /* __G_CONVERT_H__ */

View File

@ -1,631 +0,0 @@
/* GLIB - Library of useful routines for C programming
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* gdataset.c: Generic dataset mechanism, similar to GtkObject data.
* Copyright (C) 1998 Tim Janik
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
/*
* MT safe ; FIXME: might still freeze, watch out, not thoroughly
* looked at yet.
*/
#include <string.h>
#include "glib.h"
/* --- defines --- */
#define G_QUARK_BLOCK_SIZE (512)
#define G_DATA_MEM_CHUNK_PREALLOC (128)
#define G_DATA_CACHE_MAX (512)
#define G_DATASET_MEM_CHUNK_PREALLOC (32)
/* --- structures --- */
typedef struct _GDataset GDataset;
struct _GData
{
GData *next;
GQuark id;
gpointer data;
GDestroyNotify destroy_func;
};
struct _GDataset
{
gconstpointer location;
GData *datalist;
};
/* --- prototypes --- */
static inline GDataset* g_dataset_lookup (gconstpointer dataset_location);
static inline void g_datalist_clear_i (GData **datalist);
static void g_dataset_destroy_internal (GDataset *dataset);
static inline gpointer g_data_set_internal (GData **datalist,
GQuark key_id,
gpointer data,
GDestroyNotify destroy_func,
GDataset *dataset);
static void g_data_initialize (void);
static inline GQuark g_quark_new (gchar *string);
/* --- variables --- */
G_LOCK_DEFINE_STATIC (g_dataset_global);
static GHashTable *g_dataset_location_ht = NULL;
static GDataset *g_dataset_cached = NULL; /* should this be
threadspecific? */
static GMemChunk *g_dataset_mem_chunk = NULL;
static GMemChunk *g_data_mem_chunk = NULL;
static GData *g_data_cache = NULL;
static guint g_data_cache_length = 0;
G_LOCK_DEFINE_STATIC (g_quark_global);
static GHashTable *g_quark_ht = NULL;
static gchar **g_quarks = NULL;
static GQuark g_quark_seq_id = 0;
/* --- functions --- */
/* HOLDS: g_dataset_global_lock */
static inline void
g_datalist_clear_i (GData **datalist)
{
register GData *list;
/* unlink *all* items before walking their destructors
*/
list = *datalist;
*datalist = NULL;
while (list)
{
register GData *prev;
prev = list;
list = prev->next;
if (prev->destroy_func)
{
G_UNLOCK (g_dataset_global);
prev->destroy_func (prev->data);
G_LOCK (g_dataset_global);
}
if (g_data_cache_length < G_DATA_CACHE_MAX)
{
prev->next = g_data_cache;
g_data_cache = prev;
g_data_cache_length++;
}
else
g_mem_chunk_free (g_data_mem_chunk, prev);
}
}
void
g_datalist_clear (GData **datalist)
{
g_return_if_fail (datalist != NULL);
G_LOCK (g_dataset_global);
if (!g_dataset_location_ht)
g_data_initialize ();
while (*datalist)
g_datalist_clear_i (datalist);
G_UNLOCK (g_dataset_global);
}
/* HOLDS: g_dataset_global_lock */
static inline GDataset*
g_dataset_lookup (gconstpointer dataset_location)
{
register GDataset *dataset;
if (g_dataset_cached && g_dataset_cached->location == dataset_location)
return g_dataset_cached;
dataset = g_hash_table_lookup (g_dataset_location_ht, dataset_location);
if (dataset)
g_dataset_cached = dataset;
return dataset;
}
/* HOLDS: g_dataset_global_lock */
static void
g_dataset_destroy_internal (GDataset *dataset)
{
register gconstpointer dataset_location;
dataset_location = dataset->location;
while (dataset)
{
if (!dataset->datalist)
{
if (dataset == g_dataset_cached)
g_dataset_cached = NULL;
g_hash_table_remove (g_dataset_location_ht, dataset_location);
g_mem_chunk_free (g_dataset_mem_chunk, dataset);
break;
}
g_datalist_clear_i (&dataset->datalist);
dataset = g_dataset_lookup (dataset_location);
}
}
void
g_dataset_destroy (gconstpointer dataset_location)
{
g_return_if_fail (dataset_location != NULL);
G_LOCK (g_dataset_global);
if (g_dataset_location_ht)
{
register GDataset *dataset;
dataset = g_dataset_lookup (dataset_location);
if (dataset)
g_dataset_destroy_internal (dataset);
}
G_UNLOCK (g_dataset_global);
}
/* HOLDS: g_dataset_global_lock */
static inline gpointer
g_data_set_internal (GData **datalist,
GQuark key_id,
gpointer data,
GDestroyNotify destroy_func,
GDataset *dataset)
{
register GData *list;
list = *datalist;
if (!data)
{
register GData *prev;
prev = NULL;
while (list)
{
if (list->id == key_id)
{
gpointer ret_data = NULL;
if (prev)
prev->next = list->next;
else
{
*datalist = list->next;
/* the dataset destruction *must* be done
* prior to invokation of the data destroy function
*/
if (!*datalist && dataset)
g_dataset_destroy_internal (dataset);
}
/* the GData struct *must* already be unlinked
* when invoking the destroy function.
* we use (data==NULL && destroy_func!=NULL) as
* a special hint combination to "steal"
* data without destroy notification
*/
if (list->destroy_func && !destroy_func)
{
G_UNLOCK (g_dataset_global);
list->destroy_func (list->data);
G_LOCK (g_dataset_global);
}
else
ret_data = list->data;
if (g_data_cache_length < G_DATA_CACHE_MAX)
{
list->next = g_data_cache;
g_data_cache = list;
g_data_cache_length++;
}
else
g_mem_chunk_free (g_data_mem_chunk, list);
return ret_data;
}
prev = list;
list = list->next;
}
}
else
{
while (list)
{
if (list->id == key_id)
{
if (!list->destroy_func)
{
list->data = data;
list->destroy_func = destroy_func;
}
else
{
register GDestroyNotify dfunc;
register gpointer ddata;
dfunc = list->destroy_func;
ddata = list->data;
list->data = data;
list->destroy_func = destroy_func;
/* we need to have updated all structures prior to
* invokation of the destroy function
*/
G_UNLOCK (g_dataset_global);
dfunc (ddata);
G_LOCK (g_dataset_global);
}
return NULL;
}
list = list->next;
}
if (g_data_cache)
{
list = g_data_cache;
g_data_cache = list->next;
g_data_cache_length--;
}
else
list = g_chunk_new (GData, g_data_mem_chunk);
list->next = *datalist;
list->id = key_id;
list->data = data;
list->destroy_func = destroy_func;
*datalist = list;
}
return NULL;
}
void
g_dataset_id_set_data_full (gconstpointer dataset_location,
GQuark key_id,
gpointer data,
GDestroyNotify destroy_func)
{
register GDataset *dataset;
g_return_if_fail (dataset_location != NULL);
if (!data)
g_return_if_fail (destroy_func == NULL);
if (!key_id)
{
if (data)
g_return_if_fail (key_id > 0);
else
return;
}
G_LOCK (g_dataset_global);
if (!g_dataset_location_ht)
g_data_initialize ();
dataset = g_dataset_lookup (dataset_location);
if (!dataset)
{
dataset = g_chunk_new (GDataset, g_dataset_mem_chunk);
dataset->location = dataset_location;
g_datalist_init (&dataset->datalist);
g_hash_table_insert (g_dataset_location_ht,
(gpointer) dataset->location,
dataset);
}
g_data_set_internal (&dataset->datalist, key_id, data, destroy_func, dataset);
G_UNLOCK (g_dataset_global);
}
void
g_datalist_id_set_data_full (GData **datalist,
GQuark key_id,
gpointer data,
GDestroyNotify destroy_func)
{
g_return_if_fail (datalist != NULL);
if (!data)
g_return_if_fail (destroy_func == NULL);
if (!key_id)
{
if (data)
g_return_if_fail (key_id > 0);
else
return;
}
G_LOCK (g_dataset_global);
if (!g_dataset_location_ht)
g_data_initialize ();
g_data_set_internal (datalist, key_id, data, destroy_func, NULL);
G_UNLOCK (g_dataset_global);
}
gpointer
g_dataset_id_remove_no_notify (gconstpointer dataset_location,
GQuark key_id)
{
gpointer ret_data = NULL;
g_return_val_if_fail (dataset_location != NULL, NULL);
G_LOCK (g_dataset_global);
if (key_id && g_dataset_location_ht)
{
GDataset *dataset;
dataset = g_dataset_lookup (dataset_location);
if (dataset)
ret_data = g_data_set_internal (&dataset->datalist, key_id, NULL, (GDestroyNotify) 42, dataset);
}
G_UNLOCK (g_dataset_global);
return ret_data;
}
gpointer
g_datalist_id_remove_no_notify (GData **datalist,
GQuark key_id)
{
gpointer ret_data = NULL;
g_return_val_if_fail (datalist != NULL, NULL);
G_LOCK (g_dataset_global);
if (key_id && g_dataset_location_ht)
ret_data = g_data_set_internal (datalist, key_id, NULL, (GDestroyNotify) 42, NULL);
G_UNLOCK (g_dataset_global);
return ret_data;
}
gpointer
g_dataset_id_get_data (gconstpointer dataset_location,
GQuark key_id)
{
g_return_val_if_fail (dataset_location != NULL, NULL);
G_LOCK (g_dataset_global);
if (key_id && g_dataset_location_ht)
{
register GDataset *dataset;
dataset = g_dataset_lookup (dataset_location);
if (dataset)
{
register GData *list;
for (list = dataset->datalist; list; list = list->next)
if (list->id == key_id)
{
G_UNLOCK (g_dataset_global);
return list->data;
}
}
}
G_UNLOCK (g_dataset_global);
return NULL;
}
gpointer
g_datalist_id_get_data (GData **datalist,
GQuark key_id)
{
g_return_val_if_fail (datalist != NULL, NULL);
if (key_id)
{
register GData *list;
for (list = *datalist; list; list = list->next)
if (list->id == key_id)
return list->data;
}
return NULL;
}
void
g_dataset_foreach (gconstpointer dataset_location,
GDataForeachFunc func,
gpointer user_data)
{
register GDataset *dataset;
g_return_if_fail (dataset_location != NULL);
g_return_if_fail (func != NULL);
G_LOCK (g_dataset_global);
if (g_dataset_location_ht)
{
dataset = g_dataset_lookup (dataset_location);
G_UNLOCK (g_dataset_global);
if (dataset)
{
register GData *list, *next;
for (list = dataset->datalist; list; list = next)
{
next = list->next;
func (list->id, list->data, user_data);
}
}
}
else
{
G_UNLOCK (g_dataset_global);
}
}
void
g_datalist_foreach (GData **datalist,
GDataForeachFunc func,
gpointer user_data)
{
register GData *list, *next;
g_return_if_fail (datalist != NULL);
g_return_if_fail (func != NULL);
for (list = *datalist; list; list = next)
{
next = list->next;
func (list->id, list->data, user_data);
}
}
void
g_datalist_init (GData **datalist)
{
g_return_if_fail (datalist != NULL);
*datalist = NULL;
}
/* HOLDS: g_dataset_global_lock */
static void
g_data_initialize (void)
{
g_return_if_fail (g_dataset_location_ht == NULL);
g_dataset_location_ht = g_hash_table_new (g_direct_hash, NULL);
g_dataset_cached = NULL;
g_dataset_mem_chunk =
g_mem_chunk_new ("GDataset MemChunk",
sizeof (GDataset),
sizeof (GDataset) * G_DATASET_MEM_CHUNK_PREALLOC,
G_ALLOC_AND_FREE);
g_data_mem_chunk =
g_mem_chunk_new ("GData MemChunk",
sizeof (GData),
sizeof (GData) * G_DATA_MEM_CHUNK_PREALLOC,
G_ALLOC_AND_FREE);
}
GQuark
g_quark_try_string (const gchar *string)
{
GQuark quark = 0;
g_return_val_if_fail (string != NULL, 0);
G_LOCK (g_quark_global);
if (g_quark_ht)
quark = GPOINTER_TO_UINT (g_hash_table_lookup (g_quark_ht, string));
G_UNLOCK (g_quark_global);
return quark;
}
GQuark
g_quark_from_string (const gchar *string)
{
GQuark quark;
g_return_val_if_fail (string != NULL, 0);
G_LOCK (g_quark_global);
if (g_quark_ht)
quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
else
{
g_quark_ht = g_hash_table_new (g_str_hash, g_str_equal);
quark = 0;
}
if (!quark)
quark = g_quark_new (g_strdup (string));
G_UNLOCK (g_quark_global);
return quark;
}
GQuark
g_quark_from_static_string (const gchar *string)
{
GQuark quark;
g_return_val_if_fail (string != NULL, 0);
G_LOCK (g_quark_global);
if (g_quark_ht)
quark = (gulong) g_hash_table_lookup (g_quark_ht, string);
else
{
g_quark_ht = g_hash_table_new (g_str_hash, g_str_equal);
quark = 0;
}
if (!quark)
quark = g_quark_new ((gchar*) string);
G_UNLOCK (g_quark_global);
return quark;
}
G_CONST_RETURN gchar*
g_quark_to_string (GQuark quark)
{
gchar* result = NULL;
G_LOCK (g_quark_global);
if (quark > 0 && quark <= g_quark_seq_id)
result = g_quarks[quark - 1];
G_UNLOCK (g_quark_global);
return result;
}
/* HOLDS: g_quark_global_lock */
static inline GQuark
g_quark_new (gchar *string)
{
GQuark quark;
if (g_quark_seq_id % G_QUARK_BLOCK_SIZE == 0)
g_quarks = g_renew (gchar*, g_quarks, g_quark_seq_id + G_QUARK_BLOCK_SIZE);
g_quarks[g_quark_seq_id] = string;
g_quark_seq_id++;
quark = g_quark_seq_id;
g_hash_table_insert (g_quark_ht, string, GUINT_TO_POINTER (quark));
return quark;
}

View File

@ -1,106 +0,0 @@
/* 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 Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
#ifndef __G_DATASET_H__
#define __G_DATASET_H__
#include <gquark.h>
G_BEGIN_DECLS
typedef struct _GData GData;
typedef void (*GDataForeachFunc) (GQuark key_id,
gpointer data,
gpointer user_data);
/* Keyed Data List
*/
void g_datalist_init (GData **datalist);
void g_datalist_clear (GData **datalist);
gpointer g_datalist_id_get_data (GData **datalist,
GQuark key_id);
void g_datalist_id_set_data_full (GData **datalist,
GQuark key_id,
gpointer data,
GDestroyNotify destroy_func);
gpointer g_datalist_id_remove_no_notify (GData **datalist,
GQuark key_id);
void g_datalist_foreach (GData **datalist,
GDataForeachFunc func,
gpointer user_data);
#define g_datalist_id_set_data(dl, q, d) \
g_datalist_id_set_data_full ((dl), (q), (d), NULL)
#define g_datalist_id_remove_data(dl, q) \
g_datalist_id_set_data ((dl), (q), NULL)
#define g_datalist_get_data(dl, k) \
(g_datalist_id_get_data ((dl), g_quark_try_string (k)))
#define g_datalist_set_data_full(dl, k, d, f) \
g_datalist_id_set_data_full ((dl), g_quark_from_string (k), (d), (f))
#define g_datalist_remove_no_notify(dl, k) \
g_datalist_id_remove_no_notify ((dl), g_quark_try_string (k))
#define g_datalist_set_data(dl, k, d) \
g_datalist_set_data_full ((dl), (k), (d), NULL)
#define g_datalist_remove_data(dl, k) \
g_datalist_id_set_data ((dl), g_quark_try_string (k), NULL)
/* Location Associated Keyed Data
*/
void g_dataset_destroy (gconstpointer dataset_location);
gpointer g_dataset_id_get_data (gconstpointer dataset_location,
GQuark key_id);
void g_dataset_id_set_data_full (gconstpointer dataset_location,
GQuark key_id,
gpointer data,
GDestroyNotify destroy_func);
gpointer g_dataset_id_remove_no_notify (gconstpointer dataset_location,
GQuark key_id);
void g_dataset_foreach (gconstpointer dataset_location,
GDataForeachFunc func,
gpointer user_data);
#define g_dataset_id_set_data(l, k, d) \
g_dataset_id_set_data_full ((l), (k), (d), NULL)
#define g_dataset_id_remove_data(l, k) \
g_dataset_id_set_data ((l), (k), NULL)
#define g_dataset_get_data(l, k) \
(g_dataset_id_get_data ((l), g_quark_try_string (k)))
#define g_dataset_set_data_full(l, k, d, f) \
g_dataset_id_set_data_full ((l), g_quark_from_string (k), (d), (f))
#define g_dataset_remove_no_notify(l, k) \
g_dataset_id_remove_no_notify ((l), g_quark_try_string (k))
#define g_dataset_set_data(l, k, d) \
g_dataset_set_data_full ((l), (k), (d), NULL)
#define g_dataset_remove_data(l, k) \
g_dataset_id_set_data ((l), g_quark_try_string (k), NULL)
G_END_DECLS
#endif /* __G_DATASET_H__ */

1353
gdate.c

File diff suppressed because it is too large Load Diff

252
gdate.h
View File

@ -1,252 +0,0 @@
/* 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 Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
#ifndef __G_DATE_H__
#define __G_DATE_H__
#include <gquark.h>
G_BEGIN_DECLS
/* GDate
*
* Date calculations (not time for now, to be resolved). These are a
* mutant combination of Steffen Beyer's DateCalc routines
* (http://www.perl.com/CPAN/authors/id/STBEY/) and Jon Trowbridge's
* date routines (written for in-house software). Written by Havoc
* Pennington <hp@pobox.com>
*/
typedef gint32 GTime;
typedef guint16 GDateYear;
typedef guint8 GDateDay; /* day of the month */
typedef struct _GDate GDate;
/* make struct tm known without having to include time.h */
struct tm;
/* enum used to specify order of appearance in parsed date strings */
typedef enum
{
G_DATE_DAY = 0,
G_DATE_MONTH = 1,
G_DATE_YEAR = 2
} GDateDMY;
/* actual week and month values */
typedef enum
{
G_DATE_BAD_WEEKDAY = 0,
G_DATE_MONDAY = 1,
G_DATE_TUESDAY = 2,
G_DATE_WEDNESDAY = 3,
G_DATE_THURSDAY = 4,
G_DATE_FRIDAY = 5,
G_DATE_SATURDAY = 6,
G_DATE_SUNDAY = 7
} GDateWeekday;
typedef enum
{
G_DATE_BAD_MONTH = 0,
G_DATE_JANUARY = 1,
G_DATE_FEBRUARY = 2,
G_DATE_MARCH = 3,
G_DATE_APRIL = 4,
G_DATE_MAY = 5,
G_DATE_JUNE = 6,
G_DATE_JULY = 7,
G_DATE_AUGUST = 8,
G_DATE_SEPTEMBER = 9,
G_DATE_OCTOBER = 10,
G_DATE_NOVEMBER = 11,
G_DATE_DECEMBER = 12
} GDateMonth;
#define G_DATE_BAD_JULIAN 0U
#define G_DATE_BAD_DAY 0U
#define G_DATE_BAD_YEAR 0U
/* Note: directly manipulating structs is generally a bad idea, but
* in this case it's an *incredibly* bad idea, because all or part
* of this struct can be invalid at any given time. Use the functions,
* or you will get hosed, I promise.
*/
struct _GDate
{
guint julian_days : 32; /* julian days representation - we use a
* bitfield hoping that 64 bit platforms
* will pack this whole struct in one big
* int
*/
guint julian : 1; /* julian is valid */
guint dmy : 1; /* dmy is valid */
/* DMY representation */
guint day : 6;
guint month : 4;
guint year : 16;
};
/* g_date_new() returns an invalid date, you then have to _set() stuff
* to get a usable object. You can also allocate a GDate statically,
* then call g_date_clear() to initialize.
*/
GDate* g_date_new (void);
GDate* g_date_new_dmy (GDateDay day,
GDateMonth month,
GDateYear year);
GDate* g_date_new_julian (guint32 julian_day);
void g_date_free (GDate *date);
/* check g_date_valid() after doing an operation that might fail, like
* _parse. Almost all g_date operations are undefined on invalid
* dates (the exceptions are the mutators, since you need those to
* return to validity).
*/
gboolean g_date_valid (const GDate *date);
gboolean g_date_valid_day (GDateDay day) G_GNUC_CONST;
gboolean g_date_valid_month (GDateMonth month) G_GNUC_CONST;
gboolean g_date_valid_year (GDateYear year) G_GNUC_CONST;
gboolean g_date_valid_weekday (GDateWeekday weekday) G_GNUC_CONST;
gboolean g_date_valid_julian (guint32 julian_date) G_GNUC_CONST;
gboolean g_date_valid_dmy (GDateDay day,
GDateMonth month,
GDateYear year) G_GNUC_CONST;
GDateWeekday g_date_get_weekday (const GDate *date);
GDateMonth g_date_get_month (const GDate *date);
GDateYear g_date_get_year (const GDate *date);
GDateDay g_date_get_day (const GDate *date);
guint32 g_date_get_julian (const GDate *date);
guint g_date_get_day_of_year (const GDate *date);
/* First monday/sunday is the start of week 1; if we haven't reached
* that day, return 0. These are not ISO weeks of the year; that
* routine needs to be added.
* these functions return the number of weeks, starting on the
* corrsponding day
*/
guint g_date_get_monday_week_of_year (const GDate *date);
guint g_date_get_sunday_week_of_year (const GDate *date);
/* If you create a static date struct you need to clear it to get it
* in a sane state before use. You can clear a whole array at
* once with the ndates argument.
*/
void g_date_clear (GDate *date,
guint n_dates);
/* The parse routine is meant for dates typed in by a user, so it
* permits many formats but tries to catch common typos. If your data
* needs to be strictly validated, it is not an appropriate function.
*/
void g_date_set_parse (GDate *date,
const gchar *str);
void g_date_set_time (GDate *date,
GTime time);
void g_date_set_month (GDate *date,
GDateMonth month);
void g_date_set_day (GDate *date,
GDateDay day);
void g_date_set_year (GDate *date,
GDateYear year);
void g_date_set_dmy (GDate *date,
GDateDay day,
GDateMonth month,
GDateYear y);
void g_date_set_julian (GDate *date,
guint32 julian_date);
gboolean g_date_is_first_of_month (const GDate *date);
gboolean g_date_is_last_of_month (const GDate *date);
/* To go forward by some number of weeks just go forward weeks*7 days */
void g_date_add_days (GDate *date,
guint n_days);
void g_date_subtract_days (GDate *date,
guint n_days);
/* If you add/sub months while day > 28, the day might change */
void g_date_add_months (GDate *date,
guint n_months);
void g_date_subtract_months (GDate *date,
guint n_months);
/* If it's feb 29, changing years can move you to the 28th */
void g_date_add_years (GDate *date,
guint n_years);
void g_date_subtract_years (GDate *date,
guint n_years);
gboolean g_date_is_leap_year (GDateYear year) G_GNUC_CONST;
guint8 g_date_get_days_in_month (GDateMonth month,
GDateYear year) G_GNUC_CONST;
guint8 g_date_get_monday_weeks_in_year (GDateYear year) G_GNUC_CONST;
guint8 g_date_get_sunday_weeks_in_year (GDateYear year) G_GNUC_CONST;
/* Returns the number of days between the two dates. If date2 comes
before date1, a negative value is return. */
gint g_date_days_between (const GDate *date1,
const GDate *date2);
/* qsort-friendly (with a cast...) */
gint g_date_compare (const GDate *lhs,
const GDate *rhs);
void g_date_to_struct_tm (const GDate *date,
struct tm *tm);
void g_date_clamp (GDate *date,
const GDate *min_date,
const GDate *max_date);
/* Swap date1 and date2's values if date1 > date2. */
void g_date_order (GDate *date1, GDate *date2);
/* Just like strftime() except you can only use date-related formats.
* Using a time format is undefined.
*/
gsize g_date_strftime (gchar *s,
gsize slen,
const gchar *format,
const GDate *date);
#ifndef G_DISABLE_DEPRECATED
#define g_date_weekday g_date_get_weekday
#define g_date_month g_date_get_month
#define g_date_year g_date_get_year
#define g_date_day g_date_get_day
#define g_date_julian g_date_get_julian
#define g_date_day_of_year g_date_get_day_of_year
#define g_date_monday_week_of_year g_date_get_monday_week_of_year
#define g_date_sunday_week_of_year g_date_get_sunday_week_of_year
#define g_date_days_in_month g_date_get_days_in_month
#define g_date_monday_weeks_in_year g_date_get_monday_weeks_in_year
#define g_date_sunday_weeks_in_year g_date_get_sunday_weeks_in_year
#endif /* G_DISABLE_DEPRECATED */
G_END_DECLS
#endif /* __G_DATE_H__ */

View File

@ -1,609 +0,0 @@
#! /usr/bin/perl -w
# Copyright (C) 1998, 1999 Tom Tromey
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program 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 General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# gen-unicode-tables.pl - Generate tables for libunicode from Unicode data.
# See http://www.unicode.org/Public/UNIDATA/UnicodeCharacterDatabase.html
# Usage: gen-unicode-tables.pl [-decomp | -both] UNICODE-VERSION UnicodeData.txt LineBreak.txt
# I consider the output of this program to be unrestricted. Use it as
# you will.
# FIXME:
# * We could save even more space in the generated table by using
# indexes and not pointers.
# * For decomp table it might make sense to use a shift count other
# than 8. We could easily compute the perfect shift count.
use vars qw($CODE $NAME $CATEGORY $COMBINING_CLASSES $BIDI_CATEGORY $DECOMPOSITION $DECIMAL_VALUE $DIGIT_VALUE $NUMERIC_VALUE $MIRRORED $OLD_NAME $COMMENT $UPPER $LOWER $TITLE $BREAK_CODE $BREAK_CATEGORY $BREAK_NAME);
# Names of fields in Unicode data table.
$CODE = 0;
$NAME = 1;
$CATEGORY = 2;
$COMBINING_CLASSES = 3;
$BIDI_CATEGORY = 4;
$DECOMPOSITION = 5;
$DECIMAL_VALUE = 6;
$DIGIT_VALUE = 7;
$NUMERIC_VALUE = 8;
$MIRRORED = 9;
$OLD_NAME = 10;
$COMMENT = 11;
$UPPER = 12;
$LOWER = 13;
$TITLE = 14;
# Names of fields in the line break table
$BREAK_CODE = 0;
$BREAK_PROPERTY = 1;
$BREAK_NAME = 2;
# Map general category code onto symbolic name.
%mappings =
(
# Normative.
'Lu' => "G_UNICODE_UPPERCASE_LETTER",
'Ll' => "G_UNICODE_LOWERCASE_LETTER",
'Lt' => "G_UNICODE_TITLECASE_LETTER",
'Mn' => "G_UNICODE_NON_SPACING_MARK",
'Mc' => "G_UNICODE_COMBINING_MARK",
'Me' => "G_UNICODE_ENCLOSING_MARK",
'Nd' => "G_UNICODE_DECIMAL_NUMBER",
'Nl' => "G_UNICODE_LETTER_NUMBER",
'No' => "G_UNICODE_OTHER_NUMBER",
'Zs' => "G_UNICODE_SPACE_SEPARATOR",
'Zl' => "G_UNICODE_LINE_SEPARATOR",
'Zp' => "G_UNICODE_PARAGRAPH_SEPARATOR",
'Cc' => "G_UNICODE_CONTROL",
'Cf' => "G_UNICODE_FORMAT",
'Cs' => "G_UNICODE_SURROGATE",
'Co' => "G_UNICODE_PRIVATE_USE",
'Cn' => "G_UNICODE_UNASSIGNED",
# Informative.
'Lm' => "G_UNICODE_MODIFIER_LETTER",
'Lo' => "G_UNICODE_OTHER_LETTER",
'Pc' => "G_UNICODE_CONNECT_PUNCTUATION",
'Pd' => "G_UNICODE_DASH_PUNCTUATION",
'Ps' => "G_UNICODE_OPEN_PUNCTUATION",
'Pe' => "G_UNICODE_CLOSE_PUNCTUATION",
'Pi' => "G_UNICODE_INITIAL_PUNCTUATION",
'Pf' => "G_UNICODE_FINAL_PUNCTUATION",
'Po' => "G_UNICODE_OTHER_PUNCTUATION",
'Sm' => "G_UNICODE_MATH_SYMBOL",
'Sc' => "G_UNICODE_CURRENCY_SYMBOL",
'Sk' => "G_UNICODE_MODIFIER_SYMBOL",
'So' => "G_UNICODE_OTHER_SYMBOL"
);
%break_mappings =
(
'BK' => "G_UNICODE_BREAK_MANDATORY",
'CR' => "G_UNICODE_BREAK_CARRIAGE_RETURN",
'LF' => "G_UNICODE_BREAK_LINE_FEED",
'CM' => "G_UNICODE_BREAK_COMBINING_MARK",
'SG' => "G_UNICODE_BREAK_SURROGATE",
'ZW' => "G_UNICODE_BREAK_ZERO_WIDTH_SPACE",
'IN' => "G_UNICODE_BREAK_INSEPARABLE",
'GL' => "G_UNICODE_BREAK_NON_BREAKING_GLUE",
'CB' => "G_UNICODE_BREAK_CONTINGENT",
'SP' => "G_UNICODE_BREAK_SPACE",
'BA' => "G_UNICODE_BREAK_AFTER",
'BB' => "G_UNICODE_BREAK_BEFORE",
'B2' => "G_UNICODE_BREAK_BEFORE_AND_AFTER",
'HY' => "G_UNICODE_BREAK_HYPHEN",
'NS' => "G_UNICODE_BREAK_NON_STARTER",
'OP' => "G_UNICODE_BREAK_OPEN_PUNCTUATION",
'CL' => "G_UNICODE_BREAK_CLOSE_PUNCTUATION",
'QU' => "G_UNICODE_BREAK_QUOTATION",
'EX' => "G_UNICODE_BREAK_EXCLAMATION",
'ID' => "G_UNICODE_BREAK_IDEOGRAPHIC",
'NU' => "G_UNICODE_BREAK_NUMERIC",
'IS' => "G_UNICODE_BREAK_INFIX_SEPARATOR",
'SY' => "G_UNICODE_BREAK_SYMBOL",
'AL' => "G_UNICODE_BREAK_ALPHABETIC",
'PR' => "G_UNICODE_BREAK_PREFIX",
'PO' => "G_UNICODE_BREAK_POSTFIX",
'SA' => "G_UNICODE_BREAK_COMPLEX_CONTEXT",
'AI' => "G_UNICODE_BREAK_AMBIGUOUS",
'XX' => "G_UNICODE_BREAK_UNKNOWN"
);
# Title case mappings.
%title_to_lower = ();
%title_to_upper = ();
$do_decomp = 0;
$do_props = 1;
if ($ARGV[0] eq '-decomp')
{
$do_decomp = 1;
$do_props = 0;
shift @ARGV;
}
elsif ($ARGV[0] eq '-both')
{
$do_decomp = 1;
shift @ARGV;
}
print "Creating decomp table\n" if ($do_decomp);
print "Creating property table\n" if ($do_props);
print "Unicode data from $ARGV[1]\n";
open (INPUT, "< $ARGV[1]") || exit 1;
$last_code = -1;
while (<INPUT>)
{
chop;
@fields = split (';', $_, 30);
if ($#fields != 14)
{
printf STDERR ("Entry for $fields[$CODE] has wrong number of fields (%d)\n", $#fields);
}
$code = hex ($fields[$CODE]);
last if ($code > 0xFFFF); # ignore characters out of the basic plane
if ($code > $last_code + 1)
{
# Found a gap.
if ($fields[$NAME] =~ /Last>/)
{
# Fill the gap with the last character read,
# since this was a range specified in the char database
@gfields = @fields;
}
else
{
# The gap represents undefined characters. Only the type
# matters.
@gfields = ('', '', 'Cn', '0', '', '', '', '', '', '', '',
'', '', '', '');
}
for (++$last_code; $last_code < $code; ++$last_code)
{
$gfields{$CODE} = sprintf ("%04x", $last_code);
&process_one ($last_code, @gfields);
}
}
&process_one ($code, @fields);
$last_code = $code;
}
@gfields = ('', '', 'Cn', '0', '', '', '', '', '', '', '',
'', '', '', '');
for (++$last_code; $last_code < 0x10000; ++$last_code)
{
$gfields{$CODE} = sprintf ("%04x", $last_code);
&process_one ($last_code, @gfields);
}
--$last_code; # Want last to be 0xFFFF.
print "Creating line break table\n";
print "Line break data from $ARGV[2]\n";
open (INPUT, "< $ARGV[2]") || exit 1;
$last_code = -1;
while (<INPUT>)
{
chop;
next if /^#/;
@fields = split (';', $_, 30);
if ($#fields != 2)
{
printf STDERR ("Entry for $fields[$CODE] has wrong number of fields (%d)\n", $#fields);
}
$code = hex ($fields[$CODE]);
last if ($code > 0xFFFF); # ignore characters out of the basic plane
if ($code > $last_code + 1)
{
# Found a gap.
if ($fields[$NAME] =~ /Last>/)
{
# Fill the gap with the last character read,
# since this was a range specified in the char database
$gap_break_prop = $fields[$BREAK_PROPERTY];
for (++$last_code; $last_code < $code; ++$last_code)
{
$break_props[$last_code] = $gap_break_prop;
}
}
else
{
# The gap represents undefined characters. If assigned,
# they are AL, if not assigned, XX
for (++$last_code; $last_code < $code; ++$last_code)
{
if ($type[$last_code] eq 'Cn')
{
$break_props[$last_code] = 'XX';
}
else
{
$break_props[$last_code] = 'AL';
}
}
}
}
$break_props[$code] = $fields[$BREAK_PROPERTY];
$last_code = $code;
}
for (++$last_code; $last_code < 0x10000; ++$last_code)
{
if ($type[$last_code] eq 'Cn')
{
$break_props[$last_code] = 'XX';
}
else
{
$break_props[$last_code] = 'AL';
}
}
--$last_code; # Want last to be 0xFFFF.
print STDERR "Last code is not 0xFFFF" if ($last_code != 0xFFFF);
&print_tables ($last_code)
if $do_props;
&print_decomp ($last_code)
if $do_decomp;
&print_line_break ($last_code);
exit 0;
# Process a single character.
sub process_one
{
my ($code, @fields) = @_;
$type[$code] = $fields[$CATEGORY];
if ($type[$code] eq 'Nd')
{
$value[$code] = int ($fields[$DECIMAL_VALUE]);
}
elsif ($type[$code] eq 'Ll')
{
$value[$code] = hex ($fields[$UPPER]);
}
elsif ($type[$code] eq 'Lu')
{
$value[$code] = hex ($fields[$LOWER]);
}
if ($type[$code] eq 'Lt')
{
$title_to_lower{$code} = hex ($fields[$LOWER]);
$title_to_upper{$code} = hex ($fields[$UPPER]);
}
$cclass[$code] = $fields[$COMBINING_CLASSES];
# Handle decompositions.
if ($fields[$DECOMPOSITION] ne ''
&& $fields[$DECOMPOSITION] !~ /\<.*\>/)
{
$decompositions[$code] = $fields[$DECOMPOSITION];
}
}
sub print_tables
{
my ($last) = @_;
my ($outfile) = "gunichartables.h";
local ($bytes_out) = 0;
print "Writing $outfile...\n";
open (OUT, "> $outfile");
print OUT "/* This file is automatically generated. DO NOT EDIT!\n";
print OUT " Instead, edit gen-unicode-tables.pl and re-run. */\n\n";
print OUT "#ifndef CHARTABLES_H\n";
print OUT "#define CHARTABLES_H\n\n";
print OUT "#define G_UNICODE_DATA_VERSION \"$ARGV[0]\"\n\n";
printf OUT "#define G_UNICODE_LAST_CHAR 0x%04x\n\n", $last;
for ($count = 0; $count <= $last; $count += 256)
{
$row[$count / 256] = &print_row ($count, '(char *) ', 'char', 1,
'page', \&fetch_type);
}
print OUT "static char *type_table[256] = {\n";
for ($count = 0; $count <= $last; $count += 256)
{
print OUT ",\n" if $count > 0;
print OUT " ", $row[$count / 256];
$bytes_out += 4;
}
print OUT "\n};\n\n";
#
# Now print attribute table.
#
for ($count = 0; $count <= $last; $count += 256)
{
$row[$count / 256] = &print_row ($count, '', 'unsigned short', 2,
'attrpage', \&fetch_attr);
}
print OUT "static unsigned short *attr_table[256] = {\n";
for ($count = 0; $count <= $last; $count += 256)
{
print OUT ",\n" if $count > 0;
print OUT " ", $row[$count / 256];
$bytes_out += 4;
}
print OUT "\n};\n\n";
# FIXME: type.
print OUT "static unsigned short title_table[][3] = {\n";
my ($item);
my ($first) = 1;
foreach $item (sort keys %title_to_lower)
{
print OUT ",\n"
unless $first;
$first = 0;
printf OUT " { 0x%04x, 0x%04x, 0x%04x }", $item, $title_to_upper{$item}, $title_to_lower{$item};
$bytes_out += 6;
}
print OUT "\n};\n\n";
print OUT "#endif /* CHARTABLES_H */\n";
close (OUT);
printf STDERR "Generated %d bytes in tables\n", $bytes_out;
}
# A fetch function for the type table.
sub fetch_type
{
my ($index) = @_;
return $mappings{$type[$index]};
}
# A fetch function for the attribute table.
sub fetch_attr
{
my ($index) = @_;
if (defined $value[$index])
{
return sprintf ("0x%04x", $value[$index]);
}
else
{
return "0x0000";
}
}
# Print a single "row" of a two-level table.
sub print_row
{
my ($start, $def_pfx, $typname, $typsize, $name, $fetcher) = @_;
my ($i);
my (@values);
my ($flag) = 1;
my ($off);
for ($off = 0; $off < 256; ++$off)
{
$values[$off] = $fetcher->($off + $start);
if ($values[$off] ne $values[0])
{
$flag = 0;
}
}
if ($flag)
{
return $def_pfx . $values[0];
}
printf OUT "static %s %s%d[256] = {\n ", $typname, $name, $start / 256;
my ($column) = 2;
for ($i = $start; $i < $start + 256; ++$i)
{
print OUT ", "
if $i > $start;
my ($text) = $values[$i - $start];
if (length ($text) + $column + 2 > 78)
{
print OUT "\n ";
$column = 2;
}
print OUT $text;
$column += length ($text) + 2;
}
print OUT "\n};\n\n";
$bytes_out += 256 * $typsize;
return sprintf "%s%d", $name, $start / 256;
}
# Generate the character decomposition header.
sub print_decomp
{
my ($last) = @_;
my ($outfile) = "gunidecomp.h";
local ($bytes_out) = 0;
print "Writing $outfile...\n";
open (OUT, "> $outfile") || exit 1;
print OUT "/* This file is automatically generated. DO NOT EDIT! */\n\n";
print OUT "#ifndef DECOMP_H\n";
print OUT "#define DECOMP_H\n\n";
printf OUT "#define G_UNICODE_LAST_CHAR 0x%04x\n\n", $last;
my ($count, @row);
for ($count = 0; $count <= $last; $count += 256)
{
$row[$count / 256] = &print_row ($count, '(unsigned char *) ',
'unsigned char', 1, 'cclass',
\&fetch_cclass);
}
print OUT "static unsigned char *combining_class_table[256] = {\n";
for ($count = 0; $count <= $last; $count += 256)
{
print OUT ",\n" if $count > 0;
print OUT " ", $row[$count / 256];
$bytes_out += 4;
}
print OUT "\n};\n\n";
print OUT "typedef struct\n{\n";
# FIXME: type.
print OUT " unsigned short ch;\n";
print OUT " unsigned char *expansion;\n";
print OUT "} decomposition;\n\n";
print OUT "static decomposition decomp_table[] =\n{\n";
my ($iter);
my ($first) = 1;
for ($count = 0; $count <= $last; ++$count)
{
if (defined $decompositions[$count])
{
print OUT ",\n"
if ! $first;
$first = 0;
printf OUT " { 0x%04x, \"", $count;
$bytes_out += 2;
foreach $iter (&expand_decomp ($count))
{
printf OUT "\\x%02x\\x%02x", $iter / 256, $iter & 0xff;
$bytes_out += 2;
}
# Only a single terminator because one is implied in the string.
print OUT "\\0\" }";
$bytes_out += 2;
}
}
print OUT "\n};\n\n";
print OUT "#endif /* DECOMP_H */\n";
printf STDERR "Generated %d bytes in decomp tables\n", $bytes_out;
}
sub print_line_break
{
my ($last) = @_;
my ($outfile) = "gunibreak.h";
local ($bytes_out) = 0;
print "Writing $outfile...\n";
open (OUT, "> $outfile");
print OUT "/* This file is automatically generated. DO NOT EDIT!\n";
print OUT " Instead, edit gen-unicode-tables.pl and re-run. */\n\n";
print OUT "#ifndef BREAKTABLES_H\n";
print OUT "#define BREAKTABLES_H\n\n";
print OUT "#define G_UNICODE_DATA_VERSION \"$ARGV[0]\"\n\n";
printf OUT "#define G_UNICODE_LAST_CHAR 0x%04x\n\n", $last;
for ($count = 0; $count <= $last; $count += 256)
{
$row[$count / 256] = &print_row ($count, '(char *) ', 'char', 1,
'page',
\&fetch_break_type);
}
print OUT "static char *break_property_table[256] = {\n";
for ($count = 0; $count <= $last; $count += 256)
{
print OUT ",\n" if $count > 0;
print OUT " ", $row[$count / 256];
$bytes_out += 4;
}
print OUT "\n};\n\n";
print OUT "#endif /* BREAKTABLES_H */\n";
close (OUT);
printf STDERR "Generated %d bytes in break tables\n", $bytes_out;
}
# A fetch function for the break properties table.
sub fetch_break_type
{
my ($index) = @_;
return $break_mappings{$break_props[$index]};
}
# Fetcher for combining class.
sub fetch_cclass
{
my ($i) = @_;
return $cclass[$i];
}
# Expand a character decomposition recursively.
sub expand_decomp
{
my ($code) = @_;
my ($iter, $val);
my (@result) = ();
foreach $iter (split (' ', $decompositions[$code]))
{
$val = hex ($iter);
if (defined $decompositions[$val])
{
push (@result, &expand_decomp ($val));
}
else
{
push (@result, $val);
}
}
return @result;
}

254
gerror.c
View File

@ -1,254 +0,0 @@
/* 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 Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
#include "glib.h"
static GError*
g_error_new_valist(GQuark domain,
gint code,
const gchar *format,
va_list args)
{
GError *error;
error = g_new (GError, 1);
error->domain = domain;
error->code = code;
error->message = g_strdup_vprintf (format, args);
return error;
}
/**
* g_error_new:
* @domain: error domain
* @code: error code
* @format: printf()-style format for error message
* @Varargs: parameters for message format
*
* Creates a new #GError with the given @domain and @code,
* and a message formatted with @format.
*
* Return value: a new #GError
**/
GError*
g_error_new (GQuark domain,
gint code,
const gchar *format,
...)
{
GError* error;
va_list args;
g_return_val_if_fail (format != NULL, NULL);
g_return_val_if_fail (domain != 0, NULL);
va_start (args, format);
error = g_error_new_valist (domain, code, format, args);
va_end (args);
return error;
}
/**
* g_error_new_literal:
* @domain: error domain
* @code: error code
* @message: error message
*
* Creates a new #GError; unlike g_error_new(), @message is not
* a printf()-style format string. Use this function if @message
* contains text you don't have control over, that could include
* printf() escape sequences.
*
* Return value: a new #GError
**/
GError*
g_error_new_literal (GQuark domain,
gint code,
const gchar *message)
{
GError* err;
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (domain != 0, NULL);
err = g_new (GError, 1);
err->domain = domain;
err->code = code;
err->message = g_strdup (message);
return err;
}
/**
* g_error_free:
* @error: a #GError
*
* Frees a #GError and associated resources.
*
**/
void
g_error_free (GError *error)
{
g_return_if_fail (error != NULL);
g_free (error->message);
g_free (error);
}
/**
* g_error_copy:
* @error: a #GError
*
* Makes a copy of @error.
*
* Return value: a new #GError
**/
GError*
g_error_copy (const GError *error)
{
GError *copy;
g_return_val_if_fail (error != NULL, NULL);
copy = g_new (GError, 1);
*copy = *error;
copy->message = g_strdup (error->message);
return copy;
}
/**
* g_error_matches:
* @error: a #GError
* @domain: an error domain
* @code: an error code
*
* Returns TRUE if @error matches @domain and @code, FALSE
* otherwise.
*
* Return value: whether @error has @domain and @code
**/
gboolean
g_error_matches (const GError *error,
GQuark domain,
gint code)
{
return error &&
error->domain == domain &&
error->code == code;
}
#define ERROR_OVERWRITTEN_WARNING "GError set over the top of a previous GError or uninitialized memory.\n" \
"This indicates a bug in someone's code. You must ensure an error is NULL before it's set.\n" \
"The overwriting error message was: %s"
/**
* g_set_error:
* @err: a return location for a #GError, or NULL
* @domain: error domain
* @code: error code
* @format: printf()-style format
* @Varargs: args for @format
*
* Does nothing if @err is NULL; if @err is non-NULL, then *@err must
* be NULL. A new #GError is created and assigned to *@err.
**/
void
g_set_error (GError **err,
GQuark domain,
gint code,
const gchar *format,
...)
{
GError *new;
va_list args;
if (err == NULL)
return;
va_start (args, format);
new = g_error_new_valist (domain, code, format, args);
va_end (args);
if (*err == NULL)
*err = new;
else
g_warning (ERROR_OVERWRITTEN_WARNING, new->message);
}
/**
* g_propagate_error:
* @dest: error return location
* @src: error to move into the return location
*
* If @dest is NULL, free @src; otherwise,
* moves @src into *@dest. *@dest must be NULL.
**/
void
g_propagate_error (GError **dest,
GError *src)
{
g_return_if_fail (src != NULL);
if (dest == NULL)
{
if (src)
g_error_free (src);
return;
}
else
{
if (*dest != NULL)
g_warning (ERROR_OVERWRITTEN_WARNING, src->message);
else
*dest = src;
}
}
/**
* g_clear_error:
* @err: a #GError return location
*
* If @err is NULL, does nothing. If @err is non-NULL,
* calls g_error_free() on *@err and sets *@err to NULL.
**/
void
g_clear_error (GError **err)
{
if (err && *err)
{
g_error_free (*err);
*err = NULL;
}
}

View File

@ -1,74 +0,0 @@
/* gerror.h - Error reporting system
*
* Copyright 2000 Red Hat, Inc.
*
* The Gnome Library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* The Gnome 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with the Gnome Library; see the file COPYING.LIB. If not,
* write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __G_ERROR_H__
#define __G_ERROR_H__
#include <gquark.h>
G_BEGIN_DECLS
typedef struct _GError GError;
struct _GError
{
GQuark domain;
gint code;
gchar *message;
};
GError* g_error_new (GQuark domain,
gint code,
const gchar *format,
...) G_GNUC_PRINTF (3, 4);
GError* g_error_new_literal (GQuark domain,
gint code,
const gchar *message);
void g_error_free (GError *error);
GError* g_error_copy (const GError *error);
gboolean g_error_matches (const GError *error,
GQuark domain,
gint code);
/* if (err) *err = g_error_new(domain, code, format, ...), also has
* some sanity checks.
*/
void g_set_error (GError **err,
GQuark domain,
gint code,
const gchar *format,
...) G_GNUC_PRINTF (4, 5);
/* if (dest) *dest = src; also has some sanity checks.
*/
void g_propagate_error (GError **dest,
GError *src);
/* if (err && *err) { g_error_free(*err); *err = NULL; } */
void g_clear_error (GError **err);
G_END_DECLS
#endif /* __G_ERROR_H__ */

View File

@ -1,698 +0,0 @@
/* gfileutils.c - File utility functions
*
* Copyright 2000 Red Hat, Inc.
*
* GLib is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* GLib 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with GLib; see the file COPYING.LIB. If not,
* write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include "glib.h"
#include <sys/stat.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#ifdef G_OS_WIN32
#include <io.h>
#ifndef F_OK
#define F_OK 0
#define X_OK 1
#define W_OK 2
#define R_OK 4
#endif /* !F_OK */
#ifndef S_ISREG
#define S_ISREG(mode) ((mode)&_S_IFREG)
#endif
#ifndef S_ISDIR
#define S_ISDIR(mode) ((mode)&_S_IFDIR)
#endif
#endif /* G_OS_WIN32 */
#ifndef S_ISLNK
#define S_ISLNK(x) 0
#endif
#ifndef O_BINARY
#define O_BINARY 0
#endif
#include "glibintl.h"
/**
* g_file_test:
* @filename: a filename to test
* @test: bitfield of #GFileTest flags
*
* Returns TRUE if any of the tests in the bitfield @test are
* TRUE. For example, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)
* will return TRUE if the file exists; the check whether it's
* a directory doesn't matter since the existence test is TRUE.
* With the current set of available tests, there's no point
* passing in more than one test at a time.
*
* Return value: whether a test was TRUE
**/
gboolean
g_file_test (const gchar *filename,
GFileTest test)
{
if (test & G_FILE_TEST_EXISTS)
return (access (filename, F_OK) == 0);
else if (test & G_FILE_TEST_IS_EXECUTABLE)
return (access (filename, X_OK) == 0);
else
{
struct stat s;
if (stat (filename, &s) < 0)
return FALSE;
if ((test & G_FILE_TEST_IS_REGULAR) &&
S_ISREG (s.st_mode))
return TRUE;
else if ((test & G_FILE_TEST_IS_DIR) &&
S_ISDIR (s.st_mode))
return TRUE;
else if ((test & G_FILE_TEST_IS_SYMLINK) &&
S_ISLNK (s.st_mode))
return TRUE;
else
return FALSE;
}
}
GQuark
g_file_error_quark (void)
{
static GQuark q = 0;
if (q == 0)
q = g_quark_from_static_string ("g-file-error-quark");
return q;
}
/**
* g_file_error_from_errno:
* @err_no: an "errno" value
*
* Gets a #GFileError constant based on the passed-in errno.
* For example, if you pass in EEXIST this function returns
* #G_FILE_ERROR_EXIST. Unlike errno values, you can portably
* assume that all #GFileError values will exist.
*
* Normally a #GFileError value goes into a #GError returned
* from a function that manipulates files. So you would use
* g_file_error_from_errno() when constructing a #GError.
*
* Return value: #GFileError corresponding to the given errno
**/
GFileError
g_file_error_from_errno (gint err_no)
{
switch (err_no)
{
#ifdef EEXIST
case EEXIST:
return G_FILE_ERROR_EXIST;
break;
#endif
#ifdef EISDIR
case EISDIR:
return G_FILE_ERROR_ISDIR;
break;
#endif
#ifdef EACCES
case EACCES:
return G_FILE_ERROR_ACCES;
break;
#endif
#ifdef ENAMETOOLONG
case ENAMETOOLONG:
return G_FILE_ERROR_NAMETOOLONG;
break;
#endif
#ifdef ENOENT
case ENOENT:
return G_FILE_ERROR_NOENT;
break;
#endif
#ifdef ENOTDIR
case ENOTDIR:
return G_FILE_ERROR_NOTDIR;
break;
#endif
#ifdef ENXIO
case ENXIO:
return G_FILE_ERROR_NXIO;
break;
#endif
#ifdef ENODEV
case ENODEV:
return G_FILE_ERROR_NODEV;
break;
#endif
#ifdef EROFS
case EROFS:
return G_FILE_ERROR_ROFS;
break;
#endif
#ifdef ETXTBSY
case ETXTBSY:
return G_FILE_ERROR_TXTBSY;
break;
#endif
#ifdef EFAULT
case EFAULT:
return G_FILE_ERROR_FAULT;
break;
#endif
#ifdef ELOOP
case ELOOP:
return G_FILE_ERROR_LOOP;
break;
#endif
#ifdef ENOSPC
case ENOSPC:
return G_FILE_ERROR_NOSPC;
break;
#endif
#ifdef ENOMEM
case ENOMEM:
return G_FILE_ERROR_NOMEM;
break;
#endif
#ifdef EMFILE
case EMFILE:
return G_FILE_ERROR_MFILE;
break;
#endif
#ifdef ENFILE
case ENFILE:
return G_FILE_ERROR_NFILE;
break;
#endif
#ifdef EBADF
case EBADF:
return G_FILE_ERROR_BADF;
break;
#endif
#ifdef EINVAL
case EINVAL:
return G_FILE_ERROR_INVAL;
break;
#endif
#ifdef EPIPE
case EPIPE:
return G_FILE_ERROR_PIPE;
break;
#endif
#ifdef EAGAIN
case EAGAIN:
return G_FILE_ERROR_AGAIN;
break;
#endif
#ifdef EINTR
case EINTR:
return G_FILE_ERROR_INTR;
break;
#endif
#ifdef EIO
case EIO:
return G_FILE_ERROR_IO;
break;
#endif
#ifdef EPERM
case EPERM:
return G_FILE_ERROR_PERM;
break;
#endif
default:
return G_FILE_ERROR_FAILED;
break;
}
}
static gboolean
get_contents_stdio (const gchar *filename,
FILE *f,
gchar **contents,
gsize *length,
GError **error)
{
gchar buf[2048];
size_t bytes;
GString *str;
g_assert (f != NULL);
str = g_string_new ("");
while (!feof (f))
{
bytes = fread (buf, 1, 2048, f);
if (ferror (f))
{
g_set_error (error,
G_FILE_ERROR,
g_file_error_from_errno (errno),
_("Error reading file '%s': %s"),
filename, strerror (errno));
g_string_free (str, TRUE);
return FALSE;
}
g_string_append_len (str, buf, bytes);
}
fclose (f);
if (length)
*length = str->len;
*contents = g_string_free (str, FALSE);
return TRUE;
}
#ifndef G_OS_WIN32
static gboolean
get_contents_regfile (const gchar *filename,
struct stat *stat_buf,
gint fd,
gchar **contents,
gsize *length,
GError **error)
{
gchar *buf;
size_t bytes_read;
size_t size;
size = stat_buf->st_size;
buf = g_new (gchar, size + 1);
bytes_read = 0;
while (bytes_read < size)
{
gssize rc;
rc = read (fd, buf + bytes_read, size - bytes_read);
if (rc < 0)
{
if (errno != EINTR)
{
close (fd);
g_free (buf);
g_set_error (error,
G_FILE_ERROR,
g_file_error_from_errno (errno),
_("Failed to read from file '%s': %s"),
filename, strerror (errno));
return FALSE;
}
}
else if (rc == 0)
break;
else
bytes_read += rc;
}
buf[bytes_read] = '\0';
if (length)
*length = bytes_read;
*contents = buf;
return TRUE;
}
static gboolean
get_contents_posix (const gchar *filename,
gchar **contents,
gsize *length,
GError **error)
{
struct stat stat_buf;
gint fd;
/* O_BINARY useful on Cygwin */
fd = open (filename, O_RDONLY|O_BINARY);
if (fd < 0)
{
g_set_error (error,
G_FILE_ERROR,
g_file_error_from_errno (errno),
_("Failed to open file '%s': %s"),
filename, strerror (errno));
return FALSE;
}
/* I don't think this will ever fail, aside from ENOMEM, but. */
if (fstat (fd, &stat_buf) < 0)
{
close (fd);
g_set_error (error,
G_FILE_ERROR,
g_file_error_from_errno (errno),
_("Failed to get attributes of file '%s': fstat() failed: %s"),
filename, strerror (errno));
return FALSE;
}
if (stat_buf.st_size > 0 && S_ISREG (stat_buf.st_mode))
{
return get_contents_regfile (filename,
&stat_buf,
fd,
contents,
length,
error);
}
else
{
FILE *f;
f = fdopen (fd, "r");
if (f == NULL)
{
g_set_error (error,
G_FILE_ERROR,
g_file_error_from_errno (errno),
_("Failed to open file '%s': fdopen() failed: %s"),
filename, strerror (errno));
return FALSE;
}
return get_contents_stdio (filename, f, contents, length, error);
}
}
#else /* G_OS_WIN32 */
static gboolean
get_contents_win32 (const gchar *filename,
gchar **contents,
gsize *length,
GError **error)
{
FILE *f;
/* I guess you want binary mode; maybe you want text sometimes? */
f = fopen (filename, "rb");
if (f == NULL)
{
g_set_error (error,
G_FILE_ERROR,
g_file_error_from_errno (errno),
_("Failed to open file '%s': %s"),
filename, strerror (errno));
return FALSE;
}
return get_contents_stdio (filename, f, contents, length, error);
}
#endif
/**
* g_file_get_contents:
* @filename: a file to read contents from
* @contents: location to store an allocated string
* @length: location to store length in bytes of the contents
* @error: return location for a #GError
*
* Reads an entire file into allocated memory, with good error
* checking. If @error is set, FALSE is returned, and @contents is set
* to NULL. If TRUE is returned, @error will not be set, and @contents
* will be set to the file contents. The string stored in @contents
* will be nul-terminated, so for text files you can pass NULL for the
* @length argument. The error domain is #G_FILE_ERROR. Possible
* error codes are those in the #GFileError enumeration.
*
* FIXME currently crashes if the file is too big to fit in memory;
* should probably use g_try_malloc() when we have that function.
*
* Return value: TRUE on success, FALSE if error is set
**/
gboolean
g_file_get_contents (const gchar *filename,
gchar **contents,
gsize *length,
GError **error)
{
g_return_val_if_fail (filename != NULL, FALSE);
g_return_val_if_fail (contents != NULL, FALSE);
*contents = NULL;
if (length)
*length = 0;
#ifdef G_OS_WIN32
return get_contents_win32 (filename, contents, length, error);
#else
return get_contents_posix (filename, contents, length, error);
#endif
}
/*
* mkstemp() implementation is from the GNU C library.
* Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
*/
/**
* g_mkstemp:
* @tmpl: template filename
*
* Open a temporary file. See "man mkstemp" on most UNIX-like systems.
* This is a portability wrapper, which simply calls mkstemp() on systems
* that have it, and implements it in GLib otherwise.
*
* The parameter is a string that should match the rules for mktemp, i.e.
* end in "XXXXXX". The X string will be modified to form the name
* of a file that didn't exist.
*
* Return value: A file handle (as from open()) to the file
* opened for reading and writing. The file is opened in binary mode
* on platforms where there is a difference. The file handle should be
* closed with close(). In case of errors, -1 is returned.
*/
int
g_mkstemp (char *tmpl)
{
#ifdef HAVE_MKSTEMP
return mkstemp (tmpl);
#else
int len;
char *XXXXXX;
int count, fd;
static const char letters[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
static const int NLETTERS = sizeof (letters) - 1;
glong value;
GTimeVal tv;
static int counter = 0;
len = strlen (tmpl);
if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
return -1;
/* This is where the Xs start. */
XXXXXX = &tmpl[len - 6];
/* Get some more or less random data. */
g_get_current_time (&tv);
value = (tv.tv_usec ^ tv.tv_sec) + counter++;
for (count = 0; count < 100; value += 7777, ++count)
{
glong v = value;
/* Fill in the random bits. */
XXXXXX[0] = letters[v % NLETTERS];
v /= NLETTERS;
XXXXXX[1] = letters[v % NLETTERS];
v /= NLETTERS;
XXXXXX[2] = letters[v % NLETTERS];
v /= NLETTERS;
XXXXXX[3] = letters[v % NLETTERS];
v /= NLETTERS;
XXXXXX[4] = letters[v % NLETTERS];
v /= NLETTERS;
XXXXXX[5] = letters[v % NLETTERS];
fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
if (fd >= 0)
return fd;
else if (errno != EEXIST)
/* Any other error will apply also to other names we might
* try, and there are 2^32 or so of them, so give up now.
*/
return -1;
}
/* We got out of the loop because we ran out of combinations to try. */
return -1;
#endif
}
/**
* g_file_open_tmp:
* @tmpl: Template for file name, as in g_mkstemp, basename only
* @name_used: location to store actual name used
* @error: return location for a #GError
*
* Opens a file for writing in the preferred directory for temporary
* files (as returned by g_get_tmp_dir()).
*
* @tmpl should be a string ending with six 'X' characters, as the
* parameter to g_mkstemp() (or mkstemp()). However, unlike these
* functions, the template should only be a basename, no directory
* components are allowed. If template is NULL, a default template is
* used.
*
* Note that in contrast to g_mkstemp() (and mkstemp()) @tmpl is not
* modified, and might thus be a read-only literal string.
*
* The actual name used is returned in @name_used if non-NULL. This
* string should be freed with g_free when not needed any longer.
*
* Return value: A file handle (as from open()) to the file
* opened for reading and writing. The file is opened in binary mode
* on platforms where there is a difference. The file handle should be
* closed with close(). In case of errors, -1 is returned and
* @error will be set.
**/
int
g_file_open_tmp (const char *tmpl,
char **name_used,
GError **error)
{
int retval;
const char *tmpdir;
char *sep;
char *fulltemplate;
if (tmpl == NULL)
tmpl = ".XXXXXX";
if (strchr (tmpl, G_DIR_SEPARATOR)
#ifdef G_OS_WIN32
|| strchr (tmpl, '/')
#endif
)
{
g_set_error (error,
G_FILE_ERROR,
G_FILE_ERROR_FAILED,
_("Template '%s' illegal, should not contain a '%s'"),
tmpl, G_DIR_SEPARATOR_S);
return -1;
}
if (strlen (tmpl) < 6 ||
strcmp (tmpl + strlen (tmpl) - 6, "XXXXXX") != 0)
{
g_set_error (error,
G_FILE_ERROR,
G_FILE_ERROR_FAILED,
_("Template '%s' doesn't end with XXXXXX"),
tmpl);
return -1;
}
tmpdir = g_get_tmp_dir ();
if (tmpdir [strlen (tmpdir) - 1] == G_DIR_SEPARATOR)
sep = "";
else
sep = G_DIR_SEPARATOR_S;
fulltemplate = g_strconcat (tmpdir, sep, tmpl, NULL);
retval = g_mkstemp (fulltemplate);
if (retval == -1)
{
g_set_error (error,
G_FILE_ERROR,
g_file_error_from_errno (errno),
_("Failed to create file '%s': %s"),
fulltemplate, strerror (errno));
g_free (fulltemplate);
return -1;
}
if (name_used)
*name_used = fulltemplate;
else
g_free (fulltemplate);
return retval;
}

View File

@ -1,95 +0,0 @@
/* gfileutils.h - File utility functions
*
* Copyright 2000 Red Hat, Inc.
*
* GLib is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* GLib 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with GLib; see the file COPYING.LIB. If not,
* write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __G_FILEUTILS_H__
#define __G_FILEUTILS_H__
#include <gerror.h>
G_BEGIN_DECLS
#define G_FILE_ERROR g_file_error_quark ()
typedef enum
{
G_FILE_ERROR_EXIST,
G_FILE_ERROR_ISDIR,
G_FILE_ERROR_ACCES,
G_FILE_ERROR_NAMETOOLONG,
G_FILE_ERROR_NOENT,
G_FILE_ERROR_NOTDIR,
G_FILE_ERROR_NXIO,
G_FILE_ERROR_NODEV,
G_FILE_ERROR_ROFS,
G_FILE_ERROR_TXTBSY,
G_FILE_ERROR_FAULT,
G_FILE_ERROR_LOOP,
G_FILE_ERROR_NOSPC,
G_FILE_ERROR_NOMEM,
G_FILE_ERROR_MFILE,
G_FILE_ERROR_NFILE,
G_FILE_ERROR_BADF,
G_FILE_ERROR_INVAL,
G_FILE_ERROR_PIPE,
G_FILE_ERROR_AGAIN,
G_FILE_ERROR_INTR,
G_FILE_ERROR_IO,
G_FILE_ERROR_PERM,
G_FILE_ERROR_FAILED
} GFileError;
/* For backward-compat reasons, these are synced to an old
* anonymous enum in libgnome. But don't use that enum
* in new code.
*/
typedef enum
{
G_FILE_TEST_IS_REGULAR = 1 << 0,
G_FILE_TEST_IS_SYMLINK = 1 << 1,
G_FILE_TEST_IS_DIR = 1 << 2,
G_FILE_TEST_IS_EXECUTABLE = 1 << 3,
G_FILE_TEST_EXISTS = 1 << 4
} GFileTest;
GQuark g_file_error_quark (void);
/* So other code can generate a GFileError */
GFileError g_file_error_from_errno (gint err_no);
gboolean g_file_test (const gchar *filename,
GFileTest test);
gboolean g_file_get_contents (const gchar *filename,
gchar **contents,
gsize *length,
GError **error);
/* Wrapper / workalike for mkstemp() */
int g_mkstemp (char *tmpl);
/* Wrapper for g_mkstemp */
int g_file_open_tmp (const char *tmpl,
char **name_used,
GError **error);
G_END_DECLS
#endif /* __G_FILEUTILS_H__ */

695
ghash.c
View File

@ -1,695 +0,0 @@
/* 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 Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
/*
* MT safe
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "glib.h"
#define HASH_TABLE_MIN_SIZE 11
#define HASH_TABLE_MAX_SIZE 13845163
typedef struct _GHashNode GHashNode;
struct _GHashNode
{
gpointer key;
gpointer value;
GHashNode *next;
};
struct _GHashTable
{
gint size;
gint nnodes;
GHashNode **nodes;
GHashFunc hash_func;
GEqualFunc key_equal_func;
GDestroyNotify key_destroy_func;
GDestroyNotify value_destroy_func;
};
static void g_hash_table_resize (GHashTable *hash_table);
static GHashNode** g_hash_table_lookup_node (GHashTable *hash_table,
gconstpointer key);
static GHashNode* g_hash_node_new (gpointer key,
gpointer value);
static void g_hash_node_destroy (GHashNode *hash_node,
GDestroyNotify key_destroy_func,
GDestroyNotify value_destroy_func);
static void g_hash_nodes_destroy (GHashNode *hash_node,
GDestroyNotify key_destroy_func,
GDestroyNotify value_destroy_func);
static guint g_hash_table_foreach_remove_or_steal (GHashTable *hash_table,
GHRFunc func,
gpointer user_data,
gboolean notify);
G_LOCK_DEFINE_STATIC (g_hash_global);
static GMemChunk *node_mem_chunk = NULL;
static GHashNode *node_free_list = NULL;
/**
* g_hash_table_new:
* @hash_func: a function to create a hash value from a key.
* Hash values are used to determine where keys are stored within the
* #GHashTable data structure. The g_direct_hash(), g_int_hash() and
* g_str_hash() functions are provided for some common types of keys.
* If hash_func is NULL, g_direct_hash() is used.
* @key_equal_func: a function to check two keys for equality. This is
* used when looking up keys in the #GHashTable. The g_direct_equal(),
* g_int_equal() and g_str_equal() functions are provided for the most
* common types of keys. If @key_equal_func is NULL, keys are compared
* directly in a similar fashion to g_direct_equal(), but without the
* overhead of a function call.
*
* Creates a new #GHashTable.
*
* Return value: a new #GHashTable.
**/
GHashTable*
g_hash_table_new (GHashFunc hash_func,
GEqualFunc key_equal_func)
{
return g_hash_table_new_full (hash_func, key_equal_func, NULL, NULL);
}
/**
* g_hash_table_new_full:
* @hash_func: a function to create a hash value from a key.
* @key_equal_func: a function to check two keys for equality.
* @key_destroy_func: a function to free the memory allocated for the key
* used when removing the entry from the #GHashTable or #NULL if you
* don't want to supply such a function.
* @value_destroy_func: a function to free the memory allocated for the
* value used when removing the entry from the #GHashTable or #NULL if
* you don't want to supply such a function.
*
* Creates a new #GHashTable like g_hash_table_new() and allows to specify
* functions to free the memory allocated for the key and value that get
* called when removing the entry from the #GHashTable.
*
* Return value: a new #GHashTable.
**/
GHashTable*
g_hash_table_new_full (GHashFunc hash_func,
GEqualFunc key_equal_func,
GDestroyNotify key_destroy_func,
GDestroyNotify value_destroy_func)
{
GHashTable *hash_table;
guint i;
hash_table = g_new (GHashTable, 1);
hash_table->size = HASH_TABLE_MIN_SIZE;
hash_table->nnodes = 0;
hash_table->hash_func = hash_func ? hash_func : g_direct_hash;
hash_table->key_equal_func = key_equal_func;
hash_table->key_destroy_func = key_destroy_func;
hash_table->value_destroy_func = value_destroy_func;
hash_table->nodes = g_new (GHashNode*, hash_table->size);
for (i = 0; i < hash_table->size; i++)
hash_table->nodes[i] = NULL;
return hash_table;
}
/**
* g_hash_table_destroy:
* @hash_table: a #GHashTable.
*
* Destroys the #GHashTable. If keys and/or values are dynamically
* allocated, you should either free them first or create the #GHashTable
* using g_hash_table_new_full(). In the latter case the destroy functions
* you supplied will be called on all keys and values before destroying
* the #GHashTable.
**/
void
g_hash_table_destroy (GHashTable *hash_table)
{
guint i;
g_return_if_fail (hash_table != NULL);
for (i = 0; i < hash_table->size; i++)
g_hash_nodes_destroy (hash_table->nodes[i],
hash_table->key_destroy_func,
hash_table->value_destroy_func);
g_free (hash_table->nodes);
g_free (hash_table);
}
static inline GHashNode**
g_hash_table_lookup_node (GHashTable *hash_table,
gconstpointer key)
{
GHashNode **node;
node = &hash_table->nodes
[(* hash_table->hash_func) (key) % hash_table->size];
/* Hash table lookup needs to be fast.
* We therefore remove the extra conditional of testing
* whether to call the key_equal_func or not from
* the inner loop.
*/
if (hash_table->key_equal_func)
while (*node && !(*hash_table->key_equal_func) ((*node)->key, key))
node = &(*node)->next;
else
while (*node && (*node)->key != key)
node = &(*node)->next;
return node;
}
/**
* g_hash_table_lookup:
* @hash_table: a #GHashTable.
* @key: the key to look up.
*
* Looks up a key in a #GHashTable.
*
* Return value: the associated value, or NULL if the key is not found.
**/
gpointer
g_hash_table_lookup (GHashTable *hash_table,
gconstpointer key)
{
GHashNode *node;
g_return_val_if_fail (hash_table != NULL, NULL);
node = *g_hash_table_lookup_node (hash_table, key);
return node ? node->value : NULL;
}
/**
* g_hash_table_lookup_extended:
* @hash_table: a #GHashTable.
* @lookup_key: the key to look up.
* @orig_key: returns the original key.
* @value: returns the value associated with the key.
*
* Looks up a key in the #GHashTable, returning the original key and the
* associated value and a gboolean which is TRUE if the key was found. This
* is useful if you need to free the memory allocated for the original key,
* for example before calling g_hash_table_remove().
*
* Return value: #TRUE if the key was found in the #GHashTable.
**/
gboolean
g_hash_table_lookup_extended (GHashTable *hash_table,
gconstpointer lookup_key,
gpointer *orig_key,
gpointer *value)
{
GHashNode *node;
g_return_val_if_fail (hash_table != NULL, FALSE);
node = *g_hash_table_lookup_node (hash_table, lookup_key);
if (node)
{
if (orig_key)
*orig_key = node->key;
if (value)
*value = node->value;
return TRUE;
}
else
return FALSE;
}
/**
* g_hash_table_insert:
* @hash_table: a #GHashTable.
* @key: a key to insert.
* @value: the value to associate with the key.
*
* Inserts a new key and value into a #GHashTable.
*
* If the key already exists in the #GHashTable its current value is replaced
* with the new value. If you supplied a value_destroy_func when creating the
* #GHashTable, the old value is freed using that function. If you supplied
* a key_destroy_func when creating the #GHashTable, the passed key is freed
* using that function.
**/
void
g_hash_table_insert (GHashTable *hash_table,
gpointer key,
gpointer value)
{
GHashNode **node;
g_return_if_fail (hash_table != NULL);
node = g_hash_table_lookup_node (hash_table, key);
if (*node)
{
/* do not reset node->key in this place, keeping
* the old key is the intended behaviour.
* g_hash_table_replace() can be used instead.
*/
/* free the passed key */
if (hash_table->key_destroy_func)
hash_table->key_destroy_func (key);
if (hash_table->value_destroy_func)
hash_table->value_destroy_func ((*node)->value);
(*node)->value = value;
}
else
{
*node = g_hash_node_new (key, value);
hash_table->nnodes++;
g_hash_table_resize (hash_table);
}
}
/**
* g_hash_table_replace:
* @hash_table: a #GHashTable.
* @key: a key to insert.
* @value: the value to associate with the key.
*
* Inserts a new key and value into a #GHashTable similar to
* g_hash_table_insert(). The difference is that if the key already exists
* in the #GHashTable, it gets replaced by the new key. If you supplied a
* value_destroy_func when creating the #GHashTable, the old value is freed
* using that function. If you supplied a key_destroy_func when creating the
* #GHashTable, the old key is freed using that function.
**/
void
g_hash_table_replace (GHashTable *hash_table,
gpointer key,
gpointer value)
{
GHashNode **node;
g_return_if_fail (hash_table != NULL);
node = g_hash_table_lookup_node (hash_table, key);
if (*node)
{
if (hash_table->key_destroy_func)
hash_table->key_destroy_func ((*node)->key);
if (hash_table->value_destroy_func)
hash_table->value_destroy_func ((*node)->value);
(*node)->key = key;
(*node)->value = value;
}
else
{
*node = g_hash_node_new (key, value);
hash_table->nnodes++;
g_hash_table_resize (hash_table);
}
}
/**
* g_hash_table_remove:
* @hash_table: a #GHashTable.
* @key: the key to remove.
*
* Removes a key and its associated value from a #GHashTable.
*
* If the #GHashTable was created using g_hash_table_new_full(), the
* key and value are freed using the supplied destroy_functions, otherwise
* you have to make sure that any dynamically allocated values are freed
* yourself.
*
* Return value: #TRUE if the key was found and removed from the #GHashTable.
**/
gboolean
g_hash_table_remove (GHashTable *hash_table,
gconstpointer key)
{
GHashNode **node, *dest;
g_return_val_if_fail (hash_table != NULL, FALSE);
node = g_hash_table_lookup_node (hash_table, key);
if (*node)
{
dest = *node;
(*node) = dest->next;
g_hash_node_destroy (dest,
hash_table->key_destroy_func,
hash_table->value_destroy_func);
hash_table->nnodes--;
g_hash_table_resize (hash_table);
return TRUE;
}
return FALSE;
}
/**
* g_hash_table_steal:
* @hash_table: a #GHashTable.
* @key: the key to remove.
*
* Removes a key and its associated value from a #GHashTable without
* calling the key and value destroy functions.
*
* Return value: #TRUE if the key was found and removed from the #GHashTable.
**/
gboolean
g_hash_table_steal (GHashTable *hash_table,
gconstpointer key)
{
GHashNode **node, *dest;
g_return_val_if_fail (hash_table != NULL, FALSE);
node = g_hash_table_lookup_node (hash_table, key);
if (*node)
{
dest = *node;
(*node) = dest->next;
g_hash_node_destroy (dest, NULL, NULL);
hash_table->nnodes--;
g_hash_table_resize (hash_table);
return TRUE;
}
return FALSE;
}
/**
* g_hash_table_foreach_remove:
* @hash_table: a #GHashTable.
* @func: the function to call for each key/value pair.
* @user_data: user data to pass to the function.
*
* Calls the given function for each key/value pair in the #GHashTable.
* If the function returns TRUE, then the key/value pair is removed from the
* #GHashTable. If you supplied key or value destroy functions when creating
* the #GHashTable, they are used to free the memory allocated for the removed
* keys and values.
*
* Return value: the number of key/value pairs removed.
**/
guint
g_hash_table_foreach_remove (GHashTable *hash_table,
GHRFunc func,
gpointer user_data)
{
g_return_val_if_fail (hash_table != NULL, 0);
g_return_val_if_fail (func != NULL, 0);
return g_hash_table_foreach_remove_or_steal (hash_table, func, user_data, TRUE);
}
/**
* g_hash_table_foreach_steal:
* @hash_table: a #GHashTable.
* @func: the function to call for each key/value pair.
* @user_data: user data to pass to the function.
*
* Calls the given function for each key/value pair in the #GHashTable.
* If the function returns TRUE, then the key/value pair is removed from the
* #GHashTable, but no key or value destroy functions are called.
*
* Return value: the number of key/value pairs removed.
**/
guint
g_hash_table_foreach_steal (GHashTable *hash_table,
GHRFunc func,
gpointer user_data)
{
g_return_val_if_fail (hash_table != NULL, 0);
g_return_val_if_fail (func != NULL, 0);
return g_hash_table_foreach_remove_or_steal (hash_table, func, user_data, FALSE);
}
static guint
g_hash_table_foreach_remove_or_steal (GHashTable *hash_table,
GHRFunc func,
gpointer user_data,
gboolean notify)
{
GHashNode *node, *prev;
guint i;
guint deleted = 0;
for (i = 0; i < hash_table->size; i++)
{
restart:
prev = NULL;
for (node = hash_table->nodes[i]; node; prev = node, node = node->next)
{
if ((* func) (node->key, node->value, user_data))
{
deleted += 1;
hash_table->nnodes -= 1;
if (prev)
{
prev->next = node->next;
g_hash_node_destroy (node,
notify ? hash_table->value_destroy_func : NULL,
notify ? hash_table->key_destroy_func : NULL);
node = prev;
}
else
{
hash_table->nodes[i] = node->next;
g_hash_node_destroy (node,
notify ? hash_table->value_destroy_func : NULL,
notify ? hash_table->key_destroy_func : NULL);
goto restart;
}
}
}
}
g_hash_table_resize (hash_table);
return deleted;
}
/**
* g_hash_table_foreach:
* @hash_table: a #GHashTable.
* @func: the function to call for each key/value pair.
* @user_data: user data to pass to the function.
*
* Calls the given function for each of the key/value pairs in the #GHashTable.
* The function is passed the key and value of each pair, and the given
* @user_data parameter.
**/
void
g_hash_table_foreach (GHashTable *hash_table,
GHFunc func,
gpointer user_data)
{
GHashNode *node;
gint i;
g_return_if_fail (hash_table != NULL);
g_return_if_fail (func != NULL);
for (i = 0; i < hash_table->size; i++)
for (node = hash_table->nodes[i]; node; node = node->next)
(* func) (node->key, node->value, user_data);
}
/**
* g_hash_table_size:
* @hash_table: a #GHashTable.
*
* Returns the number of elements contained in the #GHashTable.
*
* Return value: the number of key/value pairs in the #GHashTable.
**/
guint
g_hash_table_size (GHashTable *hash_table)
{
g_return_val_if_fail (hash_table != NULL, 0);
return hash_table->nnodes;
}
static void
g_hash_table_resize (GHashTable *hash_table)
{
GHashNode **new_nodes;
GHashNode *node;
GHashNode *next;
gfloat nodes_per_list;
guint hash_val;
gint new_size;
gint i;
nodes_per_list = (gfloat) hash_table->nnodes / (gfloat) hash_table->size;
if ((nodes_per_list > 0.3 || hash_table->size <= HASH_TABLE_MIN_SIZE) &&
(nodes_per_list < 3.0 || hash_table->size >= HASH_TABLE_MAX_SIZE))
return;
new_size = CLAMP(g_spaced_primes_closest (hash_table->nnodes),
HASH_TABLE_MIN_SIZE,
HASH_TABLE_MAX_SIZE);
new_nodes = g_new0 (GHashNode*, new_size);
for (i = 0; i < hash_table->size; i++)
for (node = hash_table->nodes[i]; node; node = next)
{
next = node->next;
hash_val = (* hash_table->hash_func) (node->key) % new_size;
node->next = new_nodes[hash_val];
new_nodes[hash_val] = node;
}
g_free (hash_table->nodes);
hash_table->nodes = new_nodes;
hash_table->size = new_size;
}
static GHashNode*
g_hash_node_new (gpointer key,
gpointer value)
{
GHashNode *hash_node;
G_LOCK (g_hash_global);
if (node_free_list)
{
hash_node = node_free_list;
node_free_list = node_free_list->next;
}
else
{
if (!node_mem_chunk)
node_mem_chunk = g_mem_chunk_new ("hash node mem chunk",
sizeof (GHashNode),
1024, G_ALLOC_ONLY);
hash_node = g_chunk_new (GHashNode, node_mem_chunk);
}
G_UNLOCK (g_hash_global);
hash_node->key = key;
hash_node->value = value;
hash_node->next = NULL;
return hash_node;
}
static void
g_hash_node_destroy (GHashNode *hash_node,
GDestroyNotify key_destroy_func,
GDestroyNotify value_destroy_func)
{
if (key_destroy_func)
key_destroy_func (hash_node->key);
if (value_destroy_func)
value_destroy_func (hash_node->value);
#ifdef ENABLE_GC_FRIENDLY
hash_node->key = NULL;
hash_node->value = NULL;
#endif /* ENABLE_GC_FRIENDLY */
G_LOCK (g_hash_global);
hash_node->next = node_free_list;
node_free_list = hash_node;
G_UNLOCK (g_hash_global);
}
static void
g_hash_nodes_destroy (GHashNode *hash_node,
GFreeFunc key_destroy_func,
GFreeFunc value_destroy_func)
{
if (hash_node)
{
GHashNode *node = hash_node;
while (node->next)
{
if (key_destroy_func)
key_destroy_func (node->key);
if (value_destroy_func)
value_destroy_func (node->value);
#ifdef ENABLE_GC_FRIENDLY
node->key = NULL;
node->value = NULL;
#endif /* ENABLE_GC_FRIENDLY */
node = node->next;
}
if (key_destroy_func)
key_destroy_func (node->key);
if (value_destroy_func)
value_destroy_func (node->value);
#ifdef ENABLE_GC_FRIENDLY
node->key = NULL;
node->value = NULL;
#endif /* ENABLE_GC_FRIENDLY */
G_LOCK (g_hash_global);
node->next = node_free_list;
node_free_list = hash_node;
G_UNLOCK (g_hash_global);
}
}

108
ghash.h
View File

@ -1,108 +0,0 @@
/* 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 Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
#ifndef __G_HASH_H__
#define __G_HASH_H__
#include <gtypes.h>
G_BEGIN_DECLS
typedef struct _GHashTable GHashTable;
typedef gboolean (*GHRFunc) (gpointer key,
gpointer value,
gpointer user_data);
/* Hash tables
*/
GHashTable* g_hash_table_new (GHashFunc hash_func,
GEqualFunc key_equal_func);
GHashTable* g_hash_table_new_full (GHashFunc hash_func,
GEqualFunc key_equal_func,
GDestroyNotify key_destroy_func,
GDestroyNotify value_destroy_func);
void g_hash_table_destroy (GHashTable *hash_table);
void g_hash_table_insert (GHashTable *hash_table,
gpointer key,
gpointer value);
void g_hash_table_replace (GHashTable *hash_table,
gpointer key,
gpointer value);
gboolean g_hash_table_remove (GHashTable *hash_table,
gconstpointer key);
gboolean g_hash_table_steal (GHashTable *hash_table,
gconstpointer key);
gpointer g_hash_table_lookup (GHashTable *hash_table,
gconstpointer key);
gboolean g_hash_table_lookup_extended (GHashTable *hash_table,
gconstpointer lookup_key,
gpointer *orig_key,
gpointer *value);
void g_hash_table_foreach (GHashTable *hash_table,
GHFunc func,
gpointer user_data);
guint g_hash_table_foreach_remove (GHashTable *hash_table,
GHRFunc func,
gpointer user_data);
guint g_hash_table_foreach_steal (GHashTable *hash_table,
GHRFunc func,
gpointer user_data);
guint g_hash_table_size (GHashTable *hash_table);
#ifndef G_DISABLE_DEPRECATED
/* The following two functions are deprecated and will be removed in
* the next major release. They do no good. */
#define g_hash_table_freeze(hash_table) ((void)0)
#define g_hash_table_thaw(hash_table) ((void)0)
#endif /* G_DISABLE_DEPRECATED */
/* Hash Functions
*/
gboolean g_str_equal (gconstpointer v,
gconstpointer v2);
guint g_str_hash (gconstpointer v);
gboolean g_int_equal (gconstpointer v,
gconstpointer v2) G_GNUC_CONST;
guint g_int_hash (gconstpointer v) G_GNUC_CONST;
/* This "hash" function will just return the key's adress as an
* unsigned integer. Useful for hashing on plain adresses or
* simple integer values.
* passing NULL into g_hash_table_new() as GHashFunc has the
* same effect as passing g_direct_hash().
*/
guint g_direct_hash (gconstpointer v) G_GNUC_CONST;
gboolean g_direct_equal (gconstpointer v,
gconstpointer v2) G_GNUC_CONST;
G_END_DECLS
#endif /* __G_HASH_H__ */

640
ghook.c
View File

@ -1,640 +0,0 @@
/* GLIB - Library of useful routines for C programming
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* GHook: Callback maintenance functions
* Copyright (C) 1998 Tim Janik
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
/*
* MT safe
*/
#include "glib.h"
/* --- defines --- */
#define G_HOOKS_PREALLOC (16)
/* --- functions --- */
static void
default_finalize_hook (GHookList *hook_list,
GHook *hook)
{
GDestroyNotify destroy = hook->destroy;
if (destroy)
{
hook->destroy = NULL;
destroy (hook->data);
}
}
void
g_hook_list_init (GHookList *hook_list,
guint hook_size)
{
g_return_if_fail (hook_list != NULL);
g_return_if_fail (hook_size >= sizeof (GHook));
g_return_if_fail (hook_size < 65536);
hook_list->seq_id = 1;
hook_list->hook_size = hook_size;
hook_list->is_setup = TRUE;
hook_list->hooks = NULL;
hook_list->hook_memchunk = g_mem_chunk_new ("GHook Memchunk",
hook_size,
hook_size * G_HOOKS_PREALLOC,
G_ALLOC_AND_FREE);
hook_list->finalize_hook = default_finalize_hook;
}
void
g_hook_list_clear (GHookList *hook_list)
{
g_return_if_fail (hook_list != NULL);
if (hook_list->is_setup)
{
GHook *hook;
hook_list->is_setup = FALSE;
hook = hook_list->hooks;
if (!hook)
{
g_mem_chunk_destroy (hook_list->hook_memchunk);
hook_list->hook_memchunk = NULL;
}
else
do
{
GHook *tmp;
g_hook_ref (hook_list, hook);
g_hook_destroy_link (hook_list, hook);
tmp = hook->next;
g_hook_unref (hook_list, hook);
hook = tmp;
}
while (hook);
if (hook_list->hook_memchunk)
g_warning (G_STRLOC ": failed to clear hooklist, unconsolidated references on hooks left");
}
}
GHook*
g_hook_alloc (GHookList *hook_list)
{
GHook *hook;
g_return_val_if_fail (hook_list != NULL, NULL);
g_return_val_if_fail (hook_list->is_setup, NULL);
hook = g_chunk_new0 (GHook, hook_list->hook_memchunk);
hook->data = NULL;
hook->next = NULL;
hook->prev = NULL;
hook->flags = G_HOOK_FLAG_ACTIVE;
hook->ref_count = 0;
hook->hook_id = 0;
hook->func = NULL;
hook->destroy = NULL;
return hook;
}
void
g_hook_free (GHookList *hook_list,
GHook *hook)
{
g_return_if_fail (hook_list != NULL);
g_return_if_fail (hook_list->is_setup);
g_return_if_fail (hook != NULL);
g_return_if_fail (G_HOOK_IS_UNLINKED (hook));
g_return_if_fail (!G_HOOK_IN_CALL (hook));
hook_list->finalize_hook (hook_list, hook);
g_chunk_free (hook, hook_list->hook_memchunk);
}
void
g_hook_destroy_link (GHookList *hook_list,
GHook *hook)
{
g_return_if_fail (hook_list != NULL);
g_return_if_fail (hook != NULL);
hook->flags &= ~G_HOOK_FLAG_ACTIVE;
if (hook->hook_id)
{
hook->hook_id = 0;
g_hook_unref (hook_list, hook); /* counterpart to g_hook_insert_before */
}
}
gboolean
g_hook_destroy (GHookList *hook_list,
gulong hook_id)
{
GHook *hook;
g_return_val_if_fail (hook_list != NULL, FALSE);
g_return_val_if_fail (hook_id > 0, FALSE);
hook = g_hook_get (hook_list, hook_id);
if (hook)
{
g_hook_destroy_link (hook_list, hook);
return TRUE;
}
return FALSE;
}
void
g_hook_unref (GHookList *hook_list,
GHook *hook)
{
g_return_if_fail (hook_list != NULL);
g_return_if_fail (hook_list->hook_memchunk != NULL);
g_return_if_fail (hook != NULL);
g_return_if_fail (hook->ref_count > 0);
hook->ref_count--;
if (!hook->ref_count)
{
g_return_if_fail (hook->hook_id == 0);
g_return_if_fail (!G_HOOK_IN_CALL (hook));
if (hook->prev)
hook->prev->next = hook->next;
else
hook_list->hooks = hook->next;
if (hook->next)
{
hook->next->prev = hook->prev;
hook->next = NULL;
}
hook->prev = NULL;
if (!hook_list->is_setup)
{
hook_list->is_setup = TRUE;
g_hook_free (hook_list, hook);
hook_list->is_setup = FALSE;
if (!hook_list->hooks)
{
g_mem_chunk_destroy (hook_list->hook_memchunk);
hook_list->hook_memchunk = NULL;
}
}
else
g_hook_free (hook_list, hook);
}
}
void
g_hook_ref (GHookList *hook_list,
GHook *hook)
{
g_return_if_fail (hook_list != NULL);
g_return_if_fail (hook != NULL);
g_return_if_fail (hook->ref_count > 0);
hook->ref_count++;
}
void
g_hook_prepend (GHookList *hook_list,
GHook *hook)
{
g_return_if_fail (hook_list != NULL);
g_hook_insert_before (hook_list, hook_list->hooks, hook);
}
void
g_hook_insert_before (GHookList *hook_list,
GHook *sibling,
GHook *hook)
{
g_return_if_fail (hook_list != NULL);
g_return_if_fail (hook_list->is_setup);
g_return_if_fail (hook != NULL);
g_return_if_fail (G_HOOK_IS_UNLINKED (hook));
g_return_if_fail (hook->ref_count == 0);
hook->hook_id = hook_list->seq_id++;
hook->ref_count = 1; /* counterpart to g_hook_destroy_link */
if (sibling)
{
if (sibling->prev)
{
hook->prev = sibling->prev;
hook->prev->next = hook;
hook->next = sibling;
sibling->prev = hook;
}
else
{
hook_list->hooks = hook;
hook->next = sibling;
sibling->prev = hook;
}
}
else
{
if (hook_list->hooks)
{
sibling = hook_list->hooks;
while (sibling->next)
sibling = sibling->next;
hook->prev = sibling;
sibling->next = hook;
}
else
hook_list->hooks = hook;
}
}
void
g_hook_list_invoke (GHookList *hook_list,
gboolean may_recurse)
{
GHook *hook;
g_return_if_fail (hook_list != NULL);
g_return_if_fail (hook_list->is_setup);
hook = g_hook_first_valid (hook_list, may_recurse);
while (hook)
{
GHookFunc func;
gboolean was_in_call;
func = (GHookFunc) hook->func;
was_in_call = G_HOOK_IN_CALL (hook);
hook->flags |= G_HOOK_FLAG_IN_CALL;
func (hook->data);
if (!was_in_call)
hook->flags &= ~G_HOOK_FLAG_IN_CALL;
hook = g_hook_next_valid (hook_list, hook, may_recurse);
}
}
void
g_hook_list_invoke_check (GHookList *hook_list,
gboolean may_recurse)
{
GHook *hook;
g_return_if_fail (hook_list != NULL);
g_return_if_fail (hook_list->is_setup);
hook = g_hook_first_valid (hook_list, may_recurse);
while (hook)
{
GHookCheckFunc func;
gboolean was_in_call;
gboolean need_destroy;
func = (GHookCheckFunc) hook->func;
was_in_call = G_HOOK_IN_CALL (hook);
hook->flags |= G_HOOK_FLAG_IN_CALL;
need_destroy = !func (hook->data);
if (!was_in_call)
hook->flags &= ~G_HOOK_FLAG_IN_CALL;
if (need_destroy)
g_hook_destroy_link (hook_list, hook);
hook = g_hook_next_valid (hook_list, hook, may_recurse);
}
}
void
g_hook_list_marshal_check (GHookList *hook_list,
gboolean may_recurse,
GHookCheckMarshaller marshaller,
gpointer data)
{
GHook *hook;
g_return_if_fail (hook_list != NULL);
g_return_if_fail (hook_list->is_setup);
g_return_if_fail (marshaller != NULL);
hook = g_hook_first_valid (hook_list, may_recurse);
while (hook)
{
gboolean was_in_call;
gboolean need_destroy;
was_in_call = G_HOOK_IN_CALL (hook);
hook->flags |= G_HOOK_FLAG_IN_CALL;
need_destroy = !marshaller (hook, data);
if (!was_in_call)
hook->flags &= ~G_HOOK_FLAG_IN_CALL;
if (need_destroy)
g_hook_destroy_link (hook_list, hook);
hook = g_hook_next_valid (hook_list, hook, may_recurse);
}
}
void
g_hook_list_marshal (GHookList *hook_list,
gboolean may_recurse,
GHookMarshaller marshaller,
gpointer data)
{
GHook *hook;
g_return_if_fail (hook_list != NULL);
g_return_if_fail (hook_list->is_setup);
g_return_if_fail (marshaller != NULL);
hook = g_hook_first_valid (hook_list, may_recurse);
while (hook)
{
gboolean was_in_call;
was_in_call = G_HOOK_IN_CALL (hook);
hook->flags |= G_HOOK_FLAG_IN_CALL;
marshaller (hook, data);
if (!was_in_call)
hook->flags &= ~G_HOOK_FLAG_IN_CALL;
hook = g_hook_next_valid (hook_list, hook, may_recurse);
}
}
GHook*
g_hook_first_valid (GHookList *hook_list,
gboolean may_be_in_call)
{
g_return_val_if_fail (hook_list != NULL, NULL);
if (hook_list->is_setup)
{
GHook *hook;
hook = hook_list->hooks;
if (hook)
{
g_hook_ref (hook_list, hook);
if (G_HOOK_IS_VALID (hook) && (may_be_in_call || !G_HOOK_IN_CALL (hook)))
return hook;
else
return g_hook_next_valid (hook_list, hook, may_be_in_call);
}
}
return NULL;
}
GHook*
g_hook_next_valid (GHookList *hook_list,
GHook *hook,
gboolean may_be_in_call)
{
GHook *ohook = hook;
g_return_val_if_fail (hook_list != NULL, NULL);
if (!hook)
return NULL;
hook = hook->next;
while (hook)
{
if (G_HOOK_IS_VALID (hook) && (may_be_in_call || !G_HOOK_IN_CALL (hook)))
{
g_hook_ref (hook_list, hook);
g_hook_unref (hook_list, ohook);
return hook;
}
hook = hook->next;
}
g_hook_unref (hook_list, ohook);
return NULL;
}
GHook*
g_hook_get (GHookList *hook_list,
gulong hook_id)
{
GHook *hook;
g_return_val_if_fail (hook_list != NULL, NULL);
g_return_val_if_fail (hook_id > 0, NULL);
hook = hook_list->hooks;
while (hook)
{
if (hook->hook_id == hook_id)
return hook;
hook = hook->next;
}
return NULL;
}
GHook*
g_hook_find (GHookList *hook_list,
gboolean need_valids,
GHookFindFunc func,
gpointer data)
{
GHook *hook;
g_return_val_if_fail (hook_list != NULL, NULL);
g_return_val_if_fail (func != NULL, NULL);
hook = hook_list->hooks;
while (hook)
{
GHook *tmp;
/* test only non-destroyed hooks */
if (!hook->hook_id)
{
hook = hook->next;
continue;
}
g_hook_ref (hook_list, hook);
if (func (hook, data) && hook->hook_id && (!need_valids || G_HOOK_ACTIVE (hook)))
{
g_hook_unref (hook_list, hook);
return hook;
}
tmp = hook->next;
g_hook_unref (hook_list, hook);
hook = tmp;
}
return NULL;
}
GHook*
g_hook_find_data (GHookList *hook_list,
gboolean need_valids,
gpointer data)
{
GHook *hook;
g_return_val_if_fail (hook_list != NULL, NULL);
hook = hook_list->hooks;
while (hook)
{
/* test only non-destroyed hooks */
if (hook->data == data &&
hook->hook_id &&
(!need_valids || G_HOOK_ACTIVE (hook)))
return hook;
hook = hook->next;
}
return NULL;
}
GHook*
g_hook_find_func (GHookList *hook_list,
gboolean need_valids,
gpointer func)
{
GHook *hook;
g_return_val_if_fail (hook_list != NULL, NULL);
g_return_val_if_fail (func != NULL, NULL);
hook = hook_list->hooks;
while (hook)
{
/* test only non-destroyed hooks */
if (hook->func == func &&
hook->hook_id &&
(!need_valids || G_HOOK_ACTIVE (hook)))
return hook;
hook = hook->next;
}
return NULL;
}
GHook*
g_hook_find_func_data (GHookList *hook_list,
gboolean need_valids,
gpointer func,
gpointer data)
{
GHook *hook;
g_return_val_if_fail (hook_list != NULL, NULL);
g_return_val_if_fail (func != NULL, NULL);
hook = hook_list->hooks;
while (hook)
{
/* test only non-destroyed hooks */
if (hook->data == data &&
hook->func == func &&
hook->hook_id &&
(!need_valids || G_HOOK_ACTIVE (hook)))
return hook;
hook = hook->next;
}
return NULL;
}
void
g_hook_insert_sorted (GHookList *hook_list,
GHook *hook,
GHookCompareFunc func)
{
GHook *sibling;
g_return_if_fail (hook_list != NULL);
g_return_if_fail (hook_list->is_setup);
g_return_if_fail (hook != NULL);
g_return_if_fail (G_HOOK_IS_UNLINKED (hook));
g_return_if_fail (hook->func != NULL);
g_return_if_fail (func != NULL);
/* first non-destroyed hook */
sibling = hook_list->hooks;
while (sibling && !sibling->hook_id)
sibling = sibling->next;
while (sibling)
{
GHook *tmp;
g_hook_ref (hook_list, sibling);
if (func (hook, sibling) <= 0 && sibling->hook_id)
{
g_hook_unref (hook_list, sibling);
break;
}
/* next non-destroyed hook */
tmp = sibling->next;
while (tmp && !tmp->hook_id)
tmp = tmp->next;
g_hook_unref (hook_list, sibling);
sibling = tmp;
}
g_hook_insert_before (hook_list, sibling, hook);
}
gint
g_hook_compare_ids (GHook *new_hook,
GHook *sibling)
{
if (new_hook->hook_id < sibling->hook_id)
return -1;
else if (new_hook->hook_id > sibling->hook_id)
return 1;
return 0;
}

177
ghook.h
View File

@ -1,177 +0,0 @@
/* 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 Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
#ifndef __G_HOOK_H__
#define __G_HOOK_H__
#include <gmem.h>
G_BEGIN_DECLS
/* --- typedefs --- */
typedef struct _GHook GHook;
typedef struct _GHookList GHookList;
typedef gint (*GHookCompareFunc) (GHook *new_hook,
GHook *sibling);
typedef gboolean (*GHookFindFunc) (GHook *hook,
gpointer data);
typedef void (*GHookMarshaller) (GHook *hook,
gpointer marshal_data);
typedef gboolean (*GHookCheckMarshaller) (GHook *hook,
gpointer marshal_data);
typedef void (*GHookFunc) (gpointer data);
typedef gboolean (*GHookCheckFunc) (gpointer data);
typedef void (*GHookFinalizeFunc) (GHookList *hook_list,
GHook *hook);
typedef enum
{
G_HOOK_FLAG_ACTIVE = 1 << 0,
G_HOOK_FLAG_IN_CALL = 1 << 1,
G_HOOK_FLAG_MASK = 0x0f
} GHookFlagMask;
#define G_HOOK_FLAG_USER_SHIFT (4)
/* --- structures --- */
struct _GHookList
{
gulong seq_id;
guint hook_size : 16;
guint is_setup : 1;
GHook *hooks;
GMemChunk *hook_memchunk;
GHookFinalizeFunc finalize_hook;
};
struct _GHook
{
gpointer data;
GHook *next;
GHook *prev;
guint ref_count;
gulong hook_id;
guint flags;
gpointer func;
GDestroyNotify destroy;
};
/* --- macros --- */
#define G_HOOK(hook) ((GHook*) (hook))
#define G_HOOK_FLAGS(hook) (G_HOOK (hook)->flags)
#define G_HOOK_ACTIVE(hook) ((G_HOOK_FLAGS (hook) & \
G_HOOK_FLAG_ACTIVE) != 0)
#define G_HOOK_IN_CALL(hook) ((G_HOOK_FLAGS (hook) & \
G_HOOK_FLAG_IN_CALL) != 0)
#define G_HOOK_IS_VALID(hook) (G_HOOK (hook)->hook_id != 0 && \
(G_HOOK_FLAGS (hook) & \
G_HOOK_FLAG_ACTIVE))
#define G_HOOK_IS_UNLINKED(hook) (G_HOOK (hook)->next == NULL && \
G_HOOK (hook)->prev == NULL && \
G_HOOK (hook)->hook_id == 0 && \
G_HOOK (hook)->ref_count == 0)
/* --- prototypes --- */
/* callback mainenance functions */
void g_hook_list_init (GHookList *hook_list,
guint hook_size);
void g_hook_list_clear (GHookList *hook_list);
GHook* g_hook_alloc (GHookList *hook_list);
void g_hook_free (GHookList *hook_list,
GHook *hook);
void g_hook_ref (GHookList *hook_list,
GHook *hook);
void g_hook_unref (GHookList *hook_list,
GHook *hook);
gboolean g_hook_destroy (GHookList *hook_list,
gulong hook_id);
void g_hook_destroy_link (GHookList *hook_list,
GHook *hook);
void g_hook_prepend (GHookList *hook_list,
GHook *hook);
void g_hook_insert_before (GHookList *hook_list,
GHook *sibling,
GHook *hook);
void g_hook_insert_sorted (GHookList *hook_list,
GHook *hook,
GHookCompareFunc func);
GHook* g_hook_get (GHookList *hook_list,
gulong hook_id);
GHook* g_hook_find (GHookList *hook_list,
gboolean need_valids,
GHookFindFunc func,
gpointer data);
GHook* g_hook_find_data (GHookList *hook_list,
gboolean need_valids,
gpointer data);
GHook* g_hook_find_func (GHookList *hook_list,
gboolean need_valids,
gpointer func);
GHook* g_hook_find_func_data (GHookList *hook_list,
gboolean need_valids,
gpointer func,
gpointer data);
/* return the first valid hook, and increment its reference count */
GHook* g_hook_first_valid (GHookList *hook_list,
gboolean may_be_in_call);
/* return the next valid hook with incremented reference count, and
* decrement the reference count of the original hook
*/
GHook* g_hook_next_valid (GHookList *hook_list,
GHook *hook,
gboolean may_be_in_call);
/* GHookCompareFunc implementation to insert hooks sorted by their id */
gint g_hook_compare_ids (GHook *new_hook,
GHook *sibling);
/* convenience macros */
#define g_hook_append( hook_list, hook ) \
g_hook_insert_before ((hook_list), NULL, (hook))
/* invoke all valid hooks with the (*GHookFunc) signature.
*/
void g_hook_list_invoke (GHookList *hook_list,
gboolean may_recurse);
/* invoke all valid hooks with the (*GHookCheckFunc) signature,
* and destroy the hook if FALSE is returned.
*/
void g_hook_list_invoke_check (GHookList *hook_list,
gboolean may_recurse);
/* invoke a marshaller on all valid hooks.
*/
void g_hook_list_marshal (GHookList *hook_list,
gboolean may_recurse,
GHookMarshaller marshaller,
gpointer marshal_data);
void g_hook_list_marshal_check (GHookList *hook_list,
gboolean may_recurse,
GHookCheckMarshaller marshaller,
gpointer marshal_data);
G_END_DECLS
#endif /* __G_HOOK_H__ */

View File

@ -1,148 +0,0 @@
/* GLIB - Library of useful routines for C programming
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* giochannel.c: IO Channel abstraction
* Copyright 1998 Owen Taylor
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
/*
* MT safe
*/
#include "config.h"
#include "glib.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
void
g_io_channel_init (GIOChannel *channel)
{
channel->channel_flags = 0;
channel->ref_count = 1;
}
void
g_io_channel_ref (GIOChannel *channel)
{
g_return_if_fail (channel != NULL);
channel->ref_count++;
}
void
g_io_channel_unref (GIOChannel *channel)
{
g_return_if_fail (channel != NULL);
channel->ref_count--;
if (channel->ref_count == 0)
channel->funcs->io_free (channel);
}
GIOError
g_io_channel_read (GIOChannel *channel,
gchar *buf,
guint count,
guint *bytes_read)
{
g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN);
return channel->funcs->io_read (channel, buf, count, bytes_read);
}
GIOError
g_io_channel_write (GIOChannel *channel,
gchar *buf,
guint count,
guint *bytes_written)
{
g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN);
return channel->funcs->io_write (channel, buf, count, bytes_written);
}
GIOError
g_io_channel_seek (GIOChannel *channel,
gint offset,
GSeekType type)
{
g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN);
return channel->funcs->io_seek (channel, offset, type);
}
void
g_io_channel_close (GIOChannel *channel)
{
g_return_if_fail (channel != NULL);
channel->funcs->io_close (channel);
}
GSource *
g_io_create_watch (GIOChannel *channel,
GIOCondition condition)
{
g_return_val_if_fail (channel != NULL, NULL);
return channel->funcs->io_create_watch (channel, condition);
}
guint
g_io_add_watch_full (GIOChannel *channel,
gint priority,
GIOCondition condition,
GIOFunc func,
gpointer user_data,
GDestroyNotify notify)
{
GSource *source;
guint id;
g_return_val_if_fail (channel != NULL, 0);
source = g_io_create_watch (channel, condition);
if (priority != G_PRIORITY_DEFAULT)
g_source_set_priority (source, priority);
g_source_set_callback (source, (GSourceFunc)func, user_data, notify);
id = g_source_attach (source, NULL);
g_source_unref (source);
return id;
}
guint
g_io_add_watch (GIOChannel *channel,
GIOCondition condition,
GIOFunc func,
gpointer user_data)
{
return g_io_add_watch_full (channel, G_PRIORITY_DEFAULT, condition, func, user_data, NULL);
}

View File

@ -1,197 +0,0 @@
/* 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 Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
#ifndef __G_IOCHANNEL_H__
#define __G_IOCHANNEL_H__
#include <gmain.h>
#include <gtypes.h>
G_BEGIN_DECLS
/* GIOChannel
*/
typedef struct _GIOChannel GIOChannel;
typedef struct _GIOFuncs GIOFuncs;
typedef enum
{
G_IO_ERROR_NONE,
G_IO_ERROR_AGAIN,
G_IO_ERROR_INVAL,
G_IO_ERROR_UNKNOWN
} GIOError;
typedef enum
{
G_SEEK_CUR,
G_SEEK_SET,
G_SEEK_END
} GSeekType;
typedef enum
{
G_IO_IN GLIB_SYSDEF_POLLIN,
G_IO_OUT GLIB_SYSDEF_POLLOUT,
G_IO_PRI GLIB_SYSDEF_POLLPRI,
G_IO_ERR GLIB_SYSDEF_POLLERR,
G_IO_HUP GLIB_SYSDEF_POLLHUP,
G_IO_NVAL GLIB_SYSDEF_POLLNVAL
} GIOCondition;
struct _GIOChannel
{
guint channel_flags;
guint ref_count;
GIOFuncs *funcs;
};
typedef gboolean (*GIOFunc) (GIOChannel *source,
GIOCondition condition,
gpointer data);
struct _GIOFuncs
{
GIOError (*io_read) (GIOChannel *channel,
gchar *buf,
guint count,
guint *bytes_read);
GIOError (*io_write) (GIOChannel *channel,
gchar *buf,
guint count,
guint *bytes_written);
GIOError (*io_seek) (GIOChannel *channel,
gint offset,
GSeekType type);
void (*io_close) (GIOChannel *channel);
GSource * (*io_create_watch) (GIOChannel *channel,
GIOCondition condition);
void (*io_free) (GIOChannel *channel);
};
void g_io_channel_init (GIOChannel *channel);
void g_io_channel_ref (GIOChannel *channel);
void g_io_channel_unref (GIOChannel *channel);
GIOError g_io_channel_read (GIOChannel *channel,
gchar *buf,
guint count,
guint *bytes_read);
GIOError g_io_channel_write (GIOChannel *channel,
gchar *buf,
guint count,
guint *bytes_written);
GIOError g_io_channel_seek (GIOChannel *channel,
gint offset,
GSeekType type);
void g_io_channel_close (GIOChannel *channel);
guint g_io_add_watch_full (GIOChannel *channel,
gint priority,
GIOCondition condition,
GIOFunc func,
gpointer user_data,
GDestroyNotify notify);
GSource *g_io_create_watch (GIOChannel *channel,
GIOCondition condition);
guint g_io_add_watch (GIOChannel *channel,
GIOCondition condition,
GIOFunc func,
gpointer user_data);
/* On Unix, IO channels created with this function for any file
* descriptor or socket.
*
* On Win32, this can be used either for files opened with the MSVCRT
* (the Microsoft run-time C library) _open() or _pipe, including file
* descriptors 0, 1 and 2 (corresponding to stdin, stdout and stderr),
* or for Winsock SOCKETs. If the parameter is a legal file
* descriptor, it is assumed to be such, otherwise it should be a
* SOCKET. This relies on SOCKETs and file descriptors not
* overlapping. If you want to be certain, call either
* g_io_channel_win32_new_fd() or g_io_channel_win32_new_socket()
* instead as appropriate.
*
* The term file descriptor as used in the context of Win32 refers to
* the emulated Unix-like file descriptors MSVCRT provides. The native
* corresponding concept is file HANDLE. There isn't as of yet a way to
* get GIOChannels for Win32 file HANDLEs.
*/
GIOChannel* g_io_channel_unix_new (int fd);
gint g_io_channel_unix_get_fd (GIOChannel *channel);
#ifdef G_OS_WIN32
#define G_WIN32_MSG_HANDLE 19981206
/* Use this to get a GPollFD from a GIOChannel, so that you can call
* g_io_channel_win32_poll(). After calling this you should only use
* g_io_channel_read() to read from the GIOChannel, i.e. never read()
* from the underlying file descriptor. For SOCKETs, it is possible to call
* recv().
*/
void g_io_channel_win32_make_pollfd (GIOChannel *channel,
GIOCondition condition,
GPollFD *fd);
/* This can be used to wait a until at least one of the channels is readable.
* On Unix you would do a select() on the file descriptors of the channels.
*/
gint g_io_channel_win32_poll (GPollFD *fds,
gint n_fds,
gint timeout);
/* This is used to add polling for Windows messages. GDK (GTk+) programs
* should *not* use this.
*/
void g_main_poll_win32_msg_add (gint priority,
GPollFD *fd,
guint hwnd);
/* Create an IO channel for Windows messages for window handle hwnd. */
GIOChannel *g_io_channel_win32_new_messages (guint hwnd);
/* Create an IO channel for C runtime (emulated Unix-like) file
* descriptors. After calling g_io_add_watch() on a IO channel
* returned by this function, you shouldn't call read() on the file
* descriptor. This is because adding polling for a file descriptor is
* implemented on Win32 by starting a thread that sits blocked in a
* read() from the file descriptor most of the time. All reads from
* the file descriptor should be done by this internal GLib
* thread. Your code should call only g_io_channel_read().
*/
GIOChannel* g_io_channel_win32_new_fd (int fd);
/* Get the C runtime file descriptor of a channel. */
gint g_io_channel_win32_get_fd (GIOChannel *channel);
/* Create an IO channel for a winsock socket. The parameter should be
* a SOCKET. Contrary to IO channels for file descriptors (on *Win32),
* you can use normal recv() or recvfrom() on sockets even if GLib
* is polling them.
*/
GIOChannel *g_io_channel_win32_new_socket (gint socket);
#endif
G_END_DECLS
#endif /* __G_IOCHANNEL_H__ */

312
giounix.c
View File

@ -1,312 +0,0 @@
/* GLIB - Library of useful routines for C programming
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* giounix.c: IO Channels using unix file descriptors
* Copyright 1998 Owen Taylor
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
/*
* MT safe
*/
#include "glib.h"
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
/*
* Unix IO Channels
*/
typedef struct _GIOUnixChannel GIOUnixChannel;
typedef struct _GIOUnixWatch GIOUnixWatch;
struct _GIOUnixChannel
{
GIOChannel channel;
gint fd;
};
struct _GIOUnixWatch
{
GSource source;
GPollFD pollfd;
GIOChannel *channel;
GIOCondition condition;
GIOFunc callback;
};
static GIOError g_io_unix_read (GIOChannel *channel,
gchar *buf,
guint count,
guint *bytes_written);
static GIOError g_io_unix_write (GIOChannel *channel,
gchar *buf,
guint count,
guint *bytes_written);
static GIOError g_io_unix_seek (GIOChannel *channel,
gint offset,
GSeekType type);
static void g_io_unix_close (GIOChannel *channel);
static void g_io_unix_free (GIOChannel *channel);
static GSource *g_io_unix_create_watch (GIOChannel *channel,
GIOCondition condition);
static gboolean g_io_unix_prepare (GSource *source,
gint *timeout);
static gboolean g_io_unix_check (GSource *source);
static gboolean g_io_unix_dispatch (GSource *source,
GSourceFunc callback,
gpointer user_data);
static void g_io_unix_destroy (GSource *source);
GSourceFuncs unix_watch_funcs = {
g_io_unix_prepare,
g_io_unix_check,
g_io_unix_dispatch,
g_io_unix_destroy
};
GIOFuncs unix_channel_funcs = {
g_io_unix_read,
g_io_unix_write,
g_io_unix_seek,
g_io_unix_close,
g_io_unix_create_watch,
g_io_unix_free,
};
static gboolean
g_io_unix_prepare (GSource *source,
gint *timeout)
{
*timeout = -1;
return FALSE;
}
static gboolean
g_io_unix_check (GSource *source)
{
GIOUnixWatch *watch = (GIOUnixWatch *)source;
return (watch->pollfd.revents & watch->condition);
}
static gboolean
g_io_unix_dispatch (GSource *source,
GSourceFunc callback,
gpointer user_data)
{
GIOFunc func = (GIOFunc)callback;
GIOUnixWatch *watch = (GIOUnixWatch *)source;
if (!func)
{
g_warning ("IO watch dispatched without callback\n"
"You must call g_source_connect().");
return FALSE;
}
return (*func) (watch->channel,
watch->pollfd.revents & watch->condition,
user_data);
}
static void
g_io_unix_destroy (GSource *source)
{
GIOUnixWatch *watch = (GIOUnixWatch *)source;
g_io_channel_unref (watch->channel);
}
static GIOError
g_io_unix_read (GIOChannel *channel,
gchar *buf,
guint count,
guint *bytes_read)
{
GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
gint result;
result = read (unix_channel->fd, buf, count);
if (result < 0)
{
*bytes_read = 0;
switch (errno)
{
case EINVAL:
return G_IO_ERROR_INVAL;
case EAGAIN:
case EINTR:
return G_IO_ERROR_AGAIN;
default:
return G_IO_ERROR_UNKNOWN;
}
}
else
{
*bytes_read = result;
return G_IO_ERROR_NONE;
}
}
static GIOError
g_io_unix_write(GIOChannel *channel,
gchar *buf,
guint count,
guint *bytes_written)
{
GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
gint result;
result = write (unix_channel->fd, buf, count);
if (result < 0)
{
*bytes_written = 0;
switch (errno)
{
case EINVAL:
return G_IO_ERROR_INVAL;
case EAGAIN:
case EINTR:
return G_IO_ERROR_AGAIN;
default:
return G_IO_ERROR_UNKNOWN;
}
}
else
{
*bytes_written = result;
return G_IO_ERROR_NONE;
}
}
static GIOError
g_io_unix_seek (GIOChannel *channel,
gint offset,
GSeekType type)
{
GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
int whence;
off_t result;
switch (type)
{
case G_SEEK_SET:
whence = SEEK_SET;
break;
case G_SEEK_CUR:
whence = SEEK_CUR;
break;
case G_SEEK_END:
whence = SEEK_END;
break;
default:
g_warning ("g_io_unix_seek: unknown seek type");
return G_IO_ERROR_UNKNOWN;
}
result = lseek (unix_channel->fd, offset, whence);
if (result < 0)
{
switch (errno)
{
case EINVAL:
return G_IO_ERROR_INVAL;
default:
return G_IO_ERROR_UNKNOWN;
}
}
else
return G_IO_ERROR_NONE;
}
static void
g_io_unix_close (GIOChannel *channel)
{
GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
close (unix_channel->fd);
}
static void
g_io_unix_free (GIOChannel *channel)
{
GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
g_free (unix_channel);
}
static GSource *
g_io_unix_create_watch (GIOChannel *channel,
GIOCondition condition)
{
GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
GSource *source;
GIOUnixWatch *watch;
source = g_source_new (&unix_watch_funcs, sizeof (GIOUnixWatch));
watch = (GIOUnixWatch *)source;
watch->channel = channel;
g_io_channel_ref (channel);
watch->condition = condition;
watch->pollfd.fd = unix_channel->fd;
watch->pollfd.events = condition;
g_source_add_poll (source, &watch->pollfd);
return source;
}
GIOChannel *
g_io_channel_unix_new (gint fd)
{
GIOUnixChannel *unix_channel = g_new (GIOUnixChannel, 1);
GIOChannel *channel = (GIOChannel *)unix_channel;
g_io_channel_init (channel);
channel->funcs = &unix_channel_funcs;
unix_channel->fd = fd;
return channel;
}
gint
g_io_channel_unix_get_fd (GIOChannel *channel)
{
GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
return unix_channel->fd;
}

1179
giowin32.c

File diff suppressed because it is too large Load Diff

View File

@ -1,38 +0,0 @@
/* GObject - GLib Type, Object, Parameter and Signal Library
* Copyright (C) 1998, 1999, 2000 Tim Janik and Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
#ifndef __GLIB_GOBJECT_H__
#define __GLIB_GOBJECT_H__
/* topmost include file for GObject header files */
#include <gobject/gboxed.h>
#include <gobject/gbsearcharray.h>
#include <gobject/genums.h>
#include <gobject/gobject.h>
#include <gobject/gparam.h>
#include <gobject/gparamspecs.h>
#include <gobject/gsignal.h>
#include <gobject/gtype.h>
#include <gobject/gtypemodule.h>
#include <gobject/gtypeplugin.h>
#include <gobject/gvalue.h>
#include <gobject/gvaluearray.h>
#include <gobject/gvaluetypes.h>
#endif /* __GLIB_GOBJECT_H__ */

75
glib.h
View File

@ -1,75 +0,0 @@
/* 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 Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
#ifndef __G_LIB_H__
#define __G_LIB_H__
#include <galloca.h>
#include <garray.h>
#include <gasyncqueue.h>
#include <gbacktrace.h>
#include <gcache.h>
#include <gcompletion.h>
#include <gconvert.h>
#include <gdataset.h>
#include <gdate.h>
#include <gerror.h>
#include <gfileutils.h>
#include <ghash.h>
#include <ghook.h>
#include <giochannel.h>
#include <glist.h>
#include <gmacros.h>
#include <gmain.h>
#include <gmarkup.h>
#include <gmem.h>
#include <gmessages.h>
#include <gnode.h>
#include <gpattern.h>
#include <gprimes.h>
#include <gqsort.h>
#include <gquark.h>
#include <gqueue.h>
#include <grand.h>
#include <grel.h>
#include <gscanner.h>
#include <gshell.h>
#include <gslist.h>
#include <gspawn.h>
#include <gstrfuncs.h>
#include <gstring.h>
#include <gthread.h>
#include <gthreadpool.h>
#include <gtimer.h>
#include <gtree.h>
#include <gtypes.h>
#include <gunicode.h>
#include <gutils.h>
#ifdef G_PLATFORM_WIN32
#include <gwin32.h>
#endif
#endif /* __G_LIB_H__ */

10
glib/.cvsignore Normal file
View File

@ -0,0 +1,10 @@
Makefile
Makefile.in
libglib-1.3.la
*.lo
*.obj
*.lib
*.dll
*.exe
.deps
.libs

View File

@ -1,46 +1,11 @@
## Process this file with automake to produce Makefile.in
AUTOMAKE_OPTIONS = 1.4
SUBDIRS = . m4macros gobject gmodule gthread docs tests build
INCLUDES = -DG_LOG_DOMAIN=g_log_domain_glib @GLIB_DEBUG_FLAGS@ \
-DG_DISABLE_DEPRECATED -DGLIB_COMPILATION
EXTRA_DIST = \
ChangeLog.pre-1-2 \
glib.spec.in \
NEWS.pre-1-3 \
acglib.m4 \
sanity_check \
README.win32 \
TODO.xml \
glib.def \
makefile.msc.in \
makefile.mingw.in \
glibconfig.h.win32.in \
config.h.win32.in \
build-dll \
glib.rc.in \
glib-2.0.pc.in \
gobject-2.0.pc.in \
gmodule-2.0.pc.in \
gthread-2.0.pc.in \
glib-2.0-uninstalled.pc.in \
gobject-2.0-uninstalled.pc.in \
gmodule-2.0-uninstalled.pc.in \
gthread-2.0-uninstalled.pc.in \
gen-unicode-tables.pl
# These may be in the builddir too
BUILT_EXTRA_DIST = \
makefile.msc \
makefile.mingw \
glibconfig.h.win32 \
config.h.win32 \
glib.rc \
glib.spec
lib_LTLIBRARIES = libglib-1.3.la
libglib_1_3_la_SOURCES = \
@ -97,6 +62,11 @@ EXTRA_libglib_1_3_la_SOURCES = \
glibincludedir=$(includedir)/glib-2.0
glibinclude_HEADERS = \
glib-object.h \
glib.h
glibsubincludedir=$(includedir)/glib-2.0/glib
glibsubinclude_HEADERS = \
galloca.h \
garray.h \
gasyncqueue.h \
@ -111,8 +81,6 @@ glibinclude_HEADERS = \
ghash.h \
ghook.h \
giochannel.h \
glib.h \
glib-object.h \
glist.h \
gmacros.h \
gmain.h \
@ -142,24 +110,12 @@ glibinclude_HEADERS = \
gutils.h \
gwin32.h
configexecincludedir = $(libdir)/glib-2.0/include
#configexecinclude_DATA = glibconfig.h
install-exec-local: glibconfig.h
$(mkinstalldirs) $(DESTDIR)$(configexecincludedir)
file=$(DESTDIR)$(configexecincludedir)/glibconfig.h; \
if test -r $$file && cmp -s glibconfig.h $$file; then :; \
else $(INSTALL_DATA) glibconfig.h $$file; fi
CONFIGURE_DEPENDENCIES = acglib.m4
BUILT_SOURCES = stamp-gc-h #note: not glibconfig.h
glibconfig.h: stamp-gc-h
@if test -f glibconfig.h; then :; \
else rm -f stamp-gc-h; $(MAKE) stamp-gc-h; fi
stamp-gc-h: config.status
CONFIG_FILES= CONFIG_HEADERS= CONFIG_OTHER=glibconfig.h ./config.status
echo timestamp > stamp-gc-h
install-data-local:
@if test -f $(glibincludedir)/glist.h ; then \
echo "*** Old headers found in $(glibincludedir). You should remove the" ; \
echo "*** contents of this directory and type 'make install' again." ; \
false ; \
fi
libglib_1_3_la_LIBADD = @GIO@ @GSPAWN@ @PLATFORMDEP@ @ICONV_LIBS@ @G_LIBS_EXTRA@
libglib_1_3_la_DEPENDENCIES = @GIO@ @GSPAWN@ @PLATFORMDEP@
@ -181,63 +137,4 @@ if OS_WIN32
bin_PROGRAMS = gspawn-win32-helper
gspawn_win32_helper_LDADD = libglib-1.3.la
endif
if ENABLE_TIMELOOP
timeloop = timeloop
endif
noinst_PROGRAMS = testglib testgdate testgdateparser $(timeloop)
testglib_LDADD = libglib-1.3.la
testgdate_LDADD = libglib-1.3.la
testgdateparser_LDADD = libglib-1.3.la
if ENABLE_TIMELOOP
timeloop_LDADD = libglib-1.3.la
endif
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = glib-2.0.pc gobject-2.0.pc gmodule-2.0.pc gthread-2.0.pc
glibconfig.h.win32: $(top_builddir)/config.status $(top_srcdir)/glibconfig.h.win32.in
cd $(top_builddir) && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
config.h.win32: $(top_builddir)/config.status $(top_srcdir)/config.h.win32.in
cd $(top_builddir) && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
makefile.msc: $(top_builddir)/config.status $(top_srcdir)/makefile.msc.in
cd $(top_builddir) && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
makefile.mingw: $(top_builddir)/config.status $(top_srcdir)/makefile.mingw.in
cd $(top_builddir) && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
glib.rc: $(top_builddir)/config.status $(top_srcdir)/glib.rc.in
cd $(top_builddir) && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
bin_SCRIPTS=glib-config-2.0
BUILT_SOURCES=glib-config-2.0
glib-config-2.0: glib-config-2.0.in
.PHONY: files release sanity snapshot
files:
@files=`ls $(DISTFILES) 2> /dev/null `; for p in $$files; do \
echo $$p; \
done
release:
rm -rf .deps */.deps
cd docs && make glib.html
$(MAKE) distcheck
sanity:
./sanity_check $(VERSION)
snapshot:
$(MAKE) dist distdir=$(PACKAGE)-snap`date +"%Y%m%d"`
snapcheck:
$(MAKE) distcheck distdir=$(PACKAGE)-snap`date +"%Y%m%d"`
dist-hook: $(BUILT_EXTRA_DIST)
cd $(top_builddir) && CONFIG_FILES="INSTALL README" CONFIG_HEADERS= $(SHELL) ./config.status
files='$(BUILT_EXTRA_DIST) INSTALL README'; \
for f in $$files; do \
if test -f $$f; then d=.; else d=$(srcdir); fi; \
rm -f $(distdir)/$$f && cp $$d/$$f $(distdir) || exit 1; done

View File

@ -27,7 +27,7 @@
#ifndef __G_ALLOCA_H__
#define __G_ALLOCA_H__
#include <gtypes.h>
#include <glib/gtypes.h>
#ifdef __GNUC__
/* GCC does the right thing */

View File

@ -27,7 +27,7 @@
#ifndef __G_ARRAY_H__
#define __G_ARRAY_H__
#include <gtypes.h>
#include <glib/gtypes.h>
G_BEGIN_DECLS

View File

@ -27,7 +27,7 @@
#ifndef __G_ASYNCQUEUE_H__
#define __G_ASYNCQUEUE_H__
#include <gthread.h>
#include <glib/gthread.h>
G_BEGIN_DECLS

View File

@ -27,7 +27,7 @@
#ifndef __G_BACKTRACE_H__
#define __G_BACKTRACE_H__
#include <gtypes.h>
#include <glib/gtypes.h>
G_BEGIN_DECLS

View File

@ -27,7 +27,7 @@
#ifndef __G_CACHE_H__
#define __G_CACHE_H__
#include <glist.h>
#include <glib/glist.h>
G_BEGIN_DECLS

View File

@ -27,7 +27,7 @@
#ifndef __G_COMPLETION_H__
#define __G_COMPLETION_H__
#include <glist.h>
#include <glib/glist.h>
G_BEGIN_DECLS

View File

@ -28,7 +28,7 @@
#define __G_CONVERT_H__
#include <stddef.h> /* For size_t */
#include <gerror.h>
#include <glib/gerror.h>
G_BEGIN_DECLS

View File

@ -27,7 +27,7 @@
#ifndef __G_DATASET_H__
#define __G_DATASET_H__
#include <gquark.h>
#include <glib/gquark.h>
G_BEGIN_DECLS

View File

@ -27,7 +27,7 @@
#ifndef __G_DATE_H__
#define __G_DATE_H__
#include <gquark.h>
#include <glib/gquark.h>
G_BEGIN_DECLS

View File

@ -21,7 +21,7 @@
#ifndef __G_ERROR_H__
#define __G_ERROR_H__
#include <gquark.h>
#include <glib/gquark.h>
G_BEGIN_DECLS

View File

@ -21,7 +21,7 @@
#ifndef __G_FILEUTILS_H__
#define __G_FILEUTILS_H__
#include <gerror.h>
#include <glib/gerror.h>
G_BEGIN_DECLS

View File

@ -27,7 +27,7 @@
#ifndef __G_HASH_H__
#define __G_HASH_H__
#include <gtypes.h>
#include <glib/gtypes.h>
G_BEGIN_DECLS

View File

@ -27,7 +27,7 @@
#ifndef __G_HOOK_H__
#define __G_HOOK_H__
#include <gmem.h>
#include <glib/gmem.h>
G_BEGIN_DECLS

View File

@ -27,8 +27,8 @@
#ifndef __G_IOCHANNEL_H__
#define __G_IOCHANNEL_H__
#include <gmain.h>
#include <gtypes.h>
#include <glib/gmain.h>
#include <glib/gtypes.h>
G_BEGIN_DECLS

View File

@ -27,49 +27,49 @@
#ifndef __G_LIB_H__
#define __G_LIB_H__
#include <galloca.h>
#include <garray.h>
#include <gasyncqueue.h>
#include <gbacktrace.h>
#include <gcache.h>
#include <gcompletion.h>
#include <gconvert.h>
#include <gdataset.h>
#include <gdate.h>
#include <gerror.h>
#include <gfileutils.h>
#include <ghash.h>
#include <ghook.h>
#include <giochannel.h>
#include <glist.h>
#include <gmacros.h>
#include <gmain.h>
#include <gmarkup.h>
#include <gmem.h>
#include <gmessages.h>
#include <gnode.h>
#include <gpattern.h>
#include <gprimes.h>
#include <gqsort.h>
#include <gquark.h>
#include <gqueue.h>
#include <grand.h>
#include <grel.h>
#include <gscanner.h>
#include <gshell.h>
#include <gslist.h>
#include <gspawn.h>
#include <gstrfuncs.h>
#include <gstring.h>
#include <gthread.h>
#include <gthreadpool.h>
#include <gtimer.h>
#include <gtree.h>
#include <gtypes.h>
#include <gunicode.h>
#include <gutils.h>
#include <glib/galloca.h>
#include <glib/garray.h>
#include <glib/gasyncqueue.h>
#include <glib/gbacktrace.h>
#include <glib/gcache.h>
#include <glib/gcompletion.h>
#include <glib/gconvert.h>
#include <glib/gdataset.h>
#include <glib/gdate.h>
#include <glib/gerror.h>
#include <glib/gfileutils.h>
#include <glib/ghash.h>
#include <glib/ghook.h>
#include <glib/giochannel.h>
#include <glib/glist.h>
#include <glib/gmacros.h>
#include <glib/gmain.h>
#include <glib/gmarkup.h>
#include <glib/gmem.h>
#include <glib/gmessages.h>
#include <glib/gnode.h>
#include <glib/gpattern.h>
#include <glib/gprimes.h>
#include <glib/gqsort.h>
#include <glib/gquark.h>
#include <glib/gqueue.h>
#include <glib/grand.h>
#include <glib/grel.h>
#include <glib/gscanner.h>
#include <glib/gshell.h>
#include <glib/gslist.h>
#include <glib/gspawn.h>
#include <glib/gstrfuncs.h>
#include <glib/gstring.h>
#include <glib/gthread.h>
#include <glib/gthreadpool.h>
#include <glib/gtimer.h>
#include <glib/gtree.h>
#include <glib/gtypes.h>
#include <glib/gunicode.h>
#include <glib/gutils.h>
#ifdef G_PLATFORM_WIN32
#include <gwin32.h>
#include <glib/gwin32.h>
#endif
#endif /* __G_LIB_H__ */

View File

@ -27,7 +27,7 @@
#ifndef __G_LIST_H__
#define __G_LIST_H__
#include <gmem.h>
#include <glib/gmem.h>
G_BEGIN_DECLS

View File

@ -20,8 +20,8 @@
#ifndef __G_MAIN_H__
#define __G_MAIN_H__
#include <gslist.h>
#include <gthread.h>
#include <glib/gslist.h>
#include <glib/gthread.h>
G_BEGIN_DECLS

View File

@ -21,7 +21,7 @@
#ifndef __G_MARKUP_H__
#define __G_MARKUP_H__
#include <gerror.h>
#include <glib/gerror.h>
G_BEGIN_DECLS

View File

@ -27,7 +27,7 @@
#ifndef __G_MEM_H__
#define __G_MEM_H__
#include <gtypes.h>
#include <glib/gtypes.h>
G_BEGIN_DECLS

View File

@ -28,7 +28,7 @@
#define __G_MESSAGES_H__
#include <stdarg.h>
#include <gtypes.h>
#include <glib/gtypes.h>
G_BEGIN_DECLS

View File

@ -27,7 +27,7 @@
#ifndef __G_NODE_H__
#define __G_NODE_H__
#include <gmem.h>
#include <glib/gmem.h>
G_BEGIN_DECLS

View File

@ -19,7 +19,7 @@
#ifndef __G_PATTERN_H__
#define __G_PATTERN_H__
#include <gtypes.h>
#include <glib/gtypes.h>
G_BEGIN_DECLS

View File

@ -27,7 +27,7 @@
#ifndef __G_PRIMES_H__
#define __G_PRIMES_H__
#include <gtypes.h>
#include <glib/gtypes.h>
G_BEGIN_DECLS

View File

@ -28,7 +28,7 @@
#ifndef __G_QSORT_H__
#define __G_QSORT_H__
#include <gtypes.h>
#include <glib/gtypes.h>
G_BEGIN_DECLS

View File

@ -27,7 +27,7 @@
#ifndef __G_QUARK_H__
#define __G_QUARK_H__
#include <gtypes.h>
#include <glib/gtypes.h>
G_BEGIN_DECLS

View File

@ -27,7 +27,7 @@
#ifndef __G_QUEUE_H__
#define __G_QUEUE_H__
#include <glist.h>
#include <glib/glist.h>
G_BEGIN_DECLS

View File

@ -27,7 +27,7 @@
#ifndef __G_RAND_H__
#define __G_RAND_H__
#include <gtypes.h>
#include <glib/gtypes.h>
G_BEGIN_DECLS

View File

@ -27,7 +27,7 @@
#ifndef __G_REL_H__
#define __G_REL_H__
#include <gtypes.h>
#include <glib/gtypes.h>
G_BEGIN_DECLS

View File

@ -27,7 +27,7 @@
#ifndef __G_SCANNER_H__
#define __G_SCANNER_H__
#include <ghash.h>
#include <glib/ghash.h>
G_BEGIN_DECLS

View File

@ -21,7 +21,7 @@
#ifndef __G_SHELL_H__
#define __G_SHELL_H__
#include <gerror.h>
#include <glib/gerror.h>
G_BEGIN_DECLS

View File

@ -27,7 +27,7 @@
#ifndef __G_SLIST_H__
#define __G_SLIST_H__
#include <gmem.h>
#include <glib/gmem.h>
G_BEGIN_DECLS

View File

@ -21,7 +21,7 @@
#ifndef __G_SPAWN_H__
#define __G_SPAWN_H__
#include <gerror.h>
#include <glib/gerror.h>
G_BEGIN_DECLS

View File

@ -28,7 +28,7 @@
#define __G_STRFUNCS_H__
#include <stdarg.h>
#include <gtypes.h>
#include <glib/gtypes.h>
G_BEGIN_DECLS

View File

@ -27,7 +27,7 @@
#ifndef __G_STRING_H__
#define __G_STRING_H__
#include <gtypes.h>
#include <glib/gtypes.h>
G_BEGIN_DECLS

View File

@ -27,8 +27,8 @@
#ifndef __G_THREAD_H__
#define __G_THREAD_H__
#include <gerror.h>
#include <gtypes.h>
#include <glib/gerror.h>
#include <glib/gtypes.h>
G_BEGIN_DECLS

View File

@ -27,7 +27,7 @@
#ifndef __G_THREADPOOL_H__
#define __G_THREADPOOL_H__
#include <gthread.h>
#include <glib/gthread.h>
G_BEGIN_DECLS

View File

@ -27,7 +27,7 @@
#ifndef __G_TIMER_H__
#define __G_TIMER_H__
#include <gtypes.h>
#include <glib/gtypes.h>
G_BEGIN_DECLS

View File

@ -27,7 +27,7 @@
#ifndef __G_TREE_H__
#define __G_TREE_H__
#include <gnode.h>
#include <glib/gnode.h>
G_BEGIN_DECLS

View File

@ -22,8 +22,8 @@
#ifndef __G_UNICODE_H__
#define __G_UNICODE_H__
#include <gerror.h>
#include <gtypes.h>
#include <glib/gerror.h>
#include <glib/gtypes.h>
G_BEGIN_DECLS

View File

@ -27,7 +27,7 @@
#ifndef __G_UTILS_H__
#define __G_UTILS_H__
#include <gtypes.h>
#include <glib/gtypes.h>
#include <stdarg.h>
G_BEGIN_DECLS

View File

@ -27,7 +27,7 @@
#ifndef __G_WIN32_H__
#define __G_WIN32_H__
#include <gtypes.h>
#include <glib/gtypes.h>
#ifdef G_PLATFORM_WIN32

View File

@ -1,28 +0,0 @@
#ifndef __GLIBINTL_H__
#define __GLIBINTL_H__
#include "config.h"
#ifdef ENABLE_NLS
gchar *_glib_gettext (const gchar *str);
#include <libintl.h>
#define _(String) _glib_gettext(String)
#ifdef gettext_noop
#define N_(String) gettext_noop(String)
#else
#define N_(String) (String)
#endif
#else /* NLS is disabled */
#define _(String) (String)
#define N_(String) (String)
#define textdomain(String) (String)
#define gettext(String) (String)
#define dgettext(Domain,String) (String)
#define dcgettext(Domain,String,Type) (String)
#define bindtextdomain(Domain,Directory) (Domain)
#endif
#endif /* __GLIBINTL_H__ */

826
glist.c
View File

@ -1,826 +0,0 @@
/* 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 Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
/*
* MT safe
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "glib.h"
#ifndef DISABLE_MEM_POOLS
struct _GAllocator /* from gmem.c */
{
gchar *name;
guint16 n_preallocs;
guint is_unused : 1;
guint type : 4;
GAllocator *last;
GMemChunk *mem_chunk;
GList *free_lists; /* implementation specific */
};
static GAllocator *current_allocator = NULL;
G_LOCK_DEFINE_STATIC (current_allocator);
/* HOLDS: current_allocator_lock */
static void
g_list_validate_allocator (GAllocator *allocator)
{
g_return_if_fail (allocator != NULL);
g_return_if_fail (allocator->is_unused == TRUE);
if (allocator->type != G_ALLOCATOR_LIST)
{
allocator->type = G_ALLOCATOR_LIST;
if (allocator->mem_chunk)
{
g_mem_chunk_destroy (allocator->mem_chunk);
allocator->mem_chunk = NULL;
}
}
if (!allocator->mem_chunk)
{
allocator->mem_chunk = g_mem_chunk_new (allocator->name,
sizeof (GList),
sizeof (GList) * allocator->n_preallocs,
G_ALLOC_ONLY);
allocator->free_lists = NULL;
}
allocator->is_unused = FALSE;
}
void
g_list_push_allocator(GAllocator *allocator)
{
G_LOCK (current_allocator);
g_list_validate_allocator (allocator);
allocator->last = current_allocator;
current_allocator = allocator;
G_UNLOCK (current_allocator);
}
void
g_list_pop_allocator (void)
{
G_LOCK (current_allocator);
if (current_allocator)
{
GAllocator *allocator;
allocator = current_allocator;
current_allocator = allocator->last;
allocator->last = NULL;
allocator->is_unused = TRUE;
}
G_UNLOCK (current_allocator);
}
static inline GList*
_g_list_alloc (void)
{
GList *list;
G_LOCK (current_allocator);
if (!current_allocator)
{
GAllocator *allocator = g_allocator_new ("GLib default GList allocator",
128);
g_list_validate_allocator (allocator);
allocator->last = NULL;
current_allocator = allocator;
}
if (!current_allocator->free_lists)
{
list = g_chunk_new (GList, current_allocator->mem_chunk);
list->data = NULL;
}
else
{
if (current_allocator->free_lists->data)
{
list = current_allocator->free_lists->data;
current_allocator->free_lists->data = list->next;
list->data = NULL;
}
else
{
list = current_allocator->free_lists;
current_allocator->free_lists = list->next;
}
}
G_UNLOCK (current_allocator);
list->next = NULL;
list->prev = NULL;
return list;
}
GList*
g_list_alloc (void)
{
return _g_list_alloc ();
}
void
g_list_free (GList *list)
{
if (list)
{
GList *last_node = list;
#ifdef ENABLE_GC_FRIENDLY
while (last_node->next)
{
last_node->data = NULL;
last_node->prev = NULL;
last_node = last_node->next;
}
last_node->data = NULL;
last_node->prev = NULL;
#else /* !ENABLE_GC_FRIENDLY */
list->data = list->next;
#endif /* ENABLE_GC_FRIENDLY */
G_LOCK (current_allocator);
last_node->next = current_allocator->free_lists;
current_allocator->free_lists = list;
G_UNLOCK (current_allocator);
}
}
static inline void
_g_list_free_1 (GList *list)
{
if (list)
{
list->data = NULL;
#ifdef ENABLE_GC_FRIENDLY
list->prev = NULL;
#endif /* ENABLE_GC_FRIENDLY */
G_LOCK (current_allocator);
list->next = current_allocator->free_lists;
current_allocator->free_lists = list;
G_UNLOCK (current_allocator);
}
}
void
g_list_free_1 (GList *list)
{
_g_list_free_1 (list);
}
#else /* DISABLE_MEM_POOLS */
#define _g_list_alloc g_list_alloc
GList*
g_list_alloc (void)
{
GList *list;
list = g_new0 (GList, 1);
return list;
}
void
g_list_free (GList *list)
{
GList *last;
while (list)
{
last = list;
list = list->next;
g_free (last);
}
}
#define _g_list_free_1 g_list_free_1
void
g_list_free_1 (GList *list)
{
g_free (list);
}
#endif
GList*
g_list_append (GList *list,
gpointer data)
{
GList *new_list;
GList *last;
new_list = _g_list_alloc ();
new_list->data = data;
if (list)
{
last = g_list_last (list);
/* g_assert (last != NULL); */
last->next = new_list;
new_list->prev = last;
return list;
}
else
return new_list;
}
GList*
g_list_prepend (GList *list,
gpointer data)
{
GList *new_list;
new_list = _g_list_alloc ();
new_list->data = data;
if (list)
{
if (list->prev)
{
list->prev->next = new_list;
new_list->prev = list->prev;
}
list->prev = new_list;
new_list->next = list;
}
return new_list;
}
GList*
g_list_insert (GList *list,
gpointer data,
gint position)
{
GList *new_list;
GList *tmp_list;
if (position < 0)
return g_list_append (list, data);
else if (position == 0)
return g_list_prepend (list, data);
tmp_list = g_list_nth (list, position);
if (!tmp_list)
return g_list_append (list, data);
new_list = _g_list_alloc ();
new_list->data = data;
if (tmp_list->prev)
{
tmp_list->prev->next = new_list;
new_list->prev = tmp_list->prev;
}
new_list->next = tmp_list;
tmp_list->prev = new_list;
if (tmp_list == list)
return new_list;
else
return list;
}
GList *
g_list_concat (GList *list1, GList *list2)
{
GList *tmp_list;
if (list2)
{
tmp_list = g_list_last (list1);
if (tmp_list)
tmp_list->next = list2;
else
list1 = list2;
list2->prev = tmp_list;
}
return list1;
}
GList*
g_list_remove (GList *list,
gconstpointer data)
{
GList *tmp;
tmp = list;
while (tmp)
{
if (tmp->data != data)
tmp = tmp->next;
else
{
if (tmp->prev)
tmp->prev->next = tmp->next;
if (tmp->next)
tmp->next->prev = tmp->prev;
if (list == tmp)
list = list->next;
_g_list_free_1 (tmp);
break;
}
}
return list;
}
GList*
g_list_remove_all (GList *list,
gconstpointer data)
{
GList *tmp = list;
while (tmp)
{
if (tmp->data != data)
tmp = tmp->next;
else
{
GList *next = tmp->next;
if (tmp->prev)
tmp->prev->next = next;
else
list = next;
if (next)
next->prev = tmp->prev;
_g_list_free_1 (tmp);
tmp = next;
}
}
return list;
}
static inline GList*
_g_list_remove_link (GList *list,
GList *link)
{
if (link)
{
if (link->prev)
link->prev->next = link->next;
if (link->next)
link->next->prev = link->prev;
if (link == list)
list = list->next;
link->next = NULL;
link->prev = NULL;
}
return list;
}
GList*
g_list_remove_link (GList *list,
GList *link)
{
return _g_list_remove_link (list, link);
}
GList*
g_list_delete_link (GList *list,
GList *link)
{
list = _g_list_remove_link (list, link);
_g_list_free_1 (link);
return list;
}
GList*
g_list_copy (GList *list)
{
GList *new_list = NULL;
if (list)
{
GList *last;
new_list = _g_list_alloc ();
new_list->data = list->data;
last = new_list;
list = list->next;
while (list)
{
last->next = _g_list_alloc ();
last->next->prev = last;
last = last->next;
last->data = list->data;
list = list->next;
}
}
return new_list;
}
GList*
g_list_reverse (GList *list)
{
GList *last;
last = NULL;
while (list)
{
last = list;
list = last->next;
last->next = last->prev;
last->prev = list;
}
return last;
}
GList*
g_list_nth (GList *list,
guint n)
{
while ((n-- > 0) && list)
list = list->next;
return list;
}
GList*
g_list_nth_prev (GList *list,
guint n)
{
while ((n-- > 0) && list)
list = list->prev;
return list;
}
gpointer
g_list_nth_data (GList *list,
guint n)
{
while ((n-- > 0) && list)
list = list->next;
return list ? list->data : NULL;
}
GList*
g_list_find (GList *list,
gconstpointer data)
{
while (list)
{
if (list->data == data)
break;
list = list->next;
}
return list;
}
GList*
g_list_find_custom (GList *list,
gconstpointer data,
GCompareFunc func)
{
g_return_val_if_fail (func != NULL, list);
while (list)
{
if (! func (list->data, data))
return list;
list = list->next;
}
return NULL;
}
gint
g_list_position (GList *list,
GList *link)
{
gint i;
i = 0;
while (list)
{
if (list == link)
return i;
i++;
list = list->next;
}
return -1;
}
gint
g_list_index (GList *list,
gconstpointer data)
{
gint i;
i = 0;
while (list)
{
if (list->data == data)
return i;
i++;
list = list->next;
}
return -1;
}
GList*
g_list_last (GList *list)
{
if (list)
{
while (list->next)
list = list->next;
}
return list;
}
GList*
g_list_first (GList *list)
{
if (list)
{
while (list->prev)
list = list->prev;
}
return list;
}
guint
g_list_length (GList *list)
{
guint length;
length = 0;
while (list)
{
length++;
list = list->next;
}
return length;
}
void
g_list_foreach (GList *list,
GFunc func,
gpointer user_data)
{
while (list)
{
GList *next = list->next;
(*func) (list->data, user_data);
list = next;
}
}
GList*
g_list_insert_sorted (GList *list,
gpointer data,
GCompareFunc func)
{
GList *tmp_list = list;
GList *new_list;
gint cmp;
g_return_val_if_fail (func != NULL, list);
if (!list)
{
new_list = _g_list_alloc ();
new_list->data = data;
return new_list;
}
cmp = (*func) (data, tmp_list->data);
while ((tmp_list->next) && (cmp > 0))
{
tmp_list = tmp_list->next;
cmp = (*func) (data, tmp_list->data);
}
new_list = _g_list_alloc ();
new_list->data = data;
if ((!tmp_list->next) && (cmp > 0))
{
tmp_list->next = new_list;
new_list->prev = tmp_list;
return list;
}
if (tmp_list->prev)
{
tmp_list->prev->next = new_list;
new_list->prev = tmp_list->prev;
}
new_list->next = tmp_list;
tmp_list->prev = new_list;
if (tmp_list == list)
return new_list;
else
return list;
}
static GList *
g_list_sort_merge (GList *l1,
GList *l2,
GFunc compare_func,
gboolean use_data,
gpointer user_data)
{
GList list, *l, *lprev;
gint cmp;
l = &list;
lprev = NULL;
while (l1 && l2)
{
if (use_data)
cmp = ((GCompareDataFunc) compare_func) (l1->data, l2->data, user_data);
else
cmp = ((GCompareFunc) compare_func) (l1->data, l2->data);
if (cmp <= 0)
{
l->next = l1;
l = l->next;
l->prev = lprev;
lprev = l;
l1 = l1->next;
}
else
{
l->next = l2;
l = l->next;
l->prev = lprev;
lprev = l;
l2 = l2->next;
}
}
l->next = l1 ? l1 : l2;
l->next->prev = l;
return list.next;
}
static GList*
g_list_sort_real (GList *list,
GFunc compare_func,
gboolean use_data,
gpointer user_data)
{
GList *l1, *l2;
if (!list)
return NULL;
if (!list->next)
return list;
l1 = list;
l2 = list->next;
while ((l2 = l2->next) != NULL)
{
if ((l2 = l2->next) == NULL)
break;
l1 = l1->next;
}
l2 = l1->next;
l1->next = NULL;
return g_list_sort_merge (g_list_sort_real (list, compare_func, use_data, user_data),
g_list_sort_real (l2, compare_func, use_data, user_data),
compare_func,
use_data,
user_data);
}
GList *
g_list_sort (GList *list,
GCompareFunc compare_func)
{
return g_list_sort_real (list, (GFunc) compare_func, FALSE, NULL);
}
GList *
g_list_sort_with_data (GList *list,
GCompareDataFunc compare_func,
gpointer user_data)
{
return g_list_sort_real (list, (GFunc) compare_func, TRUE, user_data);
}
static GList*
g_list_sort2 (GList *list,
GCompareFunc compare_func)
{
GSList *runs = NULL;
GList *tmp;
/* Degenerate case. */
if (!list) return NULL;
/* Assume: list = [12,2,4,11,2,4,6,1,1,12]. */
for (tmp = list; tmp; )
{
GList *tmp2;
for (tmp2 = tmp;
tmp2->next && compare_func (tmp2->data, tmp2->next->data) <= 0;
tmp2 = tmp2->next)
/* Nothing */;
runs = g_slist_append (runs, tmp);
tmp = tmp2->next;
tmp2->next = NULL;
}
/* Now: runs = [[12],[2,4,11],[2,4,6],[1,1,12]]. */
while (runs->next)
{
/* We have more than one run. Merge pairwise. */
GSList *dst, *src, *dstprev = NULL;
dst = src = runs;
while (src && src->next)
{
dst->data = g_list_sort_merge (src->data,
src->next->data,
(GFunc) compare_func,
FALSE, NULL);
dstprev = dst;
dst = dst->next;
src = src->next->next;
}
/* If number of runs was odd, just keep the last. */
if (src)
{
dst->data = src->data;
dstprev = dst;
dst = dst->next;
}
dstprev->next = NULL;
g_slist_free (dst);
}
/* After 1st loop: runs = [[2,4,11,12],[1,1,2,4,6,12]]. */
/* After 2nd loop: runs = [[1,1,2,2,4,4,6,11,12,12]]. */
list = runs->data;
g_slist_free (runs);
return list;
}

105
glist.h
View File

@ -1,105 +0,0 @@
/* 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 Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
#ifndef __G_LIST_H__
#define __G_LIST_H__
#include <gmem.h>
G_BEGIN_DECLS
typedef struct _GList GList;
struct _GList
{
gpointer data;
GList *next;
GList *prev;
};
/* Doubly linked lists
*/
void g_list_push_allocator (GAllocator *allocator);
void g_list_pop_allocator (void);
GList* g_list_alloc (void);
void g_list_free (GList *list);
void g_list_free_1 (GList *list);
GList* g_list_append (GList *list,
gpointer data);
GList* g_list_prepend (GList *list,
gpointer data);
GList* g_list_insert (GList *list,
gpointer data,
gint position);
GList* g_list_insert_sorted (GList *list,
gpointer data,
GCompareFunc func);
GList* g_list_concat (GList *list1,
GList *list2);
GList* g_list_remove (GList *list,
gconstpointer data);
GList* g_list_remove_all (GList *list,
gconstpointer data);
GList* g_list_remove_link (GList *list,
GList *llink);
GList* g_list_delete_link (GList *list,
GList *link);
GList* g_list_reverse (GList *list);
GList* g_list_copy (GList *list);
GList* g_list_nth (GList *list,
guint n);
GList* g_list_nth_prev (GList *list,
guint n);
GList* g_list_find (GList *list,
gconstpointer data);
GList* g_list_find_custom (GList *list,
gconstpointer data,
GCompareFunc func);
gint g_list_position (GList *list,
GList *llink);
gint g_list_index (GList *list,
gconstpointer data);
GList* g_list_last (GList *list);
GList* g_list_first (GList *list);
guint g_list_length (GList *list);
void g_list_foreach (GList *list,
GFunc func,
gpointer user_data);
GList* g_list_sort (GList *list,
GCompareFunc compare_func);
GList* g_list_sort_with_data (GList *list,
GCompareDataFunc compare_func,
gpointer user_data);
gpointer g_list_nth_data (GList *list,
guint n);
#define g_list_previous(list) ((list) ? (((GList *)(list))->prev) : NULL)
#define g_list_next(list) ((list) ? (((GList *)(list))->next) : NULL)
G_END_DECLS
#endif /* __G_LIST_H__ */

193
gmacros.h
View File

@ -1,193 +0,0 @@
/* 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 Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
/* This file must not include any other glib header file and must thus
* not refer to variables from glibconfig.h
*/
#ifndef __G_MACROS_H__
#define __G_MACROS_H__
/* Here we provide G_GNUC_EXTENSION as an alias for __extension__,
* where this is valid. This allows for warningless compilation of
* "long long" types even in the presence of '-ansi -pedantic'.
*/
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)
# define G_GNUC_EXTENSION __extension__
#else
# define G_GNUC_EXTENSION
#endif
/* Provide macros to feature the GCC function attribute.
*/
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
#define G_GNUC_PURE \
__attribute__((pure))
#else
#define G_GNUC_PURE
#endif
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
#define G_GNUC_PRINTF( format_idx, arg_idx ) \
__attribute__((format (printf, format_idx, arg_idx)))
#define G_GNUC_SCANF( format_idx, arg_idx ) \
__attribute__((format (scanf, format_idx, arg_idx)))
#define G_GNUC_FORMAT( arg_idx ) \
__attribute__((format_arg (arg_idx)))
#define G_GNUC_NORETURN \
__attribute__((noreturn))
#define G_GNUC_CONST \
__attribute__((const))
#define G_GNUC_UNUSED \
__attribute__((unused))
#else /* !__GNUC__ */
#define G_GNUC_PRINTF( format_idx, arg_idx )
#define G_GNUC_SCANF( format_idx, arg_idx )
#define G_GNUC_FORMAT( arg_idx )
#define G_GNUC_NORETURN
#define G_GNUC_CONST
#define G_GNUC_UNUSED
#endif /* !__GNUC__ */
/* Wrap the gcc __PRETTY_FUNCTION__ and __FUNCTION__ variables with
* macros, so we can refer to them as strings unconditionally.
*/
#ifdef __GNUC__
#define G_GNUC_FUNCTION __FUNCTION__
#define G_GNUC_PRETTY_FUNCTION __PRETTY_FUNCTION__
#else /* !__GNUC__ */
#define G_GNUC_FUNCTION ""
#define G_GNUC_PRETTY_FUNCTION ""
#endif /* !__GNUC__ */
#define G_STRINGIFY(macro_or_string) G_STRINGIFY_ARG (macro_or_string)
#define G_STRINGIFY_ARG(contents) #contents
/* Provide a string identifying the current code position */
#ifdef __GNUC__
# define G_STRLOC __FILE__ ":" G_STRINGIFY (__LINE__) ":" __PRETTY_FUNCTION__ "()"
#else
# define G_STRLOC __FILE__ ":" G_STRINGIFY (__LINE__)
#endif
/* Guard C code in headers, while including them from C++ */
#ifdef __cplusplus
# define G_BEGIN_DECLS extern "C" {
# define G_END_DECLS }
#else
# define G_BEGIN_DECLS
# define G_END_DECLS
#endif
/* Provide definitions for some commonly used macros.
* Some of them are only provided if they haven't already
* been defined. It is assumed that if they are already
* defined then the current definition is correct.
*/
#ifndef NULL
# ifdef __cplusplus
# define NULL (0L)
# else /* !__cplusplus */
# define NULL ((void*) 0)
# endif /* !__cplusplus */
#endif
#ifndef FALSE
#define FALSE (0)
#endif
#ifndef TRUE
#define TRUE (!FALSE)
#endif
#undef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#undef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#undef ABS
#define ABS(a) (((a) < 0) ? -(a) : (a))
#undef CLAMP
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
/* Count the number of elements in an array. The array must be defined
* as such; using this with a dynamically allocated array will give
* incorrect results.
*/
#define G_N_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0]))
/* Macros by analogy to GINT_TO_POINTER, GPOINTER_TO_INT
*/
#define GPOINTER_TO_SIZE(p) ((gsize) (p))
#define GSIZE_TO_POINTER(s) ((gpointer) (gsize) (s))
/* Provide convenience macros for handling structure
* fields through their offsets.
*/
#define G_STRUCT_OFFSET(struct_type, member) \
((glong) ((guint8*) &((struct_type*) 0)->member))
#define G_STRUCT_MEMBER_P(struct_p, struct_offset) \
((gpointer) ((guint8*) (struct_p) + (glong) (struct_offset)))
#define G_STRUCT_MEMBER(member_type, struct_p, struct_offset) \
(*(member_type*) G_STRUCT_MEMBER_P ((struct_p), (struct_offset)))
/* Provide simple macro statement wrappers (adapted from Perl):
* G_STMT_START { statements; } G_STMT_END;
* can be used as a single statement, as in
* if (x) G_STMT_START { ... } G_STMT_END; else ...
*
* For gcc we will wrap the statements within `({' and `})' braces.
* For SunOS they will be wrapped within `if (1)' and `else (void) 0',
* and otherwise within `do' and `while (0)'.
*/
#if !(defined (G_STMT_START) && defined (G_STMT_END))
# if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus)
# define G_STMT_START (void)(
# define G_STMT_END )
# else
# if (defined (sun) || defined (__sun__))
# define G_STMT_START if (1)
# define G_STMT_END else (void)0
# else
# define G_STMT_START do
# define G_STMT_END while (0)
# endif
# endif
#endif
/* Allow the app programmer to select whether or not return values
* (usually char*) are const or not. Don't try using this feature for
* functions with C++ linkage.
*/
#ifdef G_DISABLE_CONST_RETURNS
#define G_CONST_RETURN
#else
#define G_CONST_RETURN const
#endif
#endif /* __G_MACROS_H__ */

2937
gmain.c

File diff suppressed because it is too large Load Diff

291
gmain.h
View File

@ -1,291 +0,0 @@
/* gmain.h - the GLib Main loop
* Copyright (C) 1998-2000 Red Hat, Inc.
*
* 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.
*/
#ifndef __G_MAIN_H__
#define __G_MAIN_H__
#include <gslist.h>
#include <gthread.h>
G_BEGIN_DECLS
typedef struct _GMainContext GMainContext; /* Opaque */
typedef struct _GMainLoop GMainLoop; /* Opaque */
typedef struct _GSource GSource;
typedef struct _GSourceCallbackFuncs GSourceCallbackFuncs;
typedef struct _GSourceFuncs GSourceFuncs;
typedef gboolean (*GSourceFunc) (gpointer data);
struct _GSource
{
/*< private >*/
gpointer callback_data;
GSourceCallbackFuncs *callback_funcs;
GSourceFuncs *source_funcs;
guint ref_count;
GMainContext *context;
gint priority;
guint flags;
guint id;
GSList *poll_fds;
GSource *prev;
GSource *next;
};
struct _GSourceCallbackFuncs
{
void (*ref) (gpointer cb_data);
void (*unref) (gpointer cb_data);
void (*get) (gpointer cb_data,
GSourceFunc *func,
gpointer *data);
};
struct _GSourceFuncs
{
gboolean (*prepare) (GSource *source,
gint *timeout);
gboolean (*check) (GSource *source);
gboolean (*dispatch) (GSource *source,
GSourceFunc callback,
gpointer user_data);
void (*destroy) (GSource *source); /* Can be NULL */
};
/* Any definitions using GPollFD or GPollFunc are primarily
* for Unix and not guaranteed to be the compatible on all
* operating systems on which GLib runs. Right now, the
* GLib does use these functions on Win32 as well, but interprets
* them in a fairly different way than on Unix. If you use
* these definitions, you are should be prepared to recode
* for different operating systems.
*
*
* On Win32, the fd in a GPollFD should be Win32 HANDLE (*not* a file
* descriptor as provided by the C runtime) that can be used by
* MsgWaitForMultipleObjects. This does *not* include file handles
* from CreateFile, SOCKETs, nor pipe handles. (But you can use
* WSAEventSelect to signal events when a SOCKET is readable).
*
* On Win32, fd can also be the special value G_WIN32_MSG_HANDLE to
* indicate polling for messages. These message queue GPollFDs should
* be added with the g_main_poll_win32_msg_add function.
*
* But note that G_WIN32_MSG_HANDLE GPollFDs should not be used by GDK
* (GTK) programs, as GDK itself wants to read messages and convert them
* to GDK events.
*
* So, unless you really know what you are doing, it's best not to try
* to use the main loop polling stuff for your own needs on
* Win32. It's really only written for the GIMP's needs so
* far.
*/
typedef struct _GPollFD GPollFD;
typedef gint (*GPollFunc) (GPollFD *ufds,
guint nfsd,
gint timeout);
struct _GPollFD
{
gint fd;
gushort events;
gushort revents;
};
/* Standard priorities */
#define G_PRIORITY_HIGH -100
#define G_PRIORITY_DEFAULT 0
#define G_PRIORITY_HIGH_IDLE 100
#define G_PRIORITY_DEFAULT_IDLE 200
#define G_PRIORITY_LOW 300
/* GMainContext: */
GMainContext *g_main_context_get (GThread *thread);
GMainContext *g_main_context_default (void);
gboolean g_main_context_iteration (GMainContext *context,
gboolean may_block);
gboolean g_main_context_pending (GMainContext *context);
/* For implementation of legacy interfaces
*/
GSource *g_main_context_find_source_by_id (GMainContext *context,
guint id);
GSource *g_main_context_find_source_by_user_data (GMainContext *context,
gpointer user_data);
GSource *g_main_context_find_source_by_funcs_user_data (GMainContext *context,
GSourceFuncs *funcs,
gpointer user_data);
/* Low level functions for implementing custom main loops.
*/
gboolean g_main_context_prepare (GMainContext *context,
gint *priority);
gint g_main_context_query (GMainContext *context,
gint max_priority,
gint *timeout,
GPollFD *fds,
gint n_fds);
gint g_main_context_check (GMainContext *context,
gint max_priority,
GPollFD *fds,
gint n_fds);
void g_main_context_dispatch (GMainContext *context);
void g_main_context_set_poll_func (GMainContext *context,
GPollFunc func);
GPollFunc g_main_context_get_poll_func (GMainContext *context);
/* Low level functions for use by source implementations
*/
void g_main_context_add_poll (GMainContext *context,
GPollFD *fd,
gint priority);
void g_main_context_remove_poll (GMainContext *context,
GPollFD *fd);
/* GMainLoop: */
GMainLoop *g_main_loop_new (GMainContext *context,
gboolean is_running);
void g_main_loop_run (GMainLoop *loop);
void g_main_loop_quit (GMainLoop *loop);
GMainLoop *g_main_loop_ref (GMainLoop *loop);
void g_main_loop_unref (GMainLoop *loop);
gboolean g_main_loop_is_running (GMainLoop *loop);
/* GSource: */
GSource *g_source_new (GSourceFuncs *source_funcs,
guint struct_size);
GSource *g_source_ref (GSource *source);
void g_source_unref (GSource *source);
guint g_source_attach (GSource *source,
GMainContext *context);
void g_source_destroy (GSource *source);
void g_source_set_priority (GSource *source,
gint priority);
gint g_source_get_priority (GSource *source);
void g_source_set_can_recurse (GSource *source,
gboolean can_recurse);
gboolean g_source_get_can_recurse (GSource *source);
guint g_source_get_id (GSource *source);
GMainContext *g_source_get_context (GSource *source);
void g_source_set_callback (GSource *source,
GSourceFunc func,
gpointer data,
GDestroyNotify notify);
/* Used to implement g_source_connect_closure and internally*/
void g_source_set_callback_indirect (GSource *source,
gpointer callback_data,
GSourceCallbackFuncs *callback_funcs);
void g_source_add_poll (GSource *source,
GPollFD *fd);
void g_source_remove_poll (GSource *source,
GPollFD *fd);
void g_source_get_current_time (GSource *source,
GTimeVal *timeval);
/* void g_source_connect_closure (GSource *source,
GClosure *closure);
*/
/* Specific source types
*/
GSource *g_idle_source_new (void);
GSource *g_timeout_source_new (guint interval);
/* Miscellaneous functions
*/
void g_get_current_time (GTimeVal *result);
/* ============== Compat main loop stuff ================== */
#ifndef G_DISABLE_DEPRECATED
/* Legacy names for GMainLoop functions
*/
#define g_main_new(is_running) g_main_loop_new (NULL, is_running);
#define g_main_run(loop) g_main_loop_run(loop)
#define g_main_quit(loop) g_main_loop_quit(loop)
#define g_main_destroy(loop) g_main_loop_unref(loop)
#define g_main_is_running(loop) g_main_loop_is_running(loop)
/* Functions to manipulate the default main loop
*/
#define g_main_iteration(may_block) g_main_context_iteration (NULL, may_block)
#define g_main_pending() g_main_context_pending (NULL)
#define g_main_set_poll_func(func) g_main_context_set_poll_func (NULL, func)
#endif /* G_DISABLE_DEPRECATED */
/* Source manipulation by ID */
gboolean g_source_remove (guint tag);
gboolean g_source_remove_by_user_data (gpointer user_data);
gboolean g_source_remove_by_funcs_user_data (GSourceFuncs *funcs,
gpointer user_data);
/* Idles and timeouts */
guint g_timeout_add_full (gint priority,
guint interval,
GSourceFunc function,
gpointer data,
GDestroyNotify notify);
guint g_timeout_add (guint interval,
GSourceFunc function,
gpointer data);
guint g_idle_add (GSourceFunc function,
gpointer data);
guint g_idle_add_full (gint priority,
GSourceFunc function,
gpointer data,
GDestroyNotify notify);
gboolean g_idle_remove_by_data (gpointer data);
#ifdef G_OS_WIN32
/* This is used to add polling for Windows messages. GDK (GTK+) programs
* should *not* use this.
*/
void g_main_poll_win32_msg_add (gint priority,
GPollFD *fd,
guint hwnd);
#endif /* G_OS_WIN32 */
G_END_DECLS
#endif /* __G_MAIN_H__ */

1735
gmarkup.c

File diff suppressed because it is too large Load Diff

123
gmarkup.h
View File

@ -1,123 +0,0 @@
/* gmarkup.h - Simple XML-like string parser/writer
*
* Copyright 2000 Red Hat, Inc.
*
* GLib is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* GLib 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with GLib; see the file COPYING.LIB. If not,
* write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __G_MARKUP_H__
#define __G_MARKUP_H__
#include <gerror.h>
G_BEGIN_DECLS
typedef enum
{
G_MARKUP_ERROR_BAD_UTF8,
G_MARKUP_ERROR_EMPTY,
G_MARKUP_ERROR_PARSE,
/* These three are primarily intended for specific GMarkupParser
* implementations to set.
*/
G_MARKUP_ERROR_UNKNOWN_ELEMENT,
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
G_MARKUP_ERROR_INVALID_CONTENT
} GMarkupError;
#define G_MARKUP_ERROR g_markup_error_quark ()
GQuark g_markup_error_quark ();
typedef enum
{
/* Hmm, can't think of any at the moment */
G_MARKUP_DO_NOT_USE_THIS_UNSUPPORTED_FLAG = 1 << 0
} GMarkupParseFlags;
typedef struct _GMarkupParseContext GMarkupParseContext;
typedef struct _GMarkupParser GMarkupParser;
struct _GMarkupParser
{
/* Called for open tags <foo bar="baz"> */
void (*start_element) (GMarkupParseContext *context,
const gchar *element_name,
const gchar **attribute_names,
const gchar **attribute_values,
gpointer user_data,
GError **error);
/* Called for close tags </foo> */
void (*end_element) (GMarkupParseContext *context,
const gchar *element_name,
gpointer user_data,
GError **error);
/* Called for character data */
/* text is not nul-terminated */
void (*text) (GMarkupParseContext *context,
const gchar *text,
gsize text_len,
gpointer user_data,
GError **error);
/* Called for strings that should be re-saved verbatim in this same
* position, but are not otherwise interpretable. At the moment
* this includes comments and processing instructions.
*/
/* text is not nul-terminated. */
void (*passthrough) (GMarkupParseContext *context,
const gchar *passthrough_text,
gsize text_len,
gpointer user_data,
GError **error);
/* Called on error, including one set by other
* methods in the vtable. The GError should not be freed.
*/
void (*error) (GMarkupParseContext *context,
GError *error,
gpointer user_data);
};
GMarkupParseContext *g_markup_parse_context_new (const GMarkupParser *parser,
GMarkupParseFlags flags,
gpointer user_data,
GDestroyNotify user_data_dnotify);
void g_markup_parse_context_free (GMarkupParseContext *context);
gboolean g_markup_parse_context_parse (GMarkupParseContext *context,
const gchar *text,
gssize text_len,
GError **error);
gboolean g_markup_parse_context_end_parse (GMarkupParseContext *context,
GError **error);
/* For user-constructed error messages, has no precise semantics */
void g_markup_parse_context_get_position (GMarkupParseContext *context,
gint *line_number,
gint *char_number);
/* useful when saving */
gchar* g_markup_escape_text (const gchar *text,
gssize length);
G_END_DECLS
#endif /* __G_MARKUP_H__ */

1263
gmem.c

File diff suppressed because it is too large Load Diff

174
gmem.h
View File

@ -1,174 +0,0 @@
/* 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 Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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.
*/
/*
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
* 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/.
*/
#ifndef __G_MEM_H__
#define __G_MEM_H__
#include <gtypes.h>
G_BEGIN_DECLS
typedef struct _GAllocator GAllocator;
typedef struct _GMemChunk GMemChunk;
typedef struct _GMemVTable GMemVTable;
#if GLIB_SIZEOF_VOID_P > GLIB_SIZEOF_LONG
# define G_MEM_ALIGN GLIB_SIZEOF_VOID_P
#else /* GLIB_SIZEOF_VOID_P <= GLIB_SIZEOF_LONG */
# define G_MEM_ALIGN GLIB_SIZEOF_LONG
#endif /* GLIB_SIZEOF_VOID_P <= GLIB_SIZEOF_LONG */
/* Memory allocation functions
*/
gpointer g_malloc (gulong n_bytes);
gpointer g_malloc0 (gulong n_bytes);
gpointer g_realloc (gpointer mem,
gulong n_bytes);
void g_free (gpointer mem);
gpointer g_try_malloc (gulong n_bytes);
gpointer g_try_realloc (gpointer mem,
gulong n_bytes);
/* Convenience memory allocators
*/
#define g_new(struct_type, n_structs) \
((struct_type *) g_malloc (((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
#define g_new0(struct_type, n_structs) \
((struct_type *) g_malloc0 (((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
#define g_renew(struct_type, mem, n_structs) \
((struct_type *) g_realloc ((mem), ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
/* Memory allocation virtualization for debugging purposes
* g_mem_set_vtable() has to be the very first GLib function called
* if being used
*/
struct _GMemVTable
{
gpointer (*malloc) (gsize n_bytes);
gpointer (*realloc) (gpointer mem,
gsize n_bytes);
void (*free) (gpointer mem);
/* optional */
gpointer (*calloc) (gsize n_blocks,
gsize n_block_bytes);
gpointer (*try_malloc) (gsize n_bytes);
gpointer (*try_realloc) (gpointer mem,
gsize n_bytes);
};
void g_mem_set_vtable (GMemVTable *vtable);
/* Memory profiler and checker, has to be enabled via g_mem_set_vtable()
*/
GLIB_VAR GMemVTable *glib_mem_profiler_table;
void g_mem_profile (void);
/* Memchunk convenience functions
*/
#define g_mem_chunk_create(type, pre_alloc, alloc_type) ( \
g_mem_chunk_new (#type " mem chunks (" #pre_alloc ")", \
sizeof (type), \
sizeof (type) * (pre_alloc), \
(alloc_type)) \
)
#define g_chunk_new(type, chunk) ( \
(type *) g_mem_chunk_alloc (chunk) \
)
#define g_chunk_new0(type, chunk) ( \
(type *) g_mem_chunk_alloc0 (chunk) \
)
#define g_chunk_free(mem, mem_chunk) G_STMT_START { \
g_mem_chunk_free ((mem_chunk), (mem)); \
} G_STMT_END
/* "g_mem_chunk_new" creates a new memory chunk.
* Memory chunks are used to allocate pieces of memory which are
* always the same size. Lists are a good example of such a data type.
* The memory chunk allocates and frees blocks of memory as needed.
* Just be sure to call "g_mem_chunk_free" and not "g_free" on data
* allocated in a mem chunk. ("g_free" will most likely cause a seg
* fault...somewhere).
*
* Oh yeah, GMemChunk is an opaque data type. (You don't really
* want to know what's going on inside do you?)
*/
/* ALLOC_ONLY MemChunk's can only allocate memory. The free operation
* is interpreted as a no op. ALLOC_ONLY MemChunk's save 4 bytes per
* atom. (They are also useful for lists which use MemChunk to allocate
* memory but are also part of the MemChunk implementation).
* ALLOC_AND_FREE MemChunk's can allocate and free memory.
*/
#define G_ALLOC_ONLY 1
#define G_ALLOC_AND_FREE 2
GMemChunk* g_mem_chunk_new (const gchar *name,
gint atom_size,
gulong area_size,
gint type);
void g_mem_chunk_destroy (GMemChunk *mem_chunk);
gpointer g_mem_chunk_alloc (GMemChunk *mem_chunk);
gpointer g_mem_chunk_alloc0 (GMemChunk *mem_chunk);
void g_mem_chunk_free (GMemChunk *mem_chunk,
gpointer mem);
void g_mem_chunk_clean (GMemChunk *mem_chunk);
void g_mem_chunk_reset (GMemChunk *mem_chunk);
void g_mem_chunk_print (GMemChunk *mem_chunk);
void g_mem_chunk_info (void);
/* Ah yes...we have a "g_blow_chunks" function.
* "g_blow_chunks" simply compresses all the chunks. This operation
* consists of freeing every memory area that should be freed (but
* which we haven't gotten around to doing yet). And, no,
* "g_blow_chunks" doesn't follow the naming scheme, but it is a
* much better name than "g_mem_chunk_clean_all" or something
* similar.
*/
void g_blow_chunks (void);
/* Generic allocators
*/
GAllocator* g_allocator_new (const gchar *name,
guint n_preallocs);
void g_allocator_free (GAllocator *allocator);
/* internal */
#define G_ALLOCATOR_LIST (1)
#define G_ALLOCATOR_SLIST (2)
#define G_ALLOCATOR_NODE (3)
G_END_DECLS
#endif /* __G_MEM_H__ */

Some files were not shown because too many files have changed in this diff Show More