[ Very late checkin ]

Thu Mar 15 10:37:49 2001  Owen Taylor  <otaylor@redhat.com>

        * Released 1.2.10

        * NEWS: Update

        * configure.in: Up micro/interface-age/binary-age to 10.
This commit is contained in:
Owen Taylor 2001-06-29 23:42:42 +00:00 committed by Owen Taylor
parent 05693cc388
commit 1f2b1ef109
43 changed files with 75 additions and 21760 deletions

View File

@ -1,3 +1,11 @@
Thu Mar 15 10:37:49 2001 Owen Taylor <otaylor@redhat.com>
* Released 1.2.10
* NEWS: Update
* configure.in: Up micro/interface-age/binary-age to 10.
2001-03-08 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* configure.in (FLAG_DOES_NOT_WORK): Fix typo and thus bug #51862.

View File

@ -1,3 +1,11 @@
Thu Mar 15 10:37:49 2001 Owen Taylor <otaylor@redhat.com>
* Released 1.2.10
* NEWS: Update
* configure.in: Up micro/interface-age/binary-age to 10.
2001-03-08 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* configure.in (FLAG_DOES_NOT_WORK): Fix typo and thus bug #51862.

View File

@ -1,3 +1,11 @@
Thu Mar 15 10:37:49 2001 Owen Taylor <otaylor@redhat.com>
* Released 1.2.10
* NEWS: Update
* configure.in: Up micro/interface-age/binary-age to 10.
2001-03-08 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* configure.in (FLAG_DOES_NOT_WORK): Fix typo and thus bug #51862.

View File

@ -1,3 +1,11 @@
Thu Mar 15 10:37:49 2001 Owen Taylor <otaylor@redhat.com>
* Released 1.2.10
* NEWS: Update
* configure.in: Up micro/interface-age/binary-age to 10.
2001-03-08 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* configure.in (FLAG_DOES_NOT_WORK): Fix typo and thus bug #51862.

View File

@ -1,3 +1,11 @@
Thu Mar 15 10:37:49 2001 Owen Taylor <otaylor@redhat.com>
* Released 1.2.10
* NEWS: Update
* configure.in: Up micro/interface-age/binary-age to 10.
2001-03-08 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* configure.in (FLAG_DOES_NOT_WORK): Fix typo and thus bug #51862.

View File

@ -1,3 +1,11 @@
Thu Mar 15 10:37:49 2001 Owen Taylor <otaylor@redhat.com>
* Released 1.2.10
* NEWS: Update
* configure.in: Up micro/interface-age/binary-age to 10.
2001-03-08 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* configure.in (FLAG_DOES_NOT_WORK): Fix typo and thus bug #51862.

View File

@ -1,3 +1,11 @@
Thu Mar 15 10:37:49 2001 Owen Taylor <otaylor@redhat.com>
* Released 1.2.10
* NEWS: Update
* configure.in: Up micro/interface-age/binary-age to 10.
2001-03-08 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* configure.in (FLAG_DOES_NOT_WORK): Fix typo and thus bug #51862.

View File

@ -1,3 +1,11 @@
Thu Mar 15 10:37:49 2001 Owen Taylor <otaylor@redhat.com>
* Released 1.2.10
* NEWS: Update
* configure.in: Up micro/interface-age/binary-age to 10.
2001-03-08 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
* configure.in (FLAG_DOES_NOT_WORK): Fix typo and thus bug #51862.

View File

@ -31,5 +31,3 @@ options like --prefix=/usr to configure you can give those options
to autogen.sh and they will be passed on to configure.
For information about submitting patches see the README file.

View File

@ -1,8 +1,8 @@
Simple install procedure
========================
% gzip -cd glib-1.2.9.tar.gz | tar xvf - # unpack the sources
% cd glib-1.2.9 # change to the toplevel directory
% gzip -cd glib-1.2.10.tar.gz | tar xvf - # unpack the sources
% cd glib-1.2.10 # change to the toplevel directory
% ./configure # run the `configure' script
% make # build GLIB

5
NEWS
View File

@ -1,3 +1,8 @@
Overview of Changes in GLib 1.2.10:
* Fix compilation problem on some compilers where
g_log_domain_gmodule was not being declared properly.
Overview of Changes in GLib 1.2.9:
* Move include files into a glib-1-2/ subdir to support parallel

2
README
View File

@ -1,7 +1,7 @@
General Information
===================
This is GLib version 1.2.9. GLib is a library which includes support
This is GLib version 1.2.10. GLib is a library which includes support
routines for C such as lists, trees, hashes, memory allocation, and
many other things.

View File

@ -33,9 +33,9 @@ AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)dnl
#
GLIB_MAJOR_VERSION=1
GLIB_MINOR_VERSION=2
GLIB_MICRO_VERSION=9
GLIB_INTERFACE_AGE=9
GLIB_BINARY_AGE=9
GLIB_MICRO_VERSION=10
GLIB_INTERFACE_AGE=10
GLIB_BINARY_AGE=10
GLIB_VERSION=$GLIB_MAJOR_VERSION.$GLIB_MINOR_VERSION.$GLIB_MICRO_VERSION
dnl
AC_DIVERT_POP()dnl

View File

@ -1,130 +0,0 @@
## Process this file with automake to produce Makefile.in
# require automake 1.4
AUTOMAKE_OPTIONS = 1.4
SUBDIRS = . gmodule gthread docs tests
configincludedir = $(pkglibdir)/include
bin_SCRIPTS=glib-config
BUILT_SOURCES=glib-config
glib-config: glib-config.in
INCLUDES = -DG_LOG_DOMAIN=g_log_domain_glib @GLIB_DEBUG_FLAGS@
EXTRA_DIST = \
glib.m4 \
glib.spec.in \
acglib.m4 \
sanity_check \
README.win32 \
glib.def \
makefile.msc.in \
makefile.msc \
giowin32.c \
glibconfig.h.win32 \
glibconfig.h.win32.in \
config.h.win32 \
config.h.win32.in \
glib.pc.in \
gmodule.pc.in \
gthread.pc.in
lib_LTLIBRARIES = libglib.la
libglib_la_SOURCES = \
garray.c \
gcache.c \
gcompletion.c \
gdataset.c \
gdate.c \
gerror.c \
ghash.c \
ghook.c \
giochannel.c \
giounix.c \
glist.c \
gmain.c \
gmem.c \
gmessages.c \
gmutex.c \
gnode.c \
gprimes.c \
grel.c \
gscanner.c \
gslist.c \
gstrfuncs.c \
gstring.c \
gtimer.c \
gtree.c \
gutils.c
glibincludedir=$(includedir)/glib-1.2
glibinclude_HEADERS = \
glib.h
configinclude_DATA = \
glibconfig.h
CONFIGURE_DEPENDENCIES = acglib.m4
BUILT_SOURCES = stamp-gc-h #note: not glibconfig.h
glibconfig.h: stamp-gc-h
@:
stamp-gc-h: config.status
CONFIG_FILES= CONFIG_HEADERS= CONFIG_OTHER=glibconfig.h ./config.status
echo timestamp > stamp-gc-h
libglib_la_LDFLAGS = \
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
-release $(LT_RELEASE) \
-export-dynamic
noinst_PROGRAMS = testglib testgdate testgdateparser
testglib_LDADD = libglib.la
testgdate_LDADD = libglib.la
testgdateparser_LDADD = libglib.la
m4datadir = $(datadir)/aclocal
m4data_DATA = glib.m4
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = glib.pc gmodule.pc gthread.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
.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)`date +"%y%m%d"`
dist-hook: glib.spec
if test -e $(srcdir)/INSTALL.in && test -e $(srcdir)/README.in ; then \
CONFIG_FILES="INSTALL:$(srcdir)/INSTALL.in README:$(srcdir)/README.in" \
CONFIG_HEADERS= \
$(SHELL) config.status \
&& cp INSTALL README $(distdir) ; \
fi \
&& cp glib.spec $(distdir)

View File

@ -1,490 +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 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.
*/
/*
* Modified by the GLib Team and others 1997-1999. 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 <string.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;
};
static gint g_nearest_pow (gint num);
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)
{
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;
return (GArray*) array;
}
void
g_array_free (GArray *array,
gboolean free_segment)
{
if (free_segment)
g_free (array->data);
G_LOCK (array_mem_chunk);
g_mem_chunk_free (array_mem_chunk, array);
G_UNLOCK (array_mem_chunk);
}
GArray*
g_array_append_vals (GArray *farray,
gconstpointer data,
guint len)
{
GRealArray *array = (GRealArray*) farray;
g_array_maybe_expand (array, len);
memcpy (array->data + array->elt_size * array->len, data, array->elt_size * len);
array->len += len;
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 (array->data + array->elt_size * len, array->data, array->elt_size * array->len);
memcpy (array->data, data, len * array->elt_size);
array->len += len;
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 (array->data + array->elt_size * (len + index),
array->data + array->elt_size * index,
array->elt_size * (array->len - index));
memcpy (array->data + array->elt_size * index, data, len * array->elt_size);
array->len += len;
return farray;
}
GArray*
g_array_set_size (GArray *farray,
guint length)
{
GRealArray *array = (GRealArray*) farray;
if (array->len < length)
g_array_maybe_expand (array, length - array->len);
array->len = length;
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 (array->data + array->elt_size * index,
array->data + array->elt_size * (index + 1),
array->elt_size * (array->len - index - 1));
if (array->zero_terminated)
memset (array->data + array->elt_size * (array->len - 1), 0,
array->elt_size);
array->len -= 1;
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)
g_memmove (array->data + array->elt_size * index,
array->data + array->elt_size * (array->len - 1),
array->elt_size);
if (array->zero_terminated)
memset (array->data + array->elt_size * (array->len - 1), 0,
array->elt_size);
array->len -= 1;
return farray;
}
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 = (array->len + len + array->zero_terminated) * array->elt_size;
if (want_alloc > array->alloc)
{
guint old_alloc = array->alloc;
array->alloc = g_nearest_pow (want_alloc);
array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
array->data = g_realloc (array->data, array->alloc);
if (array->clear || array->zero_terminated)
memset (array->data + old_alloc, 0, array->alloc - old_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)
{
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;
return (GPtrArray*) array;
}
void
g_ptr_array_free (GPtrArray *array,
gboolean free_segment)
{
g_return_if_fail (array);
if (free_segment)
g_free (array->pdata);
G_LOCK (ptr_array_mem_chunk);
g_mem_chunk_free (ptr_array_mem_chunk, array);
G_UNLOCK (ptr_array_mem_chunk);
}
static void
g_ptr_array_maybe_expand (GRealPtrArray *array,
gint len)
{
guint old_alloc;
if ((array->len + len) > array->alloc)
{
old_alloc = array->alloc;
array->alloc = g_nearest_pow (array->len + len);
array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
if (array->pdata)
array->pdata = g_realloc (array->pdata, sizeof(gpointer) * array->alloc);
else
array->pdata = g_new0 (gpointer, array->alloc);
memset (array->pdata + old_alloc, 0,
sizeof (gpointer) * (array->alloc - old_alloc));
}
}
void
g_ptr_array_set_size (GPtrArray *farray,
gint length)
{
GRealPtrArray* array = (GRealPtrArray*) farray;
g_return_if_fail (array);
if (length > array->len)
g_ptr_array_maybe_expand (array, (length - array->len));
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->pdata[array->len - 1] = NULL;
array->len -= 1;
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->pdata[array->len - 1] = NULL;
array->len -= 1;
return result;
}
gboolean
g_ptr_array_remove (GPtrArray* farray,
gpointer data)
{
GRealPtrArray* array = (GRealPtrArray*) farray;
int 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;
int 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;
}
/* Byte arrays
*/
GByteArray* g_byte_array_new (void)
{
return (GByteArray*) g_array_new (FALSE, FALSE, 1);
}
void g_byte_array_free (GByteArray *array,
gboolean free_segment)
{
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;
}

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 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.
*/
/*
* Modified by the GLib Team and others 1997-1999. 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,
GCompareFunc key_compare_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_compare_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_compare_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,
gpointer 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,288 +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 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.
*/
/*
* Modified by the GLib Team and others 1997-1999. 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;
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 gint len;
register gint i;
register gint 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)
{
gint plen, len;
gint done = 0;
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 && !strncmp (prefix, cmp->prefix, plen))
{
/* use the cache */
list = cmp->cache;
while (list)
{
if (strncmp (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 = 1;
}
}
if (!done)
{
/* normal code */
g_list_free (cmp->cache);
cmp->cache = NULL;
list = cmp->items;
while (*prefix && list)
{
if (!strncmp (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);
}
#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,611 +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 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.
*/
/*
* Modified by the GLib Team and others 1997-1999. 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 void 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 void
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)
{
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);
}
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;
}
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;
}
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;
}
}
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);
}
void
g_dataset_id_remove_no_notify (gconstpointer dataset_location,
GQuark key_id)
{
g_return_if_fail (dataset_location != NULL);
G_LOCK (g_dataset_global);
if (key_id && g_dataset_location_ht)
{
GDataset *dataset;
dataset = g_dataset_lookup (dataset_location);
if (dataset)
g_data_set_internal (&dataset->datalist, key_id, NULL, (GDestroyNotify) 42, dataset);
}
G_UNLOCK (g_dataset_global);
}
void
g_datalist_id_remove_no_notify (GData **datalist,
GQuark key_id)
{
g_return_if_fail (datalist != NULL);
G_LOCK (g_dataset_global);
if (key_id && g_dataset_location_ht)
g_data_set_internal (datalist, key_id, NULL, (GDestroyNotify) 42, NULL);
G_UNLOCK (g_dataset_global);
}
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;
for (list = dataset->datalist; list; list = 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;
g_return_if_fail (datalist != NULL);
g_return_if_fail (func != NULL);
for (list = *datalist; list; list = 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;
}
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;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,293 +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 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.
*/
/*
* Modified by the GLib Team and others 1997-1999. 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 _MSC_VER
#include <process.h> /* For _getpid() */
#endif
#ifndef NO_FD_SET
# define SELECT_MASK fd_set
#else
# ifndef _AIX
typedef long fd_mask;
# endif
# if defined(_IBMR2)
# define SELECT_MASK void
# else
# define SELECT_MASK int
# endif
#endif
static void stack_trace (char **args);
extern volatile gboolean glib_on_error_halt;
volatile gboolean glib_on_error_halt = TRUE;
void
g_on_error_query (const gchar *prg_name)
{
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);
#ifndef NATIVE_WIN32
if (isatty(0) && isatty(1))
fgets (buf, 8, stdin);
else
strcpy (buf, "E\n");
#else
fgets (buf, 8, stdin);
#endif
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;
}
void
g_on_error_stack_trace (const gchar *prg_name)
{
#ifndef NATIVE_WIN32
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
}
static gboolean stack_trace_done = FALSE;
static void
stack_trace_sigchld (int signum)
{
stack_trace_done = TRUE;
}
static void
stack_trace (char **args)
{
#ifndef NATIVE_WIN32
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);
#else
abort ();
#endif
}

View File

@ -1,404 +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 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.
*/
/*
* Modified by the GLib Team and others 1997-1999. 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"
#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;
guint frozen;
GHashNode **nodes;
GHashFunc hash_func;
GCompareFunc key_compare_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);
static void g_hash_nodes_destroy (GHashNode *hash_node);
G_LOCK_DEFINE_STATIC (g_hash_global);
static GMemChunk *node_mem_chunk = NULL;
static GHashNode *node_free_list = NULL;
GHashTable*
g_hash_table_new (GHashFunc hash_func,
GCompareFunc key_compare_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->frozen = FALSE;
hash_table->hash_func = hash_func ? hash_func : g_direct_hash;
hash_table->key_compare_func = key_compare_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;
}
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]);
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_compare_func or not from
* the inner loop.
*/
if (hash_table->key_compare_func)
while (*node && !(*hash_table->key_compare_func) ((*node)->key, key))
node = &(*node)->next;
else
while (*node && (*node)->key != key)
node = &(*node)->next;
return node;
}
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;
}
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 might be intended.
* a g_hash_table_remove/g_hash_table_insert pair
* can be used otherwise.
*
* node->key = key; */
(*node)->value = value;
}
else
{
*node = g_hash_node_new (key, value);
hash_table->nnodes++;
if (!hash_table->frozen)
g_hash_table_resize (hash_table);
}
}
void
g_hash_table_remove (GHashTable *hash_table,
gconstpointer key)
{
GHashNode **node, *dest;
g_return_if_fail (hash_table != NULL);
node = g_hash_table_lookup_node (hash_table, key);
if (*node)
{
dest = *node;
(*node) = dest->next;
g_hash_node_destroy (dest);
hash_table->nnodes--;
if (!hash_table->frozen)
g_hash_table_resize (hash_table);
}
}
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;
}
void
g_hash_table_freeze (GHashTable *hash_table)
{
g_return_if_fail (hash_table != NULL);
hash_table->frozen++;
}
void
g_hash_table_thaw (GHashTable *hash_table)
{
g_return_if_fail (hash_table != NULL);
if (hash_table->frozen)
if (!(--hash_table->frozen))
g_hash_table_resize (hash_table);
}
guint
g_hash_table_foreach_remove (GHashTable *hash_table,
GHRFunc func,
gpointer user_data)
{
GHashNode *node, *prev;
guint i;
guint deleted = 0;
g_return_val_if_fail (hash_table != NULL, 0);
g_return_val_if_fail (func != NULL, 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);
node = prev;
}
else
{
hash_table->nodes[i] = node->next;
g_hash_node_destroy (node);
goto restart;
}
}
}
}
if (!hash_table->frozen)
g_hash_table_resize (hash_table);
return deleted;
}
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);
}
/* Returns the number of elements contained in the hash table. */
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)
{
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)
{
if (hash_node)
{
GHashNode *node = hash_node;
while (node->next)
node = node->next;
G_LOCK (g_hash_global);
node->next = node_free_list;
node_free_list = hash_node;
G_UNLOCK (g_hash_global);
}
}

View File

@ -1,633 +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 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.
*/
/*
* Modified by the GLib Team and others 1997-1999. 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 --- */
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));
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->hook_free = NULL;
hook_list->hook_destroy = NULL;
}
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);
}
}
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));
if (hook_list->hook_free)
hook_list->hook_free (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);
if (hook->hook_id)
{
hook->hook_id = 0;
hook->flags &= ~G_HOOK_FLAG_ACTIVE;
if (hook_list->hook_destroy)
{
if (hook_list->hook_destroy != G_HOOK_DEFERRED_DESTROY)
hook_list->hook_destroy (hook_list, hook);
}
else if (hook->destroy)
{
hook->destroy (hook->data);
hook->data = NULL;
hook->func = NULL;
hook->destroy = NULL;
}
g_hook_unref (hook_list, hook); /* counterpart to g_hook_insert_before */
}
}
gboolean
g_hook_destroy (GHookList *hook_list,
guint 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->func != NULL);
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,
guint 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)
{
return ((glong) new_hook->hook_id) - ((glong) sibling->hook_id);
}

View File

@ -1,128 +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 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.
*/
/*
* Modified by the GLib Team and others 1997-1999. 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);
}
guint
g_io_add_watch_full (GIOChannel *channel,
gint priority,
GIOCondition condition,
GIOFunc func,
gpointer user_data,
GDestroyNotify notify)
{
g_return_val_if_fail (channel != NULL, 0);
return channel->funcs->io_add_watch (channel, priority, condition,
func, user_data, notify);
}
guint
g_io_add_watch (GIOChannel *channel,
GIOCondition condition,
GIOFunc func,
gpointer user_data)
{
return g_io_add_watch_full (channel, 0, condition, func, user_data, NULL);
}

View File

@ -1,313 +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 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.
*/
/*
* Modified by the GLib Team and others 1997-1999. 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 {
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 guint g_io_unix_add_watch (GIOChannel *channel,
gint priority,
GIOCondition condition,
GIOFunc func,
gpointer user_data,
GDestroyNotify notify);
static gboolean g_io_unix_prepare (gpointer source_data,
GTimeVal *current_time,
gint *timeout,
gpointer user_data);
static gboolean g_io_unix_check (gpointer source_data,
GTimeVal *current_time,
gpointer user_data);
static gboolean g_io_unix_dispatch (gpointer source_data,
GTimeVal *current_time,
gpointer user_data);
static void g_io_unix_destroy (gpointer source_data);
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_add_watch,
g_io_unix_free,
};
static gboolean
g_io_unix_prepare (gpointer source_data,
GTimeVal *current_time,
gint *timeout,
gpointer user_data)
{
*timeout = -1;
return FALSE;
}
static gboolean
g_io_unix_check (gpointer source_data,
GTimeVal *current_time,
gpointer user_data)
{
GIOUnixWatch *data = source_data;
return (data->pollfd.revents & data->condition);
}
static gboolean
g_io_unix_dispatch (gpointer source_data,
GTimeVal *current_time,
gpointer user_data)
{
GIOUnixWatch *data = source_data;
return (*data->callback)(data->channel,
data->pollfd.revents & data->condition,
user_data);
}
static void
g_io_unix_destroy (gpointer source_data)
{
GIOUnixWatch *data = source_data;
g_main_remove_poll (&data->pollfd);
g_io_channel_unref (data->channel);
g_free (data);
}
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:
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:
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 guint
g_io_unix_add_watch (GIOChannel *channel,
gint priority,
GIOCondition condition,
GIOFunc func,
gpointer user_data,
GDestroyNotify notify)
{
GIOUnixWatch *watch = g_new (GIOUnixWatch, 1);
GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
watch->channel = channel;
g_io_channel_ref (channel);
watch->callback = func;
watch->condition = condition;
watch->pollfd.fd = unix_channel->fd;
watch->pollfd.events = condition;
g_main_add_poll (&watch->pollfd, priority);
return g_source_add (priority, TRUE, &unix_watch_funcs, watch, user_data, notify);
}
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;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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 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.
*/
/*
* Modified by the GLib Team and others 1997-1999. 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"
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);
}
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;
}
void
g_list_free (GList *list)
{
if (list)
{
list->data = list->next;
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)
{
if (list)
{
list->data = NULL;
G_LOCK (current_allocator);
list->next = current_allocator->free_lists;
current_allocator->free_lists = list;
G_UNLOCK (current_allocator);
}
}
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,
gpointer 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_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_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;
}
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,
gpointer data)
{
while (list)
{
if (list->data == data)
break;
list = list->next;
}
return list;
}
GList*
g_list_find_custom (GList *list,
gpointer 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,
gpointer 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)
{
(*func) (list->data, user_data);
list = 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,
GCompareFunc compare_func)
{
GList list, *l, *lprev;
l = &list;
lprev = NULL;
while (l1 && l2)
{
if (compare_func (l1->data, l2->data) < 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;
}
GList*
g_list_sort (GList *list,
GCompareFunc compare_func)
{
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 (list, compare_func),
g_list_sort (l2, compare_func),
compare_func);
}
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,
compare_func);
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;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,756 +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 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.
*/
/*
* Modified by the GLib Team and others 1997-1999. 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 <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "glib.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef NATIVE_WIN32
#define STRICT
#include <windows.h>
/* Just use stdio. If we're out of memory, we're hosed anyway. */
#undef write
static inline int
write (FILE *fd,
const char *buf,
int len)
{
fwrite (buf, len, 1, fd);
return len;
}
static void
ensure_stdout_valid (void)
{
HANDLE handle;
handle = GetStdHandle (STD_OUTPUT_HANDLE);
if (handle == INVALID_HANDLE_VALUE)
{
AllocConsole ();
freopen ("CONOUT$", "w", stdout);
}
}
#else
#define ensure_stdout_valid() /* Define as empty */
#endif
/* --- structures --- */
typedef struct _GLogDomain GLogDomain;
typedef struct _GLogHandler GLogHandler;
struct _GLogDomain
{
gchar *log_domain;
GLogLevelFlags fatal_mask;
GLogHandler *handlers;
GLogDomain *next;
};
struct _GLogHandler
{
guint id;
GLogLevelFlags log_level;
GLogFunc log_func;
gpointer data;
GLogHandler *next;
};
/* --- variables --- */
static GMutex* g_messages_lock = NULL;
const gchar *g_log_domain_glib = "GLib";
static GLogDomain *g_log_domains = NULL;
static GLogLevelFlags g_log_always_fatal = G_LOG_FATAL_MASK;
static GPrintFunc glib_print_func = NULL;
static GPrintFunc glib_printerr_func = NULL;
static GErrorFunc glib_error_func = NULL;
static GWarningFunc glib_warning_func = NULL;
static GPrintFunc glib_message_func = NULL;
static GPrivate* g_log_depth = NULL;
/* --- functions --- */
static inline GLogDomain*
g_log_find_domain (const gchar *log_domain)
{
register GLogDomain *domain;
g_mutex_lock (g_messages_lock);
domain = g_log_domains;
while (domain)
{
if (strcmp (domain->log_domain, log_domain) == 0)
{
g_mutex_unlock (g_messages_lock);
return domain;
}
domain = domain->next;
}
g_mutex_unlock (g_messages_lock);
return NULL;
}
static inline GLogDomain*
g_log_domain_new (const gchar *log_domain)
{
register GLogDomain *domain;
domain = g_new (GLogDomain, 1);
domain->log_domain = g_strdup (log_domain);
domain->fatal_mask = G_LOG_FATAL_MASK;
domain->handlers = NULL;
g_mutex_lock (g_messages_lock);
domain->next = g_log_domains;
g_log_domains = domain;
g_mutex_unlock (g_messages_lock);
return domain;
}
static inline void
g_log_domain_check_free (GLogDomain *domain)
{
if (domain->fatal_mask == G_LOG_FATAL_MASK &&
domain->handlers == NULL)
{
register GLogDomain *last, *work;
last = NULL;
g_mutex_lock (g_messages_lock);
work = g_log_domains;
while (work)
{
if (work == domain)
{
if (last)
last->next = domain->next;
else
g_log_domains = domain->next;
g_free (domain->log_domain);
g_free (domain);
break;
}
last = work;
work = last->next;
}
g_mutex_unlock (g_messages_lock);
}
}
static inline GLogFunc
g_log_domain_get_handler (GLogDomain *domain,
GLogLevelFlags log_level,
gpointer *data)
{
if (domain && log_level)
{
register GLogHandler *handler;
handler = domain->handlers;
while (handler)
{
if ((handler->log_level & log_level) == log_level)
{
*data = handler->data;
return handler->log_func;
}
handler = handler->next;
}
}
return g_log_default_handler;
}
GLogLevelFlags
g_log_set_always_fatal (GLogLevelFlags fatal_mask)
{
GLogLevelFlags old_mask;
/* restrict the global mask to levels that are known to glib */
fatal_mask &= (1 << G_LOG_LEVEL_USER_SHIFT) - 1;
/* force errors to be fatal */
fatal_mask |= G_LOG_LEVEL_ERROR;
/* remove bogus flag */
fatal_mask &= ~G_LOG_FLAG_FATAL;
g_mutex_lock (g_messages_lock);
old_mask = g_log_always_fatal;
g_log_always_fatal = fatal_mask;
g_mutex_unlock (g_messages_lock);
return old_mask;
}
GLogLevelFlags
g_log_set_fatal_mask (const gchar *log_domain,
GLogLevelFlags fatal_mask)
{
GLogLevelFlags old_flags;
register GLogDomain *domain;
if (!log_domain)
log_domain = "";
/* force errors to be fatal */
fatal_mask |= G_LOG_LEVEL_ERROR;
/* remove bogus flag */
fatal_mask &= ~G_LOG_FLAG_FATAL;
domain = g_log_find_domain (log_domain);
if (!domain)
domain = g_log_domain_new (log_domain);
old_flags = domain->fatal_mask;
domain->fatal_mask = fatal_mask;
g_log_domain_check_free (domain);
return old_flags;
}
guint
g_log_set_handler (const gchar *log_domain,
GLogLevelFlags log_levels,
GLogFunc log_func,
gpointer user_data)
{
register GLogDomain *domain;
register GLogHandler *handler;
static guint handler_id = 0;
g_return_val_if_fail ((log_levels & G_LOG_LEVEL_MASK) != 0, 0);
g_return_val_if_fail (log_func != NULL, 0);
if (!log_domain)
log_domain = "";
domain = g_log_find_domain (log_domain);
if (!domain)
domain = g_log_domain_new (log_domain);
handler = g_new (GLogHandler, 1);
g_mutex_lock (g_messages_lock);
handler->id = ++handler_id;
g_mutex_unlock (g_messages_lock);
handler->log_level = log_levels;
handler->log_func = log_func;
handler->data = user_data;
handler->next = domain->handlers;
domain->handlers = handler;
return handler_id;
}
void
g_log_remove_handler (const gchar *log_domain,
guint handler_id)
{
register GLogDomain *domain;
g_return_if_fail (handler_id > 0);
if (!log_domain)
log_domain = "";
domain = g_log_find_domain (log_domain);
if (domain)
{
register GLogHandler *work, *last;
last = NULL;
work = domain->handlers;
while (work)
{
if (work->id == handler_id)
{
if (last)
last->next = work->next;
else
domain->handlers = work->next;
g_free (work);
g_log_domain_check_free (domain);
return;
}
last = work;
work = last->next;
}
}
g_warning ("g_log_remove_handler(): could not find handler with id `%d' for domain \"%s\"",
handler_id,
log_domain);
}
void
g_logv (const gchar *log_domain,
GLogLevelFlags log_level,
const gchar *format,
va_list args1)
{
va_list args2;
gchar buffer[1025];
register gint i;
log_level &= G_LOG_LEVEL_MASK;
if (!log_level)
return;
/* we use a stack buffer of fixed size, because we might get called
* recursively.
*/
G_VA_COPY (args2, args1);
if (g_printf_string_upper_bound (format, args1) < 1024)
vsprintf (buffer, format, args2);
else
{
/* since we might be out of memory, we can't use g_vsnprintf(). */
#ifdef HAVE_VSNPRINTF
vsnprintf (buffer, 1024, format, args2);
#else /* !HAVE_VSNPRINTF */
/* we are out of luck here */
strncpy (buffer, format, 1024);
#endif /* !HAVE_VSNPRINTF */
buffer[1024] = 0;
}
va_end (args2);
for (i = g_bit_nth_msf (log_level, -1); i >= 0; i = g_bit_nth_msf (log_level, i))
{
register GLogLevelFlags test_level;
test_level = 1 << i;
if (log_level & test_level)
{
guint depth = GPOINTER_TO_UINT (g_private_get (g_log_depth));
GLogDomain *domain;
GLogFunc log_func;
gpointer data = NULL;
domain = g_log_find_domain (log_domain ? log_domain : "");
if (depth)
test_level |= G_LOG_FLAG_RECURSION;
depth++;
g_private_set (g_log_depth, GUINT_TO_POINTER (depth));
g_mutex_lock (g_messages_lock);
if ((((domain ? domain->fatal_mask : G_LOG_FATAL_MASK) |
g_log_always_fatal) & test_level) != 0)
test_level |= G_LOG_FLAG_FATAL;
g_mutex_unlock (g_messages_lock);
log_func = g_log_domain_get_handler (domain, test_level, &data);
log_func (log_domain, test_level, buffer, data);
/* *domain can be cluttered now */
if (test_level & G_LOG_FLAG_FATAL)
abort ();
depth--;
g_private_set (g_log_depth, GUINT_TO_POINTER (depth));
}
}
}
void
g_log (const gchar *log_domain,
GLogLevelFlags log_level,
const gchar *format,
...)
{
va_list args;
va_start (args, format);
g_logv (log_domain, log_level, format, args);
va_end (args);
}
void
g_log_default_handler (const gchar *log_domain,
GLogLevelFlags log_level,
const gchar *message,
gpointer unused_data)
{
#ifdef NATIVE_WIN32
FILE *fd;
#else
gint fd;
#endif
gboolean in_recursion;
gboolean is_fatal;
GErrorFunc local_glib_error_func;
GWarningFunc local_glib_warning_func;
GPrintFunc local_glib_message_func;
in_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0;
is_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
log_level &= G_LOG_LEVEL_MASK;
if (!message)
message = "g_log_default_handler(): (NULL) message";
#ifdef NATIVE_WIN32
/* Use just stdout as stderr is hard to get redirected from the
* DOS prompt.
*/
fd = stdout;
#else
fd = (log_level >= G_LOG_LEVEL_MESSAGE) ? 1 : 2;
#endif
g_mutex_lock (g_messages_lock);
local_glib_error_func = glib_error_func;
local_glib_warning_func = glib_warning_func;
local_glib_message_func = glib_message_func;
g_mutex_unlock (g_messages_lock);
switch (log_level)
{
case G_LOG_LEVEL_ERROR:
if (!log_domain && local_glib_error_func)
{
/* compatibility code */
local_glib_error_func (message);
return;
}
/* use write(2) for output, in case we are out of memeory */
ensure_stdout_valid ();
if (log_domain)
{
write (fd, "\n", 1);
write (fd, log_domain, strlen (log_domain));
write (fd, "-", 1);
}
else
write (fd, "\n** ", 4);
if (in_recursion)
write (fd, "ERROR (recursed) **: ", 21);
else
write (fd, "ERROR **: ", 10);
write (fd, message, strlen(message));
if (is_fatal)
write (fd, "\naborting...\n", 13);
else
write (fd, "\n", 1);
break;
case G_LOG_LEVEL_CRITICAL:
ensure_stdout_valid ();
if (log_domain)
{
write (fd, "\n", 1);
write (fd, log_domain, strlen (log_domain));
write (fd, "-", 1);
}
else
write (fd, "\n** ", 4);
if (in_recursion)
write (fd, "CRITICAL (recursed) **: ", 24);
else
write (fd, "CRITICAL **: ", 13);
write (fd, message, strlen(message));
if (is_fatal)
write (fd, "\naborting...\n", 13);
else
write (fd, "\n", 1);
break;
case G_LOG_LEVEL_WARNING:
if (!log_domain && local_glib_warning_func)
{
/* compatibility code */
local_glib_warning_func (message);
return;
}
ensure_stdout_valid ();
if (log_domain)
{
write (fd, "\n", 1);
write (fd, log_domain, strlen (log_domain));
write (fd, "-", 1);
}
else
write (fd, "\n** ", 4);
if (in_recursion)
write (fd, "WARNING (recursed) **: ", 23);
else
write (fd, "WARNING **: ", 12);
write (fd, message, strlen(message));
if (is_fatal)
write (fd, "\naborting...\n", 13);
else
write (fd, "\n", 1);
break;
case G_LOG_LEVEL_MESSAGE:
if (!log_domain && local_glib_message_func)
{
/* compatibility code */
local_glib_message_func (message);
return;
}
ensure_stdout_valid ();
if (log_domain)
{
write (fd, log_domain, strlen (log_domain));
write (fd, "-", 1);
}
if (in_recursion)
write (fd, "Message (recursed): ", 20);
else
write (fd, "Message: ", 9);
write (fd, message, strlen(message));
if (is_fatal)
write (fd, "\naborting...\n", 13);
else
write (fd, "\n", 1);
break;
case G_LOG_LEVEL_INFO:
ensure_stdout_valid ();
if (log_domain)
{
write (fd, log_domain, strlen (log_domain));
write (fd, "-", 1);
}
if (in_recursion)
write (fd, "INFO (recursed): ", 17);
else
write (fd, "INFO: ", 6);
write (fd, message, strlen(message));
if (is_fatal)
write (fd, "\naborting...\n", 13);
else
write (fd, "\n", 1);
break;
case G_LOG_LEVEL_DEBUG:
ensure_stdout_valid ();
if (log_domain)
{
write (fd, log_domain, strlen (log_domain));
write (fd, "-", 1);
}
if (in_recursion)
write (fd, "DEBUG (recursed): ", 18);
else
write (fd, "DEBUG: ", 7);
write (fd, message, strlen(message));
if (is_fatal)
write (fd, "\naborting...\n", 13);
else
write (fd, "\n", 1);
break;
default:
/* we are used for a log level that is not defined by GLib itself,
* try to make the best out of it.
*/
ensure_stdout_valid ();
if (log_domain)
{
write (fd, log_domain, strlen (log_domain));
if (in_recursion)
write (fd, "-LOG (recursed:", 15);
else
write (fd, "-LOG (", 6);
}
else if (in_recursion)
write (fd, "LOG (recursed:", 14);
else
write (fd, "LOG (", 5);
if (log_level)
{
gchar string[] = "0x00): ";
gchar *p = string + 2;
guint i;
i = g_bit_nth_msf (log_level, -1);
*p = i >> 4;
p++;
*p = '0' + (i & 0xf);
if (*p > '9')
*p += 'A' - '9' - 1;
write (fd, string, 7);
}
else
write (fd, "): ", 3);
write (fd, message, strlen(message));
if (is_fatal)
write (fd, "\naborting...\n", 13);
else
write (fd, "\n", 1);
break;
}
}
GPrintFunc
g_set_print_handler (GPrintFunc func)
{
GPrintFunc old_print_func;
g_mutex_lock (g_messages_lock);
old_print_func = glib_print_func;
glib_print_func = func;
g_mutex_unlock (g_messages_lock);
return old_print_func;
}
void
g_print (const gchar *format,
...)
{
va_list args;
gchar *string;
GPrintFunc local_glib_print_func;
g_return_if_fail (format != NULL);
va_start (args, format);
string = g_strdup_vprintf (format, args);
va_end (args);
g_mutex_lock (g_messages_lock);
local_glib_print_func = glib_print_func;
g_mutex_unlock (g_messages_lock);
if (local_glib_print_func)
local_glib_print_func (string);
else
{
ensure_stdout_valid ();
fputs (string, stdout);
fflush (stdout);
}
g_free (string);
}
GPrintFunc
g_set_printerr_handler (GPrintFunc func)
{
GPrintFunc old_printerr_func;
g_mutex_lock (g_messages_lock);
old_printerr_func = glib_printerr_func;
glib_printerr_func = func;
g_mutex_unlock (g_messages_lock);
return old_printerr_func;
}
void
g_printerr (const gchar *format,
...)
{
va_list args;
gchar *string;
GPrintFunc local_glib_printerr_func;
g_return_if_fail (format != NULL);
va_start (args, format);
string = g_strdup_vprintf (format, args);
va_end (args);
g_mutex_lock (g_messages_lock);
local_glib_printerr_func = glib_printerr_func;
g_mutex_unlock (g_messages_lock);
if (local_glib_printerr_func)
local_glib_printerr_func (string);
else
{
fputs (string, stderr);
fflush (stderr);
}
g_free (string);
}
/* compatibility code */
GErrorFunc
g_set_error_handler (GErrorFunc func)
{
GErrorFunc old_error_func;
g_mutex_lock (g_messages_lock);
old_error_func = glib_error_func;
glib_error_func = func;
g_mutex_unlock (g_messages_lock);
return old_error_func;
}
/* compatibility code */
GWarningFunc
g_set_warning_handler (GWarningFunc func)
{
GWarningFunc old_warning_func;
g_mutex_lock (g_messages_lock);
old_warning_func = glib_warning_func;
glib_warning_func = func;
g_mutex_unlock (g_messages_lock);
return old_warning_func;
}
/* compatibility code */
GPrintFunc
g_set_message_handler (GPrintFunc func)
{
GPrintFunc old_message_func;
g_mutex_lock (g_messages_lock);
old_message_func = glib_message_func;
glib_message_func = func;
g_mutex_unlock (g_messages_lock);
return old_message_func;
}
void
g_messages_init (void)
{
g_messages_lock = g_mutex_new();
g_log_depth = g_private_new(NULL);
}

View File

@ -1,965 +0,0 @@
/* GLIB - Library of useful routines for C programming
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* GNode: N-way tree implementation.
* Copyright (C) 1998 Tim Janik
*
* 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.
*/
/*
* Modified by the GLib Team and others 1997-1999. 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"
/* node allocation
*/
struct _GAllocator /* from gmem.c */
{
gchar *name;
guint16 n_preallocs;
guint is_unused : 1;
guint type : 4;
GAllocator *last;
GMemChunk *mem_chunk;
GNode *free_nodes; /* implementation specific */
};
G_LOCK_DEFINE_STATIC (current_allocator);
static GAllocator *current_allocator = NULL;
/* HOLDS: current_allocator_lock */
static void
g_node_validate_allocator (GAllocator *allocator)
{
g_return_if_fail (allocator != NULL);
g_return_if_fail (allocator->is_unused == TRUE);
if (allocator->type != G_ALLOCATOR_NODE)
{
allocator->type = G_ALLOCATOR_NODE;
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 (GNode),
sizeof (GNode) * allocator->n_preallocs,
G_ALLOC_ONLY);
allocator->free_nodes = NULL;
}
allocator->is_unused = FALSE;
}
void
g_node_push_allocator (GAllocator *allocator)
{
G_LOCK (current_allocator);
g_node_validate_allocator ( allocator );
allocator->last = current_allocator;
current_allocator = allocator;
G_UNLOCK (current_allocator);
}
void
g_node_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);
}
/* --- functions --- */
GNode*
g_node_new (gpointer data)
{
GNode *node;
G_LOCK (current_allocator);
if (!current_allocator)
{
GAllocator *allocator = g_allocator_new ("GLib default GNode allocator",
128);
g_node_validate_allocator (allocator);
allocator->last = NULL;
current_allocator = allocator;
}
if (!current_allocator->free_nodes)
node = g_chunk_new (GNode, current_allocator->mem_chunk);
else
{
node = current_allocator->free_nodes;
current_allocator->free_nodes = node->next;
}
G_UNLOCK (current_allocator);
node->data = data;
node->next = NULL;
node->prev = NULL;
node->parent = NULL;
node->children = NULL;
return node;
}
static void
g_nodes_free (GNode *node)
{
GNode *parent;
parent = node;
while (1)
{
if (parent->children)
g_nodes_free (parent->children);
if (parent->next)
parent = parent->next;
else
break;
}
G_LOCK (current_allocator);
parent->next = current_allocator->free_nodes;
current_allocator->free_nodes = node;
G_UNLOCK (current_allocator);
}
void
g_node_destroy (GNode *root)
{
g_return_if_fail (root != NULL);
if (!G_NODE_IS_ROOT (root))
g_node_unlink (root);
g_nodes_free (root);
}
void
g_node_unlink (GNode *node)
{
g_return_if_fail (node != NULL);
if (node->prev)
node->prev->next = node->next;
else if (node->parent)
node->parent->children = node->next;
node->parent = NULL;
if (node->next)
{
node->next->prev = node->prev;
node->next = NULL;
}
node->prev = NULL;
}
GNode*
g_node_insert (GNode *parent,
gint position,
GNode *node)
{
g_return_val_if_fail (parent != NULL, node);
g_return_val_if_fail (node != NULL, node);
g_return_val_if_fail (G_NODE_IS_ROOT (node), node);
if (position > 0)
return g_node_insert_before (parent,
g_node_nth_child (parent, position),
node);
else if (position == 0)
return g_node_prepend (parent, node);
else /* if (position < 0) */
return g_node_append (parent, node);
}
GNode*
g_node_insert_before (GNode *parent,
GNode *sibling,
GNode *node)
{
g_return_val_if_fail (parent != NULL, node);
g_return_val_if_fail (node != NULL, node);
g_return_val_if_fail (G_NODE_IS_ROOT (node), node);
if (sibling)
g_return_val_if_fail (sibling->parent == parent, node);
node->parent = parent;
if (sibling)
{
if (sibling->prev)
{
node->prev = sibling->prev;
node->prev->next = node;
node->next = sibling;
sibling->prev = node;
}
else
{
node->parent->children = node;
node->next = sibling;
sibling->prev = node;
}
}
else
{
if (parent->children)
{
sibling = parent->children;
while (sibling->next)
sibling = sibling->next;
node->prev = sibling;
sibling->next = node;
}
else
node->parent->children = node;
}
return node;
}
GNode*
g_node_prepend (GNode *parent,
GNode *node)
{
g_return_val_if_fail (parent != NULL, node);
return g_node_insert_before (parent, parent->children, node);
}
GNode*
g_node_get_root (GNode *node)
{
g_return_val_if_fail (node != NULL, NULL);
while (node->parent)
node = node->parent;
return node;
}
gboolean
g_node_is_ancestor (GNode *node,
GNode *descendant)
{
g_return_val_if_fail (node != NULL, FALSE);
g_return_val_if_fail (descendant != NULL, FALSE);
while (descendant)
{
if (descendant->parent == node)
return TRUE;
descendant = descendant->parent;
}
return FALSE;
}
/* returns 1 for root, 2 for first level children,
* 3 for children's children...
*/
guint
g_node_depth (GNode *node)
{
register guint depth = 0;
while (node)
{
depth++;
node = node->parent;
}
return depth;
}
void
g_node_reverse_children (GNode *node)
{
GNode *child;
GNode *last;
g_return_if_fail (node != NULL);
child = node->children;
last = NULL;
while (child)
{
last = child;
child = last->next;
last->next = last->prev;
last->prev = child;
}
node->children = last;
}
guint
g_node_max_height (GNode *root)
{
register GNode *child;
register guint max_height = 0;
if (!root)
return 0;
child = root->children;
while (child)
{
register guint tmp_height;
tmp_height = g_node_max_height (child);
if (tmp_height > max_height)
max_height = tmp_height;
child = child->next;
}
return max_height + 1;
}
static gboolean
g_node_traverse_pre_order (GNode *node,
GTraverseFlags flags,
GNodeTraverseFunc func,
gpointer data)
{
if (node->children)
{
GNode *child;
if ((flags & G_TRAVERSE_NON_LEAFS) &&
func (node, data))
return TRUE;
child = node->children;
while (child)
{
register GNode *current;
current = child;
child = current->next;
if (g_node_traverse_pre_order (current, flags, func, data))
return TRUE;
}
}
else if ((flags & G_TRAVERSE_LEAFS) &&
func (node, data))
return TRUE;
return FALSE;
}
static gboolean
g_node_depth_traverse_pre_order (GNode *node,
GTraverseFlags flags,
guint depth,
GNodeTraverseFunc func,
gpointer data)
{
if (node->children)
{
GNode *child;
if ((flags & G_TRAVERSE_NON_LEAFS) &&
func (node, data))
return TRUE;
depth--;
if (!depth)
return FALSE;
child = node->children;
while (child)
{
register GNode *current;
current = child;
child = current->next;
if (g_node_depth_traverse_pre_order (current, flags, depth, func, data))
return TRUE;
}
}
else if ((flags & G_TRAVERSE_LEAFS) &&
func (node, data))
return TRUE;
return FALSE;
}
static gboolean
g_node_traverse_post_order (GNode *node,
GTraverseFlags flags,
GNodeTraverseFunc func,
gpointer data)
{
if (node->children)
{
GNode *child;
child = node->children;
while (child)
{
register GNode *current;
current = child;
child = current->next;
if (g_node_traverse_post_order (current, flags, func, data))
return TRUE;
}
if ((flags & G_TRAVERSE_NON_LEAFS) &&
func (node, data))
return TRUE;
}
else if ((flags & G_TRAVERSE_LEAFS) &&
func (node, data))
return TRUE;
return FALSE;
}
static gboolean
g_node_depth_traverse_post_order (GNode *node,
GTraverseFlags flags,
guint depth,
GNodeTraverseFunc func,
gpointer data)
{
if (node->children)
{
depth--;
if (depth)
{
GNode *child;
child = node->children;
while (child)
{
register GNode *current;
current = child;
child = current->next;
if (g_node_depth_traverse_post_order (current, flags, depth, func, data))
return TRUE;
}
}
if ((flags & G_TRAVERSE_NON_LEAFS) &&
func (node, data))
return TRUE;
}
else if ((flags & G_TRAVERSE_LEAFS) &&
func (node, data))
return TRUE;
return FALSE;
}
static gboolean
g_node_traverse_in_order (GNode *node,
GTraverseFlags flags,
GNodeTraverseFunc func,
gpointer data)
{
if (node->children)
{
GNode *child;
register GNode *current;
child = node->children;
current = child;
child = current->next;
if (g_node_traverse_in_order (current, flags, func, data))
return TRUE;
if ((flags & G_TRAVERSE_NON_LEAFS) &&
func (node, data))
return TRUE;
while (child)
{
current = child;
child = current->next;
if (g_node_traverse_in_order (current, flags, func, data))
return TRUE;
}
}
else if ((flags & G_TRAVERSE_LEAFS) &&
func (node, data))
return TRUE;
return FALSE;
}
static gboolean
g_node_depth_traverse_in_order (GNode *node,
GTraverseFlags flags,
guint depth,
GNodeTraverseFunc func,
gpointer data)
{
if (node->children)
{
depth--;
if (depth)
{
GNode *child;
register GNode *current;
child = node->children;
current = child;
child = current->next;
if (g_node_depth_traverse_in_order (current, flags, depth, func, data))
return TRUE;
if ((flags & G_TRAVERSE_NON_LEAFS) &&
func (node, data))
return TRUE;
while (child)
{
current = child;
child = current->next;
if (g_node_depth_traverse_in_order (current, flags, depth, func, data))
return TRUE;
}
}
else if ((flags & G_TRAVERSE_NON_LEAFS) &&
func (node, data))
return TRUE;
}
else if ((flags & G_TRAVERSE_LEAFS) &&
func (node, data))
return TRUE;
return FALSE;
}
static gboolean
g_node_traverse_children (GNode *node,
GTraverseFlags flags,
GNodeTraverseFunc func,
gpointer data)
{
GNode *child;
child = node->children;
while (child)
{
register GNode *current;
current = child;
child = current->next;
if (current->children)
{
if ((flags & G_TRAVERSE_NON_LEAFS) &&
func (current, data))
return TRUE;
}
else if ((flags & G_TRAVERSE_LEAFS) &&
func (current, data))
return TRUE;
}
child = node->children;
while (child)
{
register GNode *current;
current = child;
child = current->next;
if (current->children &&
g_node_traverse_children (current, flags, func, data))
return TRUE;
}
return FALSE;
}
static gboolean
g_node_depth_traverse_children (GNode *node,
GTraverseFlags flags,
guint depth,
GNodeTraverseFunc func,
gpointer data)
{
GNode *child;
child = node->children;
while (child)
{
register GNode *current;
current = child;
child = current->next;
if (current->children)
{
if ((flags & G_TRAVERSE_NON_LEAFS) &&
func (current, data))
return TRUE;
}
else if ((flags & G_TRAVERSE_LEAFS) &&
func (current, data))
return TRUE;
}
depth--;
if (!depth)
return FALSE;
child = node->children;
while (child)
{
register GNode *current;
current = child;
child = current->next;
if (current->children &&
g_node_depth_traverse_children (current, flags, depth, func, data))
return TRUE;
}
return FALSE;
}
void
g_node_traverse (GNode *root,
GTraverseType order,
GTraverseFlags flags,
gint depth,
GNodeTraverseFunc func,
gpointer data)
{
g_return_if_fail (root != NULL);
g_return_if_fail (func != NULL);
g_return_if_fail (order <= G_LEVEL_ORDER);
g_return_if_fail (flags <= G_TRAVERSE_MASK);
g_return_if_fail (depth == -1 || depth > 0);
switch (order)
{
case G_PRE_ORDER:
if (depth < 0)
g_node_traverse_pre_order (root, flags, func, data);
else
g_node_depth_traverse_pre_order (root, flags, depth, func, data);
break;
case G_POST_ORDER:
if (depth < 0)
g_node_traverse_post_order (root, flags, func, data);
else
g_node_depth_traverse_post_order (root, flags, depth, func, data);
break;
case G_IN_ORDER:
if (depth < 0)
g_node_traverse_in_order (root, flags, func, data);
else
g_node_depth_traverse_in_order (root, flags, depth, func, data);
break;
case G_LEVEL_ORDER:
if (root->children)
{
if (!((flags & G_TRAVERSE_NON_LEAFS) &&
func (root, data)))
{
if (depth < 0)
g_node_traverse_children (root, flags, func, data);
else
{
depth--;
if (depth)
g_node_depth_traverse_children (root, flags, depth, func, data);
}
}
}
else if (flags & G_TRAVERSE_LEAFS)
func (root, data);
break;
}
}
static gboolean
g_node_find_func (GNode *node,
gpointer data)
{
register gpointer *d = data;
if (*d != node->data)
return FALSE;
*(++d) = node;
return TRUE;
}
GNode*
g_node_find (GNode *root,
GTraverseType order,
GTraverseFlags flags,
gpointer data)
{
gpointer d[2];
g_return_val_if_fail (root != NULL, NULL);
g_return_val_if_fail (order <= G_LEVEL_ORDER, NULL);
g_return_val_if_fail (flags <= G_TRAVERSE_MASK, NULL);
d[0] = data;
d[1] = NULL;
g_node_traverse (root, order, flags, -1, g_node_find_func, d);
return d[1];
}
static void
g_node_count_func (GNode *node,
GTraverseFlags flags,
guint *n)
{
if (node->children)
{
GNode *child;
if (flags & G_TRAVERSE_NON_LEAFS)
(*n)++;
child = node->children;
while (child)
{
g_node_count_func (child, flags, n);
child = child->next;
}
}
else if (flags & G_TRAVERSE_LEAFS)
(*n)++;
}
guint
g_node_n_nodes (GNode *root,
GTraverseFlags flags)
{
guint n = 0;
g_return_val_if_fail (root != NULL, 0);
g_return_val_if_fail (flags <= G_TRAVERSE_MASK, 0);
g_node_count_func (root, flags, &n);
return n;
}
GNode*
g_node_last_child (GNode *node)
{
g_return_val_if_fail (node != NULL, NULL);
node = node->children;
if (node)
while (node->next)
node = node->next;
return node;
}
GNode*
g_node_nth_child (GNode *node,
guint n)
{
g_return_val_if_fail (node != NULL, NULL);
node = node->children;
if (node)
while ((n-- > 0) && node)
node = node->next;
return node;
}
guint
g_node_n_children (GNode *node)
{
guint n = 0;
g_return_val_if_fail (node != NULL, 0);
node = node->children;
while (node)
{
n++;
node = node->next;
}
return n;
}
GNode*
g_node_find_child (GNode *node,
GTraverseFlags flags,
gpointer data)
{
g_return_val_if_fail (node != NULL, NULL);
g_return_val_if_fail (flags <= G_TRAVERSE_MASK, NULL);
node = node->children;
while (node)
{
if (node->data == data)
{
if (G_NODE_IS_LEAF (node))
{
if (flags & G_TRAVERSE_LEAFS)
return node;
}
else
{
if (flags & G_TRAVERSE_NON_LEAFS)
return node;
}
}
node = node->next;
}
return NULL;
}
gint
g_node_child_position (GNode *node,
GNode *child)
{
register guint n = 0;
g_return_val_if_fail (node != NULL, -1);
g_return_val_if_fail (child != NULL, -1);
g_return_val_if_fail (child->parent == node, -1);
node = node->children;
while (node)
{
if (node == child)
return n;
n++;
node = node->next;
}
return -1;
}
gint
g_node_child_index (GNode *node,
gpointer data)
{
register guint n = 0;
g_return_val_if_fail (node != NULL, -1);
node = node->children;
while (node)
{
if (node->data == data)
return n;
n++;
node = node->next;
}
return -1;
}
GNode*
g_node_first_sibling (GNode *node)
{
g_return_val_if_fail (node != NULL, NULL);
while (node->prev)
node = node->prev;
return node;
}
GNode*
g_node_last_sibling (GNode *node)
{
g_return_val_if_fail (node != NULL, NULL);
while (node->next)
node = node->next;
return node;
}
void
g_node_children_foreach (GNode *node,
GTraverseFlags flags,
GNodeForeachFunc func,
gpointer data)
{
g_return_if_fail (node != NULL);
g_return_if_fail (flags <= G_TRAVERSE_MASK);
g_return_if_fail (func != NULL);
node = node->children;
while (node)
{
register GNode *current;
current = node;
node = current->next;
if (G_NODE_IS_LEAF (current))
{
if (flags & G_TRAVERSE_LEAFS)
func (current, data);
}
else
{
if (flags & G_TRAVERSE_NON_LEAFS)
func (current, data);
}
}
}

View File

@ -1,83 +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 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.
*/
/*
* Modified by the GLib Team and others 1997-1999. 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"
static const guint g_primes[] =
{
11,
19,
37,
73,
109,
163,
251,
367,
557,
823,
1237,
1861,
2777,
4177,
6247,
9371,
14057,
21089,
31627,
47431,
71143,
106721,
160073,
240101,
360163,
540217,
810343,
1215497,
1823231,
2734867,
4102283,
6153409,
9230113,
13845163,
};
static const guint g_nprimes = sizeof (g_primes) / sizeof (g_primes[0]);
guint
g_spaced_primes_closest (guint num)
{
gint i;
for (i = 0; i < g_nprimes; i++)
if (g_primes[i] > num)
return g_primes[i];
return g_primes[g_nprimes - 1];
}

View File

@ -1,459 +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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* Modified by the GLib Team and others 1997-1999. 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 <stdarg.h>
#include <string.h>
typedef struct _GRealRelation GRealRelation;
typedef struct _GRealTuples GRealTuples;
struct _GRealRelation
{
gint fields;
gint current_field;
GHashTable *all_tuples;
GHashTable **hashed_tuple_tables;
GMemChunk *tuple_chunk;
gint count;
};
struct _GRealTuples
{
gint len;
gint width;
gpointer *data;
};
static gboolean
tuple_equal_2 (gconstpointer v_a,
gconstpointer v_b)
{
gpointer* a = (gpointer*) v_a;
gpointer* b = (gpointer*) v_b;
return a[0] == b[0] && a[1] == b[1];
}
static guint
tuple_hash_2 (gconstpointer v_a)
{
gpointer* a = (gpointer*) v_a;
return (gulong)a[0] ^ (gulong)a[1];
}
static GHashFunc
tuple_hash (gint fields)
{
switch (fields)
{
case 2:
return tuple_hash_2;
default:
g_error ("no tuple hash for %d", fields);
}
return NULL;
}
static GCompareFunc
tuple_equal (gint fields)
{
switch (fields)
{
case 2:
return tuple_equal_2;
default:
g_error ("no tuple equal for %d", fields);
}
return NULL;
}
GRelation*
g_relation_new (gint fields)
{
GRealRelation* rel = g_new0 (GRealRelation, 1);
rel->fields = fields;
rel->tuple_chunk = g_mem_chunk_new ("Relation Chunk",
fields * sizeof (gpointer),
fields * sizeof (gpointer) * 128,
G_ALLOC_AND_FREE);
rel->all_tuples = g_hash_table_new (tuple_hash (fields), tuple_equal (fields));
rel->hashed_tuple_tables = g_new0 (GHashTable*, fields);
return (GRelation*) rel;
}
static void
g_relation_free_array (gpointer key, gpointer value, gpointer user_data)
{
g_hash_table_destroy ((GHashTable*) value);
}
void
g_relation_destroy (GRelation *relation)
{
GRealRelation *rel = (GRealRelation *) relation;
gint i;
if (rel)
{
g_hash_table_destroy (rel->all_tuples);
g_mem_chunk_destroy (rel->tuple_chunk);
for (i = 0; i < rel->fields; i += 1)
{
if (rel->hashed_tuple_tables[i])
{
g_hash_table_foreach (rel->hashed_tuple_tables[i], g_relation_free_array, NULL);
g_hash_table_destroy (rel->hashed_tuple_tables[i]);
}
}
g_free (rel->hashed_tuple_tables);
g_free (rel);
}
}
void
g_relation_index (GRelation *relation,
gint field,
GHashFunc hash_func,
GCompareFunc key_compare_func)
{
GRealRelation *rel = (GRealRelation *) relation;
g_return_if_fail (relation != NULL);
g_return_if_fail (rel->count == 0 && rel->hashed_tuple_tables[field] == NULL);
rel->hashed_tuple_tables[field] = g_hash_table_new (hash_func, key_compare_func);
}
void
g_relation_insert (GRelation *relation,
...)
{
GRealRelation *rel = (GRealRelation *) relation;
gpointer* tuple = g_chunk_new (gpointer, rel->tuple_chunk);
va_list args;
gint i;
va_start(args, relation);
for (i = 0; i < rel->fields; i += 1)
tuple[i] = va_arg(args, gpointer);
va_end(args);
g_hash_table_insert (rel->all_tuples, tuple, tuple);
rel->count += 1;
for (i = 0; i < rel->fields; i += 1)
{
GHashTable *table;
gpointer key;
GHashTable *per_key_table;
table = rel->hashed_tuple_tables[i];
if (table == NULL)
continue;
key = tuple[i];
per_key_table = g_hash_table_lookup (table, key);
if (per_key_table == NULL)
{
per_key_table = g_hash_table_new (tuple_hash (rel->fields), tuple_equal (rel->fields));
g_hash_table_insert (table, key, per_key_table);
}
g_hash_table_insert (per_key_table, tuple, tuple);
}
}
static void
g_relation_delete_tuple (gpointer tuple_key,
gpointer tuple_value,
gpointer user_data)
{
gpointer *tuple = (gpointer*) tuple_value;
GRealRelation *rel = (GRealRelation *) user_data;
gint j;
g_assert (tuple_key == tuple_value);
for (j = 0; j < rel->fields; j += 1)
{
GHashTable *one_table = rel->hashed_tuple_tables[j];
gpointer one_key;
GHashTable *per_key_table;
if (one_table == NULL)
continue;
if (j == rel->current_field)
/* can't delete from the table we're foreaching in */
continue;
one_key = tuple[j];
per_key_table = g_hash_table_lookup (one_table, one_key);
g_hash_table_remove (per_key_table, tuple);
}
g_hash_table_remove (rel->all_tuples, tuple);
rel->count -= 1;
}
gint
g_relation_delete (GRelation *relation,
gconstpointer key,
gint field)
{
GRealRelation *rel = (GRealRelation *) relation;
GHashTable *table = rel->hashed_tuple_tables[field];
GHashTable *key_table;
gint count = rel->count;
g_return_val_if_fail (relation != NULL, 0);
g_return_val_if_fail (table != NULL, 0);
key_table = g_hash_table_lookup (table, key);
if (!key_table)
return 0;
rel->current_field = field;
g_hash_table_foreach (key_table, g_relation_delete_tuple, rel);
g_hash_table_remove (table, key);
g_hash_table_destroy (key_table);
/* @@@ FIXME: Remove empty hash tables. */
return count - rel->count;
}
static void
g_relation_select_tuple (gpointer tuple_key,
gpointer tuple_value,
gpointer user_data)
{
gpointer *tuple = (gpointer*) tuple_value;
GRealTuples *tuples = (GRealTuples*) user_data;
gint stride = sizeof (gpointer) * tuples->width;
g_assert (tuple_key == tuple_value);
memcpy (tuples->data + (tuples->len * tuples->width),
tuple,
stride);
tuples->len += 1;
}
GTuples*
g_relation_select (GRelation *relation,
gconstpointer key,
gint field)
{
GRealRelation *rel = (GRealRelation *) relation;
GHashTable *table = rel->hashed_tuple_tables[field];
GHashTable *key_table;
GRealTuples *tuples = g_new0 (GRealTuples, 1);
gint count;
g_return_val_if_fail (relation != NULL, NULL);
g_return_val_if_fail (table != NULL, NULL);
key_table = g_hash_table_lookup (table, key);
if (!key_table)
return (GTuples*)tuples;
count = g_relation_count (relation, key, field);
tuples->data = g_malloc (sizeof (gpointer) * rel->fields * count);
tuples->width = rel->fields;
g_hash_table_foreach (key_table, g_relation_select_tuple, tuples);
g_assert (count == tuples->len);
return (GTuples*)tuples;
}
gint
g_relation_count (GRelation *relation,
gconstpointer key,
gint field)
{
GRealRelation *rel = (GRealRelation *) relation;
GHashTable *table = rel->hashed_tuple_tables[field];
GHashTable *key_table;
g_return_val_if_fail (relation != NULL, 0);
g_return_val_if_fail (table != NULL, 0);
key_table = g_hash_table_lookup (table, key);
if (!key_table)
return 0;
return g_hash_table_size (key_table);
}
gboolean
g_relation_exists (GRelation *relation, ...)
{
GRealRelation *rel = (GRealRelation *) relation;
gpointer* tuple = g_chunk_new (gpointer, rel->tuple_chunk);
va_list args;
gint i;
gboolean result;
va_start(args, relation);
for (i = 0; i < rel->fields; i += 1)
tuple[i] = va_arg(args, gpointer);
va_end(args);
result = g_hash_table_lookup (rel->all_tuples, tuple) != NULL;
g_mem_chunk_free (rel->tuple_chunk, tuple);
return result;
}
void
g_tuples_destroy (GTuples *tuples0)
{
GRealTuples *tuples = (GRealTuples*) tuples0;
if (tuples)
{
g_free (tuples->data);
g_free (tuples);
}
}
gpointer
g_tuples_index (GTuples *tuples0,
gint index,
gint field)
{
GRealTuples *tuples = (GRealTuples*) tuples0;
g_return_val_if_fail (tuples0 != NULL, NULL);
g_return_val_if_fail (field < tuples->width, NULL);
return tuples->data[index * tuples->width + field];
}
/* Print
*/
static void
g_relation_print_one (gpointer tuple_key,
gpointer tuple_value,
gpointer user_data)
{
gint i;
GString *gstring;
GRealRelation* rel = (GRealRelation*) user_data;
gpointer* tuples = (gpointer*) tuple_value;
gstring = g_string_new ("[");
for (i = 0; i < rel->fields; i += 1)
{
g_string_sprintfa (gstring, "%p", tuples[i]);
if (i < (rel->fields - 1))
g_string_append (gstring, ",");
}
g_string_append (gstring, "]");
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, gstring->str);
g_string_free (gstring, TRUE);
}
static void
g_relation_print_index (gpointer tuple_key,
gpointer tuple_value,
gpointer user_data)
{
GRealRelation* rel = (GRealRelation*) user_data;
GHashTable* table = (GHashTable*) tuple_value;
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "*** key %p", tuple_key);
g_hash_table_foreach (table,
g_relation_print_one,
rel);
}
void
g_relation_print (GRelation *relation)
{
gint i;
GRealRelation* rel = (GRealRelation*) relation;
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "*** all tuples (%d)", rel->count);
g_hash_table_foreach (rel->all_tuples,
g_relation_print_one,
rel);
for (i = 0; i < rel->fields; i += 1)
{
if (rel->hashed_tuple_tables[i] == NULL)
continue;
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO, "*** index %d", i);
g_hash_table_foreach (rel->hashed_tuple_tables[i],
g_relation_print_index,
rel);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,595 +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 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.
*/
/*
* Modified by the GLib Team and others 1997-1999. 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"
struct _GAllocator /* from gmem.c */
{
gchar *name;
guint16 n_preallocs;
guint is_unused : 1;
guint type : 4;
GAllocator *last;
GMemChunk *mem_chunk;
GSList *free_lists; /* implementation specific */
};
G_LOCK_DEFINE_STATIC (current_allocator);
static GAllocator *current_allocator = NULL;
/* HOLDS: current_allocator_lock */
static void
g_slist_validate_allocator (GAllocator *allocator)
{
g_return_if_fail (allocator != NULL);
g_return_if_fail (allocator->is_unused == TRUE);
if (allocator->type != G_ALLOCATOR_SLIST)
{
allocator->type = G_ALLOCATOR_SLIST;
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 (GSList),
sizeof (GSList) * allocator->n_preallocs,
G_ALLOC_ONLY);
allocator->free_lists = NULL;
}
allocator->is_unused = FALSE;
}
void
g_slist_push_allocator (GAllocator *allocator)
{
G_LOCK (current_allocator);
g_slist_validate_allocator (allocator);
allocator->last = current_allocator;
current_allocator = allocator;
G_UNLOCK (current_allocator);
}
void
g_slist_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);
}
GSList*
g_slist_alloc (void)
{
GSList *list;
G_LOCK (current_allocator);
if (!current_allocator)
{
GAllocator *allocator = g_allocator_new ("GLib default GSList allocator",
128);
g_slist_validate_allocator (allocator);
allocator->last = NULL;
current_allocator = allocator;
}
if (!current_allocator->free_lists)
{
list = g_chunk_new (GSList, 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;
return list;
}
void
g_slist_free (GSList *list)
{
if (list)
{
list->data = list->next;
G_LOCK (current_allocator);
list->next = current_allocator->free_lists;
current_allocator->free_lists = list;
G_UNLOCK (current_allocator);
}
}
void
g_slist_free_1 (GSList *list)
{
if (list)
{
list->data = NULL;
G_LOCK (current_allocator);
list->next = current_allocator->free_lists;
current_allocator->free_lists = list;
G_UNLOCK (current_allocator);
}
}
GSList*
g_slist_append (GSList *list,
gpointer data)
{
GSList *new_list;
GSList *last;
new_list = g_slist_alloc ();
new_list->data = data;
if (list)
{
last = g_slist_last (list);
/* g_assert (last != NULL); */
last->next = new_list;
return list;
}
else
return new_list;
}
GSList*
g_slist_prepend (GSList *list,
gpointer data)
{
GSList *new_list;
new_list = g_slist_alloc ();
new_list->data = data;
new_list->next = list;
return new_list;
}
GSList*
g_slist_insert (GSList *list,
gpointer data,
gint position)
{
GSList *prev_list;
GSList *tmp_list;
GSList *new_list;
if (position < 0)
return g_slist_append (list, data);
else if (position == 0)
return g_slist_prepend (list, data);
new_list = g_slist_alloc ();
new_list->data = data;
if (!list)
return new_list;
prev_list = NULL;
tmp_list = list;
while ((position-- > 0) && tmp_list)
{
prev_list = tmp_list;
tmp_list = tmp_list->next;
}
if (prev_list)
{
new_list->next = prev_list->next;
prev_list->next = new_list;
}
else
{
new_list->next = list;
list = new_list;
}
return list;
}
GSList *
g_slist_concat (GSList *list1, GSList *list2)
{
if (list2)
{
if (list1)
g_slist_last (list1)->next = list2;
else
list1 = list2;
}
return list1;
}
GSList*
g_slist_remove (GSList *list,
gpointer data)
{
GSList *tmp;
GSList *prev;
prev = NULL;
tmp = list;
while (tmp)
{
if (tmp->data == data)
{
if (prev)
prev->next = tmp->next;
if (list == tmp)
list = list->next;
tmp->next = NULL;
g_slist_free (tmp);
break;
}
prev = tmp;
tmp = tmp->next;
}
return list;
}
GSList*
g_slist_remove_link (GSList *list,
GSList *link)
{
GSList *tmp;
GSList *prev;
prev = NULL;
tmp = list;
while (tmp)
{
if (tmp == link)
{
if (prev)
prev->next = tmp->next;
if (list == tmp)
list = list->next;
tmp->next = NULL;
break;
}
prev = tmp;
tmp = tmp->next;
}
return list;
}
GSList*
g_slist_copy (GSList *list)
{
GSList *new_list = NULL;
if (list)
{
GSList *last;
new_list = g_slist_alloc ();
new_list->data = list->data;
last = new_list;
list = list->next;
while (list)
{
last->next = g_slist_alloc ();
last = last->next;
last->data = list->data;
list = list->next;
}
}
return new_list;
}
GSList*
g_slist_reverse (GSList *list)
{
GSList *prev = NULL;
while (list)
{
GSList *next = list->next;
list->next = prev;
prev = list;
list = next;
}
return prev;
}
GSList*
g_slist_nth (GSList *list,
guint n)
{
while ((n-- > 0) && list)
list = list->next;
return list;
}
gpointer
g_slist_nth_data (GSList *list,
guint n)
{
while ((n-- > 0) && list)
list = list->next;
return list ? list->data : NULL;
}
GSList*
g_slist_find (GSList *list,
gpointer data)
{
while (list)
{
if (list->data == data)
break;
list = list->next;
}
return list;
}
GSList*
g_slist_find_custom (GSList *list,
gpointer 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_slist_position (GSList *list,
GSList *link)
{
gint i;
i = 0;
while (list)
{
if (list == link)
return i;
i++;
list = list->next;
}
return -1;
}
gint
g_slist_index (GSList *list,
gpointer data)
{
gint i;
i = 0;
while (list)
{
if (list->data == data)
return i;
i++;
list = list->next;
}
return -1;
}
GSList*
g_slist_last (GSList *list)
{
if (list)
{
while (list->next)
list = list->next;
}
return list;
}
guint
g_slist_length (GSList *list)
{
guint length;
length = 0;
while (list)
{
length++;
list = list->next;
}
return length;
}
void
g_slist_foreach (GSList *list,
GFunc func,
gpointer user_data)
{
while (list)
{
(*func) (list->data, user_data);
list = list->next;
}
}
GSList*
g_slist_insert_sorted (GSList *list,
gpointer data,
GCompareFunc func)
{
GSList *tmp_list = list;
GSList *prev_list = NULL;
GSList *new_list;
gint cmp;
g_return_val_if_fail (func != NULL, list);
if (!list)
{
new_list = g_slist_alloc();
new_list->data = data;
return new_list;
}
cmp = (*func) (data, tmp_list->data);
while ((tmp_list->next) && (cmp > 0))
{
prev_list = tmp_list;
tmp_list = tmp_list->next;
cmp = (*func) (data, tmp_list->data);
}
new_list = g_slist_alloc();
new_list->data = data;
if ((!tmp_list->next) && (cmp > 0))
{
tmp_list->next = new_list;
return list;
}
if (prev_list)
{
prev_list->next = new_list;
new_list->next = tmp_list;
return list;
}
else
{
new_list->next = list;
return new_list;
}
}
static GSList*
g_slist_sort_merge (GSList *l1,
GSList *l2,
GCompareFunc compare_func)
{
GSList list, *l;
l=&list;
while (l1 && l2)
{
if (compare_func(l1->data,l2->data) < 0)
{
l=l->next=l1;
l1=l1->next;
}
else
{
l=l->next=l2;
l2=l2->next;
}
}
l->next= l1 ? l1 : l2;
return list.next;
}
GSList*
g_slist_sort (GSList *list,
GCompareFunc compare_func)
{
GSList *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_slist_sort_merge (g_slist_sort (list, compare_func),
g_slist_sort (l2, compare_func),
compare_func);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,512 +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 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.
*/
/*
* Modified by the GLib Team and others 1997-1999. 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 <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "glib.h"
typedef struct _GRealStringChunk GRealStringChunk;
typedef struct _GRealString GRealString;
struct _GRealStringChunk
{
GHashTable *const_table;
GSList *storage_list;
gint storage_next;
gint this_size;
gint default_size;
};
struct _GRealString
{
gchar *str;
gint len;
gint alloc;
};
G_LOCK_DEFINE_STATIC (string_mem_chunk);
static GMemChunk *string_mem_chunk = NULL;
/* Hash Functions.
*/
gint
g_str_equal (gconstpointer v, gconstpointer v2)
{
return strcmp ((const gchar*) v, (const gchar*)v2) == 0;
}
/* 31 bit hash function */
guint
g_str_hash (gconstpointer key)
{
const char *p = key;
guint h = *p;
if (h)
for (p += 1; *p != '\0'; p++)
h = (h << 5) - h + *p;
return h;
}
/* String Chunks.
*/
GStringChunk*
g_string_chunk_new (gint default_size)
{
GRealStringChunk *new_chunk = g_new (GRealStringChunk, 1);
gint size = 1;
while (size < default_size)
size <<= 1;
new_chunk->const_table = NULL;
new_chunk->storage_list = NULL;
new_chunk->storage_next = size;
new_chunk->default_size = size;
new_chunk->this_size = size;
return (GStringChunk*) new_chunk;
}
void
g_string_chunk_free (GStringChunk *fchunk)
{
GRealStringChunk *chunk = (GRealStringChunk*) fchunk;
GSList *tmp_list;
g_return_if_fail (chunk != NULL);
if (chunk->storage_list)
{
for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next)
g_free (tmp_list->data);
g_slist_free (chunk->storage_list);
}
if (chunk->const_table)
g_hash_table_destroy (chunk->const_table);
g_free (chunk);
}
gchar*
g_string_chunk_insert (GStringChunk *fchunk,
const gchar *string)
{
GRealStringChunk *chunk = (GRealStringChunk*) fchunk;
gint len = strlen (string);
char* pos;
g_return_val_if_fail (chunk != NULL, NULL);
if ((chunk->storage_next + len + 1) > chunk->this_size)
{
gint new_size = chunk->default_size;
while (new_size < len+1)
new_size <<= 1;
chunk->storage_list = g_slist_prepend (chunk->storage_list,
g_new (char, new_size));
chunk->this_size = new_size;
chunk->storage_next = 0;
}
pos = ((char*)chunk->storage_list->data) + chunk->storage_next;
strcpy (pos, string);
chunk->storage_next += len + 1;
return pos;
}
gchar*
g_string_chunk_insert_const (GStringChunk *fchunk,
const gchar *string)
{
GRealStringChunk *chunk = (GRealStringChunk*) fchunk;
char* lookup;
g_return_val_if_fail (chunk != NULL, NULL);
if (!chunk->const_table)
chunk->const_table = g_hash_table_new (g_str_hash, g_str_equal);
lookup = (char*) g_hash_table_lookup (chunk->const_table, (gchar *)string);
if (!lookup)
{
lookup = g_string_chunk_insert (fchunk, string);
g_hash_table_insert (chunk->const_table, lookup, lookup);
}
return lookup;
}
/* Strings.
*/
static gint
nearest_pow (gint num)
{
gint n = 1;
while (n < num)
n <<= 1;
return n;
}
static void
g_string_maybe_expand (GRealString* string, gint len)
{
if (string->len + len >= string->alloc)
{
string->alloc = nearest_pow (string->len + len + 1);
string->str = g_realloc (string->str, string->alloc);
}
}
GString*
g_string_sized_new (guint dfl_size)
{
GRealString *string;
G_LOCK (string_mem_chunk);
if (!string_mem_chunk)
string_mem_chunk = g_mem_chunk_new ("string mem chunk",
sizeof (GRealString),
1024, G_ALLOC_AND_FREE);
string = g_chunk_new (GRealString, string_mem_chunk);
G_UNLOCK (string_mem_chunk);
string->alloc = 0;
string->len = 0;
string->str = NULL;
g_string_maybe_expand (string, MAX (dfl_size, 2));
string->str[0] = 0;
return (GString*) string;
}
GString*
g_string_new (const gchar *init)
{
GString *string;
string = g_string_sized_new (2);
if (init)
g_string_append (string, init);
return string;
}
void
g_string_free (GString *string,
gint free_segment)
{
g_return_if_fail (string != NULL);
if (free_segment)
g_free (string->str);
G_LOCK (string_mem_chunk);
g_mem_chunk_free (string_mem_chunk, string);
G_UNLOCK (string_mem_chunk);
}
GString*
g_string_assign (GString *lval,
const gchar *rval)
{
g_return_val_if_fail (lval != NULL, NULL);
g_return_val_if_fail (rval != NULL, NULL);
g_string_truncate (lval, 0);
g_string_append (lval, rval);
return lval;
}
GString*
g_string_truncate (GString* fstring,
gint len)
{
GRealString *string = (GRealString*)fstring;
g_return_val_if_fail (string != NULL, NULL);
g_return_val_if_fail (len >= 0, NULL);
string->len = len;
string->str[len] = 0;
return fstring;
}
GString*
g_string_append (GString *fstring,
const gchar *val)
{
GRealString *string = (GRealString*)fstring;
int len;
g_return_val_if_fail (string != NULL, NULL);
g_return_val_if_fail (val != NULL, fstring);
len = strlen (val);
g_string_maybe_expand (string, len);
strcpy (string->str + string->len, val);
string->len += len;
return fstring;
}
GString*
g_string_append_c (GString *fstring,
gchar c)
{
GRealString *string = (GRealString*)fstring;
g_return_val_if_fail (string != NULL, NULL);
g_string_maybe_expand (string, 1);
string->str[string->len++] = c;
string->str[string->len] = 0;
return fstring;
}
GString*
g_string_prepend (GString *fstring,
const gchar *val)
{
GRealString *string = (GRealString*)fstring;
gint len;
g_return_val_if_fail (string != NULL, NULL);
g_return_val_if_fail (val != NULL, fstring);
len = strlen (val);
g_string_maybe_expand (string, len);
g_memmove (string->str + len, string->str, string->len);
strncpy (string->str, val, len);
string->len += len;
string->str[string->len] = 0;
return fstring;
}
GString*
g_string_prepend_c (GString *fstring,
gchar c)
{
GRealString *string = (GRealString*)fstring;
g_return_val_if_fail (string != NULL, NULL);
g_string_maybe_expand (string, 1);
g_memmove (string->str + 1, string->str, string->len);
string->str[0] = c;
string->len += 1;
string->str[string->len] = 0;
return fstring;
}
GString*
g_string_insert (GString *fstring,
gint pos,
const gchar *val)
{
GRealString *string = (GRealString*)fstring;
gint len;
g_return_val_if_fail (string != NULL, NULL);
g_return_val_if_fail (val != NULL, fstring);
g_return_val_if_fail (pos >= 0, fstring);
g_return_val_if_fail (pos <= string->len, fstring);
len = strlen (val);
g_string_maybe_expand (string, len);
g_memmove (string->str + pos + len, string->str + pos, string->len - pos);
strncpy (string->str + pos, val, len);
string->len += len;
string->str[string->len] = 0;
return fstring;
}
GString *
g_string_insert_c (GString *fstring,
gint pos,
gchar c)
{
GRealString *string = (GRealString*)fstring;
g_return_val_if_fail (string != NULL, NULL);
g_return_val_if_fail (pos <= string->len, fstring);
g_string_maybe_expand (string, 1);
g_memmove (string->str + pos + 1, string->str + pos, string->len - pos);
string->str[pos] = c;
string->len += 1;
string->str[string->len] = 0;
return fstring;
}
GString*
g_string_erase (GString *fstring,
gint pos,
gint len)
{
GRealString *string = (GRealString*)fstring;
g_return_val_if_fail (string != NULL, NULL);
g_return_val_if_fail (len >= 0, fstring);
g_return_val_if_fail (pos >= 0, fstring);
g_return_val_if_fail (pos <= string->len, fstring);
g_return_val_if_fail (pos + len <= string->len, fstring);
if (pos + len < string->len)
g_memmove (string->str + pos, string->str + pos + len, string->len - (pos + len));
string->len -= len;
string->str[string->len] = 0;
return fstring;
}
GString*
g_string_down (GString *fstring)
{
GRealString *string = (GRealString*)fstring;
guchar *s;
g_return_val_if_fail (string != NULL, NULL);
s = string->str;
while (*s)
{
*s = tolower (*s);
s++;
}
return fstring;
}
GString*
g_string_up (GString *fstring)
{
GRealString *string = (GRealString*)fstring;
guchar *s;
g_return_val_if_fail (string != NULL, NULL);
s = string->str;
while (*s)
{
*s = toupper (*s);
s++;
}
return fstring;
}
static void
g_string_sprintfa_int (GString *string,
const gchar *fmt,
va_list args)
{
gchar *buffer;
buffer = g_strdup_vprintf (fmt, args);
g_string_append (string, buffer);
g_free (buffer);
}
void
g_string_sprintf (GString *string,
const gchar *fmt,
...)
{
va_list args;
g_string_truncate (string, 0);
va_start (args, fmt);
g_string_sprintfa_int (string, fmt, args);
va_end (args);
}
void
g_string_sprintfa (GString *string,
const gchar *fmt,
...)
{
va_list args;
va_start (args, fmt);
g_string_sprintfa_int (string, fmt, args);
va_end (args);
}

View File

@ -1,201 +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 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.
*/
/*
* Modified by the GLib Team and others 1997-1999. 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"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#ifndef NATIVE_WIN32
#include <sys/time.h>
#endif /* NATIVE_WIN32 */
#ifdef NATIVE_WIN32
#include <windows.h>
#endif /* NATIVE_WIN32 */
typedef struct _GRealTimer GRealTimer;
struct _GRealTimer
{
#ifdef NATIVE_WIN32
DWORD start;
DWORD end;
#else /* !NATIVE_WIN32 */
struct timeval start;
struct timeval end;
#endif /* !NATIVE_WIN32 */
guint active : 1;
};
GTimer*
g_timer_new (void)
{
GRealTimer *timer;
timer = g_new (GRealTimer, 1);
timer->active = TRUE;
#ifdef NATIVE_WIN32
timer->start = GetTickCount ();
#else /* !NATIVE_WIN32 */
gettimeofday (&timer->start, NULL);
#endif /* !NATIVE_WIN32 */
return ((GTimer*) timer);
}
void
g_timer_destroy (GTimer *timer)
{
g_return_if_fail (timer != NULL);
g_free (timer);
}
void
g_timer_start (GTimer *timer)
{
GRealTimer *rtimer;
g_return_if_fail (timer != NULL);
rtimer = (GRealTimer*) timer;
rtimer->active = TRUE;
#ifdef NATIVE_WIN32
rtimer->start = GetTickCount ();
#else /* !NATIVE_WIN32 */
gettimeofday (&rtimer->start, NULL);
#endif /* !NATIVE_WIN32 */
}
void
g_timer_stop (GTimer *timer)
{
GRealTimer *rtimer;
g_return_if_fail (timer != NULL);
rtimer = (GRealTimer*) timer;
rtimer->active = FALSE;
#ifdef NATIVE_WIN32
rtimer->end = GetTickCount ();
#else /* !NATIVE_WIN32 */
gettimeofday (&rtimer->end, NULL);
#endif /* !NATIVE_WIN32 */
}
void
g_timer_reset (GTimer *timer)
{
GRealTimer *rtimer;
g_return_if_fail (timer != NULL);
rtimer = (GRealTimer*) timer;
#ifdef NATIVE_WIN32
rtimer->start = GetTickCount ();
#else /* !NATIVE_WIN32 */
gettimeofday (&rtimer->start, NULL);
#endif /* !NATIVE_WIN32 */
}
gdouble
g_timer_elapsed (GTimer *timer,
gulong *microseconds)
{
GRealTimer *rtimer;
gdouble total;
#ifndef NATIVE_WIN32
struct timeval elapsed;
#endif /* NATIVE_WIN32 */
g_return_val_if_fail (timer != NULL, 0);
rtimer = (GRealTimer*) timer;
#ifdef NATIVE_WIN32
if (rtimer->active)
rtimer->end = GetTickCount ();
/* Check for wraparound, which happens every 49.7 days.
* No, Win95 machines probably are never running for that long,
* but NT machines are.
*/
if (rtimer->end < rtimer->start)
total = (UINT_MAX - (rtimer->start - rtimer->end)) / 1000.0;
else
total = (rtimer->end - rtimer->start) / 1000.0;
if (microseconds)
{
if (rtimer->end < rtimer->start)
*microseconds =
((UINT_MAX - (rtimer->start - rtimer->end)) % 1000) * 1000;
else
*microseconds =
((rtimer->end - rtimer->start) % 1000) * 1000;
}
#else /* !NATIVE_WIN32 */
if (rtimer->active)
gettimeofday (&rtimer->end, NULL);
if (rtimer->start.tv_usec > rtimer->end.tv_usec)
{
rtimer->end.tv_usec += 1000000;
rtimer->end.tv_sec--;
}
elapsed.tv_usec = rtimer->end.tv_usec - rtimer->start.tv_usec;
elapsed.tv_sec = rtimer->end.tv_sec - rtimer->start.tv_sec;
total = elapsed.tv_sec + ((gdouble) elapsed.tv_usec / 1e6);
if (total < 0)
{
total = 0;
if (microseconds)
*microseconds = 0;
}
else
if (microseconds)
*microseconds = elapsed.tv_usec;
#endif /* !NATIVE_WIN32 */
return total;
}

View File

@ -1,744 +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 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.
*/
/*
* Modified by the GLib Team and others 1997-1999. 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 _GRealTree GRealTree;
typedef struct _GTreeNode GTreeNode;
struct _GRealTree
{
GTreeNode *root;
GCompareFunc key_compare;
};
struct _GTreeNode
{
gint balance; /* height (left) - height (right) */
GTreeNode *left; /* left subtree */
GTreeNode *right; /* right subtree */
gpointer key; /* key for this node */
gpointer value; /* value stored at this node */
};
static GTreeNode* g_tree_node_new (gpointer key,
gpointer value);
static void g_tree_node_destroy (GTreeNode *node);
static GTreeNode* g_tree_node_insert (GTreeNode *node,
GCompareFunc compare,
gpointer key,
gpointer value,
gint *inserted);
static GTreeNode* g_tree_node_remove (GTreeNode *node,
GCompareFunc compare,
gpointer key);
static GTreeNode* g_tree_node_balance (GTreeNode *node);
static GTreeNode* g_tree_node_remove_leftmost (GTreeNode *node,
GTreeNode **leftmost);
static GTreeNode* g_tree_node_restore_left_balance (GTreeNode *node,
gint old_balance);
static GTreeNode* g_tree_node_restore_right_balance (GTreeNode *node,
gint old_balance);
static gpointer g_tree_node_lookup (GTreeNode *node,
GCompareFunc compare,
gpointer key);
static gint g_tree_node_count (GTreeNode *node);
static gint g_tree_node_pre_order (GTreeNode *node,
GTraverseFunc traverse_func,
gpointer data);
static gint g_tree_node_in_order (GTreeNode *node,
GTraverseFunc traverse_func,
gpointer data);
static gint g_tree_node_post_order (GTreeNode *node,
GTraverseFunc traverse_func,
gpointer data);
static gpointer g_tree_node_search (GTreeNode *node,
GSearchFunc search_func,
gpointer data);
static gint g_tree_node_height (GTreeNode *node);
static GTreeNode* g_tree_node_rotate_left (GTreeNode *node);
static GTreeNode* g_tree_node_rotate_right (GTreeNode *node);
static void g_tree_node_check (GTreeNode *node);
G_LOCK_DEFINE_STATIC (g_tree_global);
static GMemChunk *node_mem_chunk = NULL;
static GTreeNode *node_free_list = NULL;
static GTreeNode*
g_tree_node_new (gpointer key,
gpointer value)
{
GTreeNode *node;
G_LOCK (g_tree_global);
if (node_free_list)
{
node = node_free_list;
node_free_list = node->right;
}
else
{
if (!node_mem_chunk)
node_mem_chunk = g_mem_chunk_new ("GLib GTreeNode mem chunk",
sizeof (GTreeNode),
1024,
G_ALLOC_ONLY);
node = g_chunk_new (GTreeNode, node_mem_chunk);
}
G_UNLOCK (g_tree_global);
node->balance = 0;
node->left = NULL;
node->right = NULL;
node->key = key;
node->value = value;
return node;
}
static void
g_tree_node_destroy (GTreeNode *node)
{
if (node)
{
g_tree_node_destroy (node->right);
g_tree_node_destroy (node->left);
G_LOCK (g_tree_global);
node->right = node_free_list;
node_free_list = node;
G_UNLOCK (g_tree_global);
}
}
GTree*
g_tree_new (GCompareFunc key_compare_func)
{
GRealTree *rtree;
g_return_val_if_fail (key_compare_func != NULL, NULL);
rtree = g_new (GRealTree, 1);
rtree->root = NULL;
rtree->key_compare = key_compare_func;
return (GTree*) rtree;
}
void
g_tree_destroy (GTree *tree)
{
GRealTree *rtree;
g_return_if_fail (tree != NULL);
rtree = (GRealTree*) tree;
g_tree_node_destroy (rtree->root);
g_free (rtree);
}
void
g_tree_insert (GTree *tree,
gpointer key,
gpointer value)
{
GRealTree *rtree;
gint inserted;
g_return_if_fail (tree != NULL);
rtree = (GRealTree*) tree;
inserted = FALSE;
rtree->root = g_tree_node_insert (rtree->root, rtree->key_compare,
key, value, &inserted);
}
void
g_tree_remove (GTree *tree,
gpointer key)
{
GRealTree *rtree;
g_return_if_fail (tree != NULL);
rtree = (GRealTree*) tree;
rtree->root = g_tree_node_remove (rtree->root, rtree->key_compare, key);
}
gpointer
g_tree_lookup (GTree *tree,
gpointer key)
{
GRealTree *rtree;
g_return_val_if_fail (tree != NULL, NULL);
rtree = (GRealTree*) tree;
return g_tree_node_lookup (rtree->root, rtree->key_compare, key);
}
void
g_tree_traverse (GTree *tree,
GTraverseFunc traverse_func,
GTraverseType traverse_type,
gpointer data)
{
GRealTree *rtree;
g_return_if_fail (tree != NULL);
rtree = (GRealTree*) tree;
if (!rtree->root)
return;
switch (traverse_type)
{
case G_PRE_ORDER:
g_tree_node_pre_order (rtree->root, traverse_func, data);
break;
case G_IN_ORDER:
g_tree_node_in_order (rtree->root, traverse_func, data);
break;
case G_POST_ORDER:
g_tree_node_post_order (rtree->root, traverse_func, data);
break;
case G_LEVEL_ORDER:
g_warning ("g_tree_traverse(): traverse type G_LEVEL_ORDER isn't implemented.");
break;
}
}
gpointer
g_tree_search (GTree *tree,
GSearchFunc search_func,
gpointer data)
{
GRealTree *rtree;
g_return_val_if_fail (tree != NULL, NULL);
rtree = (GRealTree*) tree;
if (rtree->root)
return g_tree_node_search (rtree->root, search_func, data);
else
return NULL;
}
gint
g_tree_height (GTree *tree)
{
GRealTree *rtree;
g_return_val_if_fail (tree != NULL, 0);
rtree = (GRealTree*) tree;
if (rtree->root)
return g_tree_node_height (rtree->root);
else
return 0;
}
gint
g_tree_nnodes (GTree *tree)
{
GRealTree *rtree;
g_return_val_if_fail (tree != NULL, 0);
rtree = (GRealTree*) tree;
if (rtree->root)
return g_tree_node_count (rtree->root);
else
return 0;
}
static GTreeNode*
g_tree_node_insert (GTreeNode *node,
GCompareFunc compare,
gpointer key,
gpointer value,
gint *inserted)
{
gint old_balance;
gint cmp;
if (!node)
{
*inserted = TRUE;
return g_tree_node_new (key, value);
}
cmp = (* compare) (key, node->key);
if (cmp == 0)
{
*inserted = FALSE;
node->value = value;
return node;
}
if (cmp < 0)
{
if (node->left)
{
old_balance = node->left->balance;
node->left = g_tree_node_insert (node->left, compare, key, value, inserted);
if ((old_balance != node->left->balance) && node->left->balance)
node->balance -= 1;
}
else
{
*inserted = TRUE;
node->left = g_tree_node_new (key, value);
node->balance -= 1;
}
}
else if (cmp > 0)
{
if (node->right)
{
old_balance = node->right->balance;
node->right = g_tree_node_insert (node->right, compare, key, value, inserted);
if ((old_balance != node->right->balance) && node->right->balance)
node->balance += 1;
}
else
{
*inserted = TRUE;
node->right = g_tree_node_new (key, value);
node->balance += 1;
}
}
if (*inserted)
{
if ((node->balance < -1) || (node->balance > 1))
node = g_tree_node_balance (node);
}
return node;
}
static GTreeNode*
g_tree_node_remove (GTreeNode *node,
GCompareFunc compare,
gpointer key)
{
GTreeNode *new_root;
gint old_balance;
gint cmp;
if (!node)
return NULL;
cmp = (* compare) (key, node->key);
if (cmp == 0)
{
GTreeNode *garbage;
garbage = node;
if (!node->right)
{
node = node->left;
}
else
{
old_balance = node->right->balance;
node->right = g_tree_node_remove_leftmost (node->right, &new_root);
new_root->left = node->left;
new_root->right = node->right;
new_root->balance = node->balance;
node = g_tree_node_restore_right_balance (new_root, old_balance);
}
G_LOCK (g_tree_global);
garbage->right = node_free_list;
node_free_list = garbage;
G_UNLOCK (g_tree_global);
}
else if (cmp < 0)
{
if (node->left)
{
old_balance = node->left->balance;
node->left = g_tree_node_remove (node->left, compare, key);
node = g_tree_node_restore_left_balance (node, old_balance);
}
}
else if (cmp > 0)
{
if (node->right)
{
old_balance = node->right->balance;
node->right = g_tree_node_remove (node->right, compare, key);
node = g_tree_node_restore_right_balance (node, old_balance);
}
}
return node;
}
static GTreeNode*
g_tree_node_balance (GTreeNode *node)
{
if (node->balance < -1)
{
if (node->left->balance > 0)
node->left = g_tree_node_rotate_left (node->left);
node = g_tree_node_rotate_right (node);
}
else if (node->balance > 1)
{
if (node->right->balance < 0)
node->right = g_tree_node_rotate_right (node->right);
node = g_tree_node_rotate_left (node);
}
return node;
}
static GTreeNode*
g_tree_node_remove_leftmost (GTreeNode *node,
GTreeNode **leftmost)
{
gint old_balance;
if (!node->left)
{
*leftmost = node;
return node->right;
}
old_balance = node->left->balance;
node->left = g_tree_node_remove_leftmost (node->left, leftmost);
return g_tree_node_restore_left_balance (node, old_balance);
}
static GTreeNode*
g_tree_node_restore_left_balance (GTreeNode *node,
gint old_balance)
{
if (!node->left)
node->balance += 1;
else if ((node->left->balance != old_balance) &&
(node->left->balance == 0))
node->balance += 1;
if (node->balance > 1)
return g_tree_node_balance (node);
return node;
}
static GTreeNode*
g_tree_node_restore_right_balance (GTreeNode *node,
gint old_balance)
{
if (!node->right)
node->balance -= 1;
else if ((node->right->balance != old_balance) &&
(node->right->balance == 0))
node->balance -= 1;
if (node->balance < -1)
return g_tree_node_balance (node);
return node;
}
static gpointer
g_tree_node_lookup (GTreeNode *node,
GCompareFunc compare,
gpointer key)
{
gint cmp;
if (!node)
return NULL;
cmp = (* compare) (key, node->key);
if (cmp == 0)
return node->value;
if (cmp < 0)
{
if (node->left)
return g_tree_node_lookup (node->left, compare, key);
}
else if (cmp > 0)
{
if (node->right)
return g_tree_node_lookup (node->right, compare, key);
}
return NULL;
}
static gint
g_tree_node_count (GTreeNode *node)
{
gint count;
count = 1;
if (node->left)
count += g_tree_node_count (node->left);
if (node->right)
count += g_tree_node_count (node->right);
return count;
}
static gint
g_tree_node_pre_order (GTreeNode *node,
GTraverseFunc traverse_func,
gpointer data)
{
if ((*traverse_func) (node->key, node->value, data))
return TRUE;
if (node->left)
{
if (g_tree_node_pre_order (node->left, traverse_func, data))
return TRUE;
}
if (node->right)
{
if (g_tree_node_pre_order (node->right, traverse_func, data))
return TRUE;
}
return FALSE;
}
static gint
g_tree_node_in_order (GTreeNode *node,
GTraverseFunc traverse_func,
gpointer data)
{
if (node->left)
{
if (g_tree_node_in_order (node->left, traverse_func, data))
return TRUE;
}
if ((*traverse_func) (node->key, node->value, data))
return TRUE;
if (node->right)
{
if (g_tree_node_in_order (node->right, traverse_func, data))
return TRUE;
}
return FALSE;
}
static gint
g_tree_node_post_order (GTreeNode *node,
GTraverseFunc traverse_func,
gpointer data)
{
if (node->left)
{
if (g_tree_node_post_order (node->left, traverse_func, data))
return TRUE;
}
if (node->right)
{
if (g_tree_node_post_order (node->right, traverse_func, data))
return TRUE;
}
if ((*traverse_func) (node->key, node->value, data))
return TRUE;
return FALSE;
}
static gpointer
g_tree_node_search (GTreeNode *node,
GSearchFunc search_func,
gpointer data)
{
gint dir;
if (!node)
return NULL;
do {
dir = (* search_func) (node->key, data);
if (dir == 0)
return node->value;
if (dir < 0)
node = node->left;
else if (dir > 0)
node = node->right;
} while (node && (dir != 0));
return NULL;
}
static gint
g_tree_node_height (GTreeNode *node)
{
gint left_height;
gint right_height;
if (node)
{
left_height = 0;
right_height = 0;
if (node->left)
left_height = g_tree_node_height (node->left);
if (node->right)
right_height = g_tree_node_height (node->right);
return MAX (left_height, right_height) + 1;
}
return 0;
}
static GTreeNode*
g_tree_node_rotate_left (GTreeNode *node)
{
GTreeNode *left;
GTreeNode *right;
gint a_bal;
gint b_bal;
left = node->left;
right = node->right;
node->right = right->left;
right->left = node;
a_bal = node->balance;
b_bal = right->balance;
if (b_bal <= 0)
{
if (a_bal >= 1)
right->balance = b_bal - 1;
else
right->balance = a_bal + b_bal - 2;
node->balance = a_bal - 1;
}
else
{
if (a_bal <= b_bal)
right->balance = a_bal - 2;
else
right->balance = b_bal - 1;
node->balance = a_bal - b_bal - 1;
}
return right;
}
static GTreeNode*
g_tree_node_rotate_right (GTreeNode *node)
{
GTreeNode *left;
gint a_bal;
gint b_bal;
left = node->left;
node->left = left->right;
left->right = node;
a_bal = node->balance;
b_bal = left->balance;
if (b_bal <= 0)
{
if (b_bal > a_bal)
left->balance = b_bal + 1;
else
left->balance = a_bal + 2;
node->balance = a_bal - b_bal + 1;
}
else
{
if (a_bal <= -1)
left->balance = b_bal + 1;
else
left->balance = a_bal + b_bal + 2;
node->balance = a_bal + 1;
}
return left;
}
static void
g_tree_node_check (GTreeNode *node)
{
gint left_height;
gint right_height;
gint balance;
if (node)
{
left_height = 0;
right_height = 0;
if (node->left)
left_height = g_tree_node_height (node->left);
if (node->right)
right_height = g_tree_node_height (node->right);
balance = right_height - left_height;
if (balance != node->balance)
g_log (g_log_domain_glib, G_LOG_LEVEL_INFO,
"g_tree_node_check: failed: %d ( %d )\n",
balance, node->balance);
if (node->left)
g_tree_node_check (node->left);
if (node->right)
g_tree_node_check (node->right);
}
}

View File

@ -1,927 +0,0 @@
/* GLIB - Library of useful routines for C programming
* Copyright (C) 1995-1998 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GLib Team and others 1997-1999. 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 for the unix part, FIXME: make the win32 part MT safe as well.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "glibconfig.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
#include <sys/types.h>
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef NATIVE_WIN32
# define STRICT /* Strict typing, please */
# include <windows.h>
# include <direct.h>
# include <errno.h>
# include <ctype.h>
# ifdef _MSC_VER
# include <io.h>
# endif /* _MSC_VER */
#endif /* NATIVE_WIN32 */
/* implement Glib's inline functions
*/
#define G_INLINE_FUNC extern
#define G_CAN_INLINE 1
#include "glib.h"
#ifdef MAXPATHLEN
#define G_PATH_LENGTH (MAXPATHLEN + 1)
#elif defined (PATH_MAX)
#define G_PATH_LENGTH (PATH_MAX + 1)
#else /* !MAXPATHLEN */
#define G_PATH_LENGTH (2048 + 1)
#endif /* !MAXPATHLEN && !PATH_MAX */
const guint glib_major_version = GLIB_MAJOR_VERSION;
const guint glib_minor_version = GLIB_MINOR_VERSION;
const guint glib_micro_version = GLIB_MICRO_VERSION;
const guint glib_interface_age = GLIB_INTERFACE_AGE;
const guint glib_binary_age = GLIB_BINARY_AGE;
#if defined (NATIVE_WIN32) && defined (__LCC__)
int __stdcall
LibMain (void *hinstDll,
unsigned long dwReason,
void *reserved)
{
return 1;
}
#endif /* NATIVE_WIN32 && __LCC__ */
void
g_atexit (GVoidFunc func)
{
gint result;
gchar *error = NULL;
/* keep this in sync with glib.h */
#ifdef G_NATIVE_ATEXIT
result = ATEXIT (func);
if (result)
error = g_strerror (errno);
#elif defined (HAVE_ATEXIT)
# ifdef NeXT /* @#%@! NeXTStep */
result = !atexit ((void (*)(void)) func);
if (result)
error = g_strerror (errno);
# else
result = atexit ((void (*)(void)) func);
if (result)
error = g_strerror (errno);
# endif /* NeXT */
#elif defined (HAVE_ON_EXIT)
result = on_exit ((void (*)(int, void *)) func, NULL);
if (result)
error = g_strerror (errno);
#else
result = 0;
error = "no implementation";
#endif /* G_NATIVE_ATEXIT */
if (error)
g_error ("Could not register atexit() function: %s", error);
}
gint
g_snprintf (gchar *str,
gulong n,
gchar const *fmt,
...)
{
#ifdef HAVE_VSNPRINTF
va_list args;
gint retval;
g_return_val_if_fail (str != NULL, 0);
g_return_val_if_fail (n > 0, 0);
g_return_val_if_fail (fmt != NULL, 0);
va_start (args, fmt);
retval = vsnprintf (str, n, fmt, args);
va_end (args);
if (retval < 0)
{
str[n-1] = '\0';
retval = strlen (str);
}
return retval;
#else /* !HAVE_VSNPRINTF */
gchar *printed;
va_list args;
g_return_val_if_fail (str != NULL, 0);
g_return_val_if_fail (n > 0, 0);
g_return_val_if_fail (fmt != NULL, 0);
va_start (args, fmt);
printed = g_strdup_vprintf (fmt, args);
va_end (args);
strncpy (str, printed, n);
str[n-1] = '\0';
g_free (printed);
return strlen (str);
#endif /* !HAVE_VSNPRINTF */
}
gint
g_vsnprintf (gchar *str,
gulong n,
gchar const *fmt,
va_list args)
{
#ifdef HAVE_VSNPRINTF
gint retval;
g_return_val_if_fail (str != NULL, 0);
g_return_val_if_fail (n > 0, 0);
g_return_val_if_fail (fmt != NULL, 0);
retval = vsnprintf (str, n, fmt, args);
if (retval < 0)
{
str[n-1] = '\0';
retval = strlen (str);
}
return retval;
#else /* !HAVE_VSNPRINTF */
gchar *printed;
g_return_val_if_fail (str != NULL, 0);
g_return_val_if_fail (n > 0, 0);
g_return_val_if_fail (fmt != NULL, 0);
printed = g_strdup_vprintf (fmt, args);
strncpy (str, printed, n);
str[n-1] = '\0';
g_free (printed);
return strlen (str);
#endif /* !HAVE_VSNPRINTF */
}
guint
g_parse_debug_string (const gchar *string,
GDebugKey *keys,
guint nkeys)
{
guint i;
guint result = 0;
g_return_val_if_fail (string != NULL, 0);
if (!g_strcasecmp (string, "all"))
{
for (i=0; i<nkeys; i++)
result |= keys[i].value;
}
else
{
gchar *str = g_strdup (string);
gchar *p = str;
gchar *q;
gboolean done = FALSE;
while (*p && !done)
{
q = strchr (p, ':');
if (!q)
{
q = p + strlen(p);
done = TRUE;
}
*q = 0;
for (i=0; i<nkeys; i++)
if (!g_strcasecmp(keys[i].key, p))
result |= keys[i].value;
p = q+1;
}
g_free (str);
}
return result;
}
gchar*
g_basename (const gchar *file_name)
{
register gchar *base;
g_return_val_if_fail (file_name != NULL, NULL);
base = strrchr (file_name, G_DIR_SEPARATOR);
if (base)
return base + 1;
#ifdef NATIVE_WIN32
if (isalpha (file_name[0]) && file_name[1] == ':')
return (gchar*) file_name + 2;
#endif /* NATIVE_WIN32 */
return (gchar*) file_name;
}
gboolean
g_path_is_absolute (const gchar *file_name)
{
g_return_val_if_fail (file_name != NULL, FALSE);
if (file_name[0] == G_DIR_SEPARATOR)
return TRUE;
#ifdef NATIVE_WIN32
if (isalpha (file_name[0]) && file_name[1] == ':' && file_name[2] == G_DIR_SEPARATOR)
return TRUE;
#endif
return FALSE;
}
gchar*
g_path_skip_root (gchar *file_name)
{
g_return_val_if_fail (file_name != NULL, NULL);
if (file_name[0] == G_DIR_SEPARATOR)
return file_name + 1;
#ifdef NATIVE_WIN32
if (isalpha (file_name[0]) && file_name[1] == ':' && file_name[2] == G_DIR_SEPARATOR)
return file_name + 3;
#endif
return NULL;
}
gchar*
g_dirname (const gchar *file_name)
{
register gchar *base;
register guint len;
g_return_val_if_fail (file_name != NULL, NULL);
base = strrchr (file_name, G_DIR_SEPARATOR);
if (!base)
return g_strdup (".");
while (base > file_name && *base == G_DIR_SEPARATOR)
base--;
len = (guint) 1 + base - file_name;
base = g_new (gchar, len + 1);
g_memmove (base, file_name, len);
base[len] = 0;
return base;
}
gchar*
g_get_current_dir (void)
{
gchar *buffer;
gchar *dir;
buffer = g_new (gchar, G_PATH_LENGTH);
*buffer = 0;
/* We don't use getcwd(3) on SUNOS, because, it does a popen("pwd")
* and, if that wasn't bad enough, hangs in doing so.
*/
#if defined (sun) && !defined (__SVR4)
dir = getwd (buffer);
#else /* !sun */
dir = getcwd (buffer, G_PATH_LENGTH - 1);
#endif /* !sun */
if (!dir || !*buffer)
{
/* hm, should we g_error() out here?
* this can happen if e.g. "./" has mode \0000
*/
buffer[0] = G_DIR_SEPARATOR;
buffer[1] = 0;
}
dir = g_strdup (buffer);
g_free (buffer);
return dir;
}
gchar*
g_getenv (const gchar *variable)
{
#ifndef NATIVE_WIN32
g_return_val_if_fail (variable != NULL, NULL);
return getenv (variable);
#else
gchar *v;
guint k;
static gchar *p = NULL;
static gint l;
gchar dummy[2];
g_return_val_if_fail (variable != NULL, NULL);
v = getenv (variable);
if (!v)
return NULL;
/* On Windows NT, it is relatively typical that environment variables
* contain references to other environment variables. Handle that by
* calling ExpandEnvironmentStrings.
*/
/* First check how much space we need */
k = ExpandEnvironmentStrings (v, dummy, 2);
/* Then allocate that much, and actualy do the expansion */
if (p == NULL)
{
p = g_malloc (k);
l = k;
}
else if (k > l)
{
p = g_realloc (p, k);
l = k;
}
ExpandEnvironmentStrings (v, p, k);
return p;
#endif
}
G_LOCK_DEFINE_STATIC (g_utils_global);
static gchar *g_tmp_dir = NULL;
static gchar *g_user_name = NULL;
static gchar *g_real_name = NULL;
static gchar *g_home_dir = NULL;
/* HOLDS: g_utils_global_lock */
static void
g_get_any_init (void)
{
if (!g_tmp_dir)
{
g_tmp_dir = g_strdup (g_getenv ("TMPDIR"));
if (!g_tmp_dir)
g_tmp_dir = g_strdup (g_getenv ("TMP"));
if (!g_tmp_dir)
g_tmp_dir = g_strdup (g_getenv ("TEMP"));
#ifdef P_tmpdir
if (!g_tmp_dir)
{
int k;
g_tmp_dir = g_strdup (P_tmpdir);
k = strlen (g_tmp_dir);
if (g_tmp_dir[k-1] == G_DIR_SEPARATOR)
g_tmp_dir[k-1] = '\0';
}
#endif
if (!g_tmp_dir)
{
#ifndef NATIVE_WIN32
g_tmp_dir = g_strdup ("/tmp");
#else /* NATIVE_WIN32 */
g_tmp_dir = g_strdup ("C:\\");
#endif /* NATIVE_WIN32 */
}
if (!g_home_dir)
g_home_dir = g_strdup (g_getenv ("HOME"));
#ifdef NATIVE_WIN32
if (!g_home_dir)
{
/* The official way to specify a home directory on NT is
* the HOMEDRIVE and HOMEPATH environment variables.
*
* This is inside #ifdef NATIVE_WIN32 because with the cygwin dll,
* HOME should be a POSIX style pathname.
*/
if (getenv ("HOMEDRIVE") != NULL && getenv ("HOMEPATH") != NULL)
{
gchar *homedrive, *homepath;
homedrive = g_strdup (g_getenv ("HOMEDRIVE"));
homepath = g_strdup (g_getenv ("HOMEPATH"));
g_home_dir = g_strconcat (homedrive, homepath, NULL);
g_free (homedrive);
g_free (homepath);
}
}
#endif /* !NATIVE_WIN32 */
#ifdef HAVE_PWD_H
{
struct passwd *pw = NULL;
gpointer buffer = NULL;
# ifdef HAVE_GETPWUID_R
struct passwd pwd;
# ifdef _SC_GETPW_R_SIZE_MAX
/* This reurns the maximum length */
guint bufsize = sysconf (_SC_GETPW_R_SIZE_MAX);
# else /* _SC_GETPW_R_SIZE_MAX */
guint bufsize = 64;
# endif /* _SC_GETPW_R_SIZE_MAX */
gint error;
do
{
g_free (buffer);
buffer = g_malloc (bufsize);
errno = 0;
# ifdef HAVE_GETPWUID_R_POSIX
error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw);
error = error < 0 ? errno : error;
# else /* !HAVE_GETPWUID_R_POSIX */
# ifdef _AIX
error = getpwuid_r (getuid (), &pwd, buffer, bufsize);
pw = error == 0 ? &pwd : NULL;
# else /* !_AIX */
pw = getpwuid_r (getuid (), &pwd, buffer, bufsize);
error = pw ? 0 : errno;
# endif /* !_AIX */
# endif /* !HAVE_GETPWUID_R_POSIX */
if (!pw)
{
/* we bail out prematurely if the user id can't be found
* (should be pretty rare case actually), or if the buffer
* should be sufficiently big and lookups are still not
* successfull.
*/
if (error == 0 || error == ENOENT)
{
g_warning ("getpwuid_r(): failed due to: No such user %d.",
getuid ());
break;
}
if (bufsize > 32 * 1024)
{
g_warning ("getpwuid_r(): failed due to: %s.",
g_strerror (error));
break;
}
bufsize *= 2;
}
}
while (!pw);
# endif /* !HAVE_GETPWUID_R */
if (!pw)
{
setpwent ();
pw = getpwuid (getuid ());
endpwent ();
}
if (pw)
{
g_user_name = g_strdup (pw->pw_name);
g_real_name = g_strdup (pw->pw_gecos);
if (!g_home_dir)
g_home_dir = g_strdup (pw->pw_dir);
}
g_free (buffer);
}
#else /* !HAVE_PWD_H */
# ifdef NATIVE_WIN32
{
guint len = 17;
gchar buffer[17];
if (GetUserName (buffer, &len))
{
g_user_name = g_strdup (buffer);
g_real_name = g_strdup (buffer);
}
}
# endif /* NATIVE_WIN32 */
#endif /* !HAVE_PWD_H */
if (!g_user_name)
g_user_name = g_strdup ("somebody");
if (!g_real_name)
g_real_name = g_strdup ("Unknown");
else
{
gchar *p;
for (p = g_real_name; *p; p++)
if (*p == ',')
{
*p = 0;
p = g_strdup (g_real_name);
g_free (g_real_name);
g_real_name = p;
break;
}
}
}
}
gchar*
g_get_user_name (void)
{
G_LOCK (g_utils_global);
if (!g_tmp_dir)
g_get_any_init ();
G_UNLOCK (g_utils_global);
return g_user_name;
}
gchar*
g_get_real_name (void)
{
G_LOCK (g_utils_global);
if (!g_tmp_dir)
g_get_any_init ();
G_UNLOCK (g_utils_global);
return g_real_name;
}
/* Return the home directory of the user. If there is a HOME
* environment variable, its value is returned, otherwise use some
* system-dependent way of finding it out. If no home directory can be
* deduced, return NULL.
*/
gchar*
g_get_home_dir (void)
{
G_LOCK (g_utils_global);
if (!g_tmp_dir)
g_get_any_init ();
G_UNLOCK (g_utils_global);
return g_home_dir;
}
/* Return a directory to be used to store temporary files. This is the
* value of the TMPDIR, TMP or TEMP environment variables (they are
* checked in that order). If none of those exist, use P_tmpdir from
* stdio.h. If that isn't defined, return "/tmp" on POSIXly systems,
* and C:\ on Windows.
*/
gchar*
g_get_tmp_dir (void)
{
G_LOCK (g_utils_global);
if (!g_tmp_dir)
g_get_any_init ();
G_UNLOCK (g_utils_global);
return g_tmp_dir;
}
static gchar *g_prgname = NULL;
gchar*
g_get_prgname (void)
{
gchar* retval;
G_LOCK (g_utils_global);
retval = g_prgname;
G_UNLOCK (g_utils_global);
return retval;
}
void
g_set_prgname (const gchar *prgname)
{
gchar *c;
G_LOCK (g_utils_global);
c = g_prgname;
g_prgname = g_strdup (prgname);
g_free (c);
G_UNLOCK (g_utils_global);
}
guint
g_direct_hash (gconstpointer v)
{
return GPOINTER_TO_UINT (v);
}
gint
g_direct_equal (gconstpointer v1,
gconstpointer v2)
{
return v1 == v2;
}
gint
g_int_equal (gconstpointer v1,
gconstpointer v2)
{
return *((const gint*) v1) == *((const gint*) v2);
}
guint
g_int_hash (gconstpointer v)
{
return *(const gint*) v;
}
#if 0 /* Old IO Channels */
GIOChannel*
g_iochannel_new (gint fd)
{
GIOChannel *channel = g_new (GIOChannel, 1);
channel->fd = fd;
#ifdef NATIVE_WIN32
channel->peer = 0;
channel->peer_fd = 0;
channel->offset = 0;
channel->need_wakeups = 0;
#endif /* NATIVE_WIN32 */
return channel;
}
void
g_iochannel_free (GIOChannel *channel)
{
g_return_if_fail (channel != NULL);
g_free (channel);
}
void
g_iochannel_close_and_free (GIOChannel *channel)
{
g_return_if_fail (channel != NULL);
close (channel->fd);
g_iochannel_free (channel);
}
#undef g_iochannel_wakeup_peer
void
g_iochannel_wakeup_peer (GIOChannel *channel)
{
#ifdef NATIVE_WIN32
static guint message = 0;
#endif
g_return_if_fail (channel != NULL);
#ifdef NATIVE_WIN32
if (message == 0)
message = RegisterWindowMessage ("gdk-pipe-readable");
# if 0
g_print ("g_iochannel_wakeup_peer: calling PostThreadMessage (%#x, %d, %d, %d)\n",
channel->peer, message, channel->peer_fd, channel->offset);
# endif
PostThreadMessage (channel->peer, message,
channel->peer_fd, channel->offset);
#endif /* NATIVE_WIN32 */
}
#endif /* Old IO Channels */
#ifdef NATIVE_WIN32
#ifdef _MSC_VER
int
gwin_ftruncate (gint fd,
guint size)
{
HANDLE hfile;
guint curpos;
g_return_val_if_fail (fd >= 0, -1);
hfile = (HANDLE) _get_osfhandle (fd);
curpos = SetFilePointer (hfile, 0, NULL, FILE_CURRENT);
if (curpos == 0xFFFFFFFF
|| SetFilePointer (hfile, size, NULL, FILE_BEGIN) == 0xFFFFFFFF
|| !SetEndOfFile (hfile))
{
gint error = GetLastError ();
switch (error)
{
case ERROR_INVALID_HANDLE:
errno = EBADF;
break;
default:
errno = EIO;
break;
}
return -1;
}
return 0;
}
DIR*
gwin_opendir (const char *dirname)
{
DIR *result;
gchar *mask;
guint k;
g_return_val_if_fail (dirname != NULL, NULL);
result = g_new0 (DIR, 1);
result->find_file_data = g_new0 (WIN32_FIND_DATA, 1);
result->dir_name = g_strdup (dirname);
k = strlen (result->dir_name);
if (k && result->dir_name[k - 1] == '\\')
{
result->dir_name[k - 1] = '\0';
k--;
}
mask = g_strdup_printf ("%s\\*", result->dir_name);
result->find_file_handle = (guint) FindFirstFile (mask,
(LPWIN32_FIND_DATA) result->find_file_data);
g_free (mask);
if (result->find_file_handle == (guint) INVALID_HANDLE_VALUE)
{
int error = GetLastError ();
g_free (result->dir_name);
g_free (result->find_file_data);
g_free (result);
switch (error)
{
default:
errno = EIO;
return NULL;
}
}
result->just_opened = TRUE;
return result;
}
struct dirent*
gwin_readdir (DIR *dir)
{
static struct dirent result;
g_return_val_if_fail (dir != NULL, NULL);
if (dir->just_opened)
dir->just_opened = FALSE;
else
{
if (!FindNextFile ((HANDLE) dir->find_file_handle,
(LPWIN32_FIND_DATA) dir->find_file_data))
{
int error = GetLastError ();
switch (error)
{
case ERROR_NO_MORE_FILES:
return NULL;
default:
errno = EIO;
return NULL;
}
}
}
strcpy (result.d_name, g_basename (((LPWIN32_FIND_DATA) dir->find_file_data)->cFileName));
return &result;
}
void
gwin_rewinddir (DIR *dir)
{
gchar *mask;
g_return_if_fail (dir != NULL);
if (!FindClose ((HANDLE) dir->find_file_handle))
g_warning ("gwin_rewinddir(): FindClose() failed\n");
mask = g_strdup_printf ("%s\\*", dir->dir_name);
dir->find_file_handle = (guint) FindFirstFile (mask,
(LPWIN32_FIND_DATA) dir->find_file_data);
g_free (mask);
if (dir->find_file_handle == (guint) INVALID_HANDLE_VALUE)
{
int error = GetLastError ();
switch (error)
{
default:
errno = EIO;
return;
}
}
dir->just_opened = TRUE;
}
gint
gwin_closedir (DIR *dir)
{
g_return_val_if_fail (dir != NULL, -1);
if (!FindClose ((HANDLE) dir->find_file_handle))
{
int error = GetLastError ();
switch (error)
{
default:
errno = EIO; return -1;
}
}
g_free (dir->dir_name);
g_free (dir->find_file_data);
g_free (dir);
return 0;
}
#endif /* _MSC_VER */
#endif /* NATIVE_WIN32 */

View File

@ -1,486 +0,0 @@
#include "glib.h"
#include <stdio.h>
#include <string.h>
#include <locale.h>
#include <time.h>
gboolean failed = FALSE;
guint32 passed = 0;
guint32 notpassed = 0;
#define TEST(m,cond) G_STMT_START { failed = !(cond); \
if (failed) \
{ ++notpassed; \
if (!m) \
g_print ("\n(%s:%d) failed for: %s\n", __FILE__, __LINE__, ( # cond )); \
else \
g_print ("\n(%s:%d) failed for: %s: (%s)\n", __FILE__, __LINE__, ( # cond ), (gchar*)m); \
} \
else \
++passed; \
if ((passed+notpassed) % 10000 == 0) g_print ("."); fflush (stdout); \
} G_STMT_END
void g_date_debug_print(GDate* d)
{
if (!d) g_print("NULL!\n");
else
g_print("julian: %u (%s) DMY: %u %u %u (%s)\n",
d->julian_days,
d->julian ? "valid" : "invalid",
d->day,
d->month,
d->year,
d->dmy ? "valid" : "invalid");
fflush(stdout);
}
int main(int argc, char** argv)
{
GDate* d;
guint32 j;
GDateMonth m;
GDateYear y, prev_y;
GDateDay day;
gchar buf[101];
gchar* loc;
/* Try to get all the leap year cases. */
GDateYear check_years[] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 98, 99, 100, 101, 102, 103, 397,
398, 399, 400, 401, 402, 403, 404, 405, 406,
1598, 1599, 1600, 1601, 1602, 1650, 1651,
1897, 1898, 1899, 1900, 1901, 1902, 1903,
1961, 1962, 1963, 1964, 1965, 1967,
1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976,
1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985,
1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012,
3000, 3001, 3002, 3998, 3999, 4000, 4001, 4002, 4003
};
guint n_check_years = sizeof(check_years)/sizeof(GDateYear);
guint i;
gboolean discontinuity;
g_print("checking GDate...");
TEST("sizeof(GDate) is not more than 8 bytes on this platform", sizeof(GDate) < 9);
d = g_date_new();
TEST("Empty constructor produces invalid date", !g_date_valid(d));
g_date_free(d);
d = g_date_new_dmy(1,1,1);
TEST("January 1, Year 1 created and valid", g_date_valid(d));
j = g_date_julian(d);
TEST("January 1, Year 1 is Julian date 1", j == 1);
TEST("Returned month is January", g_date_month(d) == G_DATE_JANUARY);
TEST("Returned day is 1", g_date_day(d) == 1);
TEST("Returned year is 1", g_date_year(d) == 1);
TEST("Bad month is invalid", !g_date_valid_month(G_DATE_BAD_MONTH));
TEST("Month 13 is invalid", !g_date_valid_month(13));
TEST("Bad day is invalid", !g_date_valid_day(G_DATE_BAD_DAY));
TEST("Day 32 is invalid", !g_date_valid_day(32));
TEST("Bad year is invalid", !g_date_valid_year(G_DATE_BAD_YEAR));
TEST("Bad julian is invalid", !g_date_valid_julian(G_DATE_BAD_JULIAN));
TEST("Bad weekday is invalid", !g_date_valid_weekday(G_DATE_BAD_WEEKDAY));
TEST("Year 2000 is a leap year", g_date_is_leap_year(2000));
TEST("Year 1999 is not a leap year", !g_date_is_leap_year(1999));
TEST("Year 1996 is a leap year", g_date_is_leap_year(1996));
TEST("Year 1600 is a leap year", g_date_is_leap_year(1600));
TEST("Year 2100 is not a leap year", !g_date_is_leap_year(2100));
TEST("Year 1800 is not a leap year", !g_date_is_leap_year(1800));
g_date_free(d);
loc = setlocale(LC_ALL,"");
if (loc)
g_print("\nLocale set to %s\n", loc);
else
g_print("\nLocale unchanged\n");
d = g_date_new();
g_date_set_time(d, time(NULL));
TEST("Today is valid", g_date_valid(d));
g_date_strftime(buf,100,"Today is a %A, %x\n", d);
g_print("%s", buf);
g_date_set_time(d, 1);
TEST("Beginning of Unix epoch is valid", g_date_valid(d));
g_date_strftime(buf,100,"1 second into the Unix epoch it was a %A, in the month of %B, %x\n", d);
g_print("%s", buf);
g_date_set_julian(d, 1);
TEST("GDate's \"Julian\" epoch's first day is valid", g_date_valid(d));
g_date_strftime(buf,100,"Our \"Julian\" epoch begins on a %A, in the month of %B, %x\n",
d);
g_print("%s", buf);
g_date_set_dmy(d, 10, 1, 2000);
g_date_strftime(buf,100,"%x", d);
g_date_set_parse(d, buf);
/* Note: this test will hopefully work, but no promises. */
TEST("Successfully parsed a %x-formatted string",
g_date_valid(d) &&
g_date_month(d) == 1 &&
g_date_day(d) == 10 &&
g_date_year(d) == 2000);
if (failed)
g_date_debug_print(d);
g_date_free(d);
j = G_DATE_BAD_JULIAN;
i = 0;
discontinuity = TRUE;
y = check_years[0];
prev_y = G_DATE_BAD_YEAR;
while (i < n_check_years)
{
guint32 first_day_of_year = G_DATE_BAD_JULIAN;
guint16 days_in_year = g_date_is_leap_year(y) ? 366 : 365;
guint sunday_week_of_year = 0;
guint sunday_weeks_in_year = g_date_sunday_weeks_in_year(y);
guint monday_week_of_year = 0;
guint monday_weeks_in_year = g_date_monday_weeks_in_year(y);
if (discontinuity)
g_print(" (Break in sequence of requested years to check)\n");
g_print("Checking year %u", y);
TEST("Year is valid", g_date_valid_year(y));
TEST("Number of Sunday weeks in year is 52 or 53",
sunday_weeks_in_year == 52 || sunday_weeks_in_year == 53);
TEST("Number of Monday weeks in year is 52 or 53",
monday_weeks_in_year == 52 || monday_weeks_in_year == 53);
m = 1;
while (m < 13)
{
guint8 dim = g_date_days_in_month(m,y);
GDate days[31]; /* This is the fast way, no allocation */
TEST("Sensible number of days in month", (dim > 0 && dim < 32));
TEST("Month between 1 and 12 is valid", g_date_valid_month(m));
day = 1;
g_date_clear(days, 31);
while (day <= dim)
{
guint i;
GDate tmp;
TEST("DMY triplet is valid", g_date_valid_dmy(day,m,y));
/* Create GDate with triplet */
d = &days[day-1];
TEST("Cleared day is invalid", !g_date_valid(d));
g_date_set_dmy(d,day,m,y);
TEST("Set day is valid", g_date_valid(d));
if (m == G_DATE_JANUARY && day == 1)
{
first_day_of_year = g_date_julian(d);
}
g_assert(first_day_of_year != G_DATE_BAD_JULIAN);
TEST("Date with DMY triplet is valid", g_date_valid(d));
TEST("Month accessor works", g_date_month(d) == m);
TEST("Year accessor works", g_date_year(d) == y);
TEST("Day of month accessor works", g_date_day(d) == day);
TEST("Day of year is consistent with Julian dates",
((g_date_julian(d) + 1 - first_day_of_year) ==
(g_date_day_of_year(d))));
if (failed)
{
g_print("first day: %u this day: %u day of year: %u\n",
first_day_of_year,
g_date_julian(d),
g_date_day_of_year(d));
}
if (m == G_DATE_DECEMBER && day == 31)
{
TEST("Last day of year equals number of days in year",
g_date_day_of_year(d) == days_in_year);
if (failed)
{
g_print("last day: %u days in year: %u\n",
g_date_day_of_year(d), days_in_year);
}
}
TEST("Day of year is not more than number of days in the year",
g_date_day_of_year(d) <= days_in_year);
TEST("Monday week of year is not more than number of weeks in the year",
g_date_monday_week_of_year(d) <= monday_weeks_in_year);
if (failed)
{
g_print("Weeks in year: %u\n", monday_weeks_in_year);
g_date_debug_print(d);
}
TEST("Monday week of year is >= than last week of year",
g_date_monday_week_of_year(d) >= monday_week_of_year);
if (g_date_weekday(d) == G_DATE_MONDAY)
{
TEST("Monday week of year on Monday 1 more than previous day's week of year",
(g_date_monday_week_of_year(d) - monday_week_of_year) == 1);
}
else
{
TEST("Monday week of year on non-Monday 0 more than previous day's week of year",
(g_date_monday_week_of_year(d) - monday_week_of_year) == 0);
}
monday_week_of_year = g_date_monday_week_of_year(d);
TEST("Sunday week of year is not more than number of weeks in the year",
g_date_sunday_week_of_year(d) <= sunday_weeks_in_year);
if (failed)
{
g_date_debug_print(d);
}
TEST("Sunday week of year is >= than last week of year",
g_date_sunday_week_of_year(d) >= sunday_week_of_year);
if (g_date_weekday(d) == G_DATE_SUNDAY)
{
TEST("Sunday week of year on Sunday 1 more than previous day's week of year",
(g_date_sunday_week_of_year(d) - sunday_week_of_year) == 1);
}
else
{
TEST("Sunday week of year on non-Sunday 0 more than previous day's week of year",
(g_date_sunday_week_of_year(d) - sunday_week_of_year) == 0);
}
sunday_week_of_year = g_date_sunday_week_of_year(d);
TEST("Date is equal to itself",
g_date_compare(d,d) == 0);
/*************** Increments ***********/
i = 1;
while (i < 402) /* Need to get 400 year increments in */
{
/***** Days ******/
tmp = *d;
g_date_add_days(d, i);
TEST("Adding days gives a value greater than previous",
g_date_compare(d, &tmp) > 0);
g_date_subtract_days(d, i);
TEST("Forward days then backward days returns us to current day",
g_date_day(d) == day);
if (failed)
{
g_print(" (increment %u, dmy %u %u %u) ", i, day, m, y);
g_date_debug_print(d);
}
TEST("Forward days then backward days returns us to current month",
g_date_month(d) == m);
if (failed)
{
g_print(" (increment %u, dmy %u %u %u) ", i, day, m, y);
g_date_debug_print(d);
}
TEST("Forward days then backward days returns us to current year",
g_date_year(d) == y);
if (failed)
{
g_print(" (increment %u, dmy %u %u %u) ", i, day, m, y);
g_date_debug_print(d);
}
/******* Months ********/
tmp = *d;
g_date_add_months(d, i);
TEST("Adding months gives a larger value",
g_date_compare(d, &tmp) > 0);
g_date_subtract_months(d, i);
TEST("Forward months then backward months returns us to current month",
g_date_month(d) == m);
if (failed)
{
g_print(" (increment %u, dmy %u %u %u) ", i, day, m, y);
g_date_debug_print(d);
}
TEST("Forward months then backward months returns us to current year",
g_date_year(d) == y);
if (failed)
{
g_print(" (increment %u, dmy %u %u %u) ", i, day, m, y);
g_date_debug_print(d);
}
if (day < 29)
{
/* Day should be unchanged */
TEST("Forward months then backward months returns us to current day",
g_date_day(d) == day);
if (failed)
{
g_print(" (increment %u, dmy %u %u %u) ", i, day, m, y);
g_date_debug_print(d);
}
}
else
{
/* reset the day for later tests */
g_date_set_day(d, day);
}
/******* Years ********/
tmp = *d;
g_date_add_years(d, i);
TEST("Adding years gives a larger value",
g_date_compare(d,&tmp) > 0);
g_date_subtract_years(d, i);
TEST("Forward years then backward years returns us to current month",
g_date_month(d) == m);
if (failed)
{
g_print(" (increment %u, dmy %u %u %u) ", i, day, m, y);
g_date_debug_print(d);
}
TEST("Forward years then backward years returns us to current year",
g_date_year(d) == y);
if (failed)
{
g_print(" (increment %u, dmy %u %u %u) ", i, day, m, y);
g_date_debug_print(d);
}
if (m != 2 && day != 29)
{
TEST("Forward years then backward years returns us to current day",
g_date_day(d) == day);
if (failed)
{
g_print(" (increment %u, dmy %u %u %u) ", i, day, m, y);
g_date_debug_print(d);
}
}
else
{
g_date_set_day(d, day); /* reset */
}
i += 10;
}
/***** increment test relative to our local Julian count */
if (!discontinuity) {
/* We can only run sequence tests between sequential years */
TEST("Julians are sequential with increment 1",
j+1 == g_date_julian(d));
if (failed)
{
g_print("Out of sequence, prev: %u expected: %u got: %u\n",
j, j+1, g_date_julian(d));
}
g_date_add_days(d,1);
TEST("Next day has julian 1 higher",
g_date_julian(d) == j + 2);
g_date_subtract_days(d, 1);
if (j != G_DATE_BAD_JULIAN)
{
g_date_subtract_days(d, 1);
TEST("Previous day has julian 1 lower",
g_date_julian(d) == j);
g_date_add_days(d, 1); /* back to original */
}
}
discontinuity = FALSE; /* goes away now */
fflush(stdout);
fflush(stderr);
j = g_date_julian(d); /* inc current julian */
++day;
}
++m;
}
g_print(" done\n");
++i;
prev_y = y;
y = check_years[i];
if (prev_y == G_DATE_BAD_YEAR ||
(prev_y + 1) != y) discontinuity = TRUE;
}
g_print("\n%u tests passed, %u failed\n",passed, notpassed);
return 0;
}

View File

@ -1,109 +0,0 @@
#include "glib.h"
#include <stdio.h>
#include <string.h>
#include <locale.h>
void g_date_debug_print(GDate* d)
{
if (!d) g_print("NULL!\n");
else
g_print("julian: %u (%s) DMY: %u %u %u (%s)\n",
d->julian_days,
d->julian ? "valid" : "invalid",
d->day,
d->month,
d->year,
d->dmy ? "valid" : "invalid");
fflush(stdout);
}
/* These only work in the POSIX locale, maybe C too -
* type POSIX into the program to check them
*/
char* posix_tests [] = {
"19981024",
"981024",
"October 1998",
"October 98",
"oCT 98",
"10/24/98",
"10 -- 24 -- 98",
"10/24/1998",
"October 24, 1998",
NULL
};
int main(int argc, char** argv)
{
GDate* d;
gchar* loc;
gchar input[1024];
loc = setlocale(LC_ALL,"");
if (loc)
g_print("\nLocale set to %s\n", loc);
else
g_print("\nLocale unchanged\n");
d = g_date_new();
while (fgets(input, 1023, stdin))
{
if (input[0] == '\n')
{
g_print("Enter a date to parse and press enter, or type `POSIX':\n");
continue;
}
if (strcmp(input,"POSIX\n") == 0)
{
char** s = posix_tests;
while (*s) {
g_date_set_parse(d, *s);
g_print("POSIXy parse test `%s' ...", *s);
if (!g_date_valid(d))
{
g_print(" failed.\n");
}
else
{
gchar buf[256];
g_date_strftime(buf,100," parsed `%x' (%B %d %Y)\n",
d);
g_print("%s", buf);
}
++s;
}
}
else
{
g_date_set_parse(d, input);
if (!g_date_valid(d))
{
g_print("Parse failed.\n");
}
else
{
gchar buf[256];
g_date_strftime(buf,100,"Parsed: `%x' (%B %d %Y)\n",
d);
g_print("%s", buf);
}
}
}
g_date_free(d);
return 0;
}

View File

@ -1,921 +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 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.
*/
/*
* Modified by the GLib Team and others 1997-1999. 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/.
*/
#undef G_LOG_DOMAIN
#include <stdio.h>
#include <string.h>
#include "glib.h"
int array[10000];
gboolean failed = FALSE;
#define TEST(m,cond) G_STMT_START { failed = !(cond); \
if (failed) \
{ if (!m) \
g_print ("\n(%s:%d) failed for: %s\n", __FILE__, __LINE__, ( # cond )); \
else \
g_print ("\n(%s:%d) failed for: %s: (%s)\n", __FILE__, __LINE__, ( # cond ), (gchar*)m); \
} \
else \
g_print ("."); fflush (stdout); \
} G_STMT_END
#define C2P(c) ((gpointer) ((long) (c)))
#define P2C(p) ((gchar) ((long) (p)))
#define GLIB_TEST_STRING "el dorado "
#define GLIB_TEST_STRING_5 "el do"
static gboolean
node_build_string (GNode *node,
gpointer data)
{
gchar **p = data;
gchar *string;
gchar c[2] = "_";
c[0] = P2C (node->data);
string = g_strconcat (*p ? *p : "", c, NULL);
g_free (*p);
*p = string;
return FALSE;
}
static void
g_node_test (void)
{
GNode *root;
GNode *node;
GNode *node_B;
GNode *node_F;
GNode *node_G;
GNode *node_J;
guint i;
gchar *tstring;
g_print ("checking n-way trees: ");
failed = FALSE;
root = g_node_new (C2P ('A'));
TEST (NULL, g_node_depth (root) == 1 && g_node_max_height (root) == 1);
node_B = g_node_new (C2P ('B'));
g_node_append (root, node_B);
TEST (NULL, root->children == node_B);
g_node_append_data (node_B, C2P ('E'));
g_node_prepend_data (node_B, C2P ('C'));
g_node_insert (node_B, 1, g_node_new (C2P ('D')));
node_F = g_node_new (C2P ('F'));
g_node_append (root, node_F);
TEST (NULL, root->children->next == node_F);
node_G = g_node_new (C2P ('G'));
g_node_append (node_F, node_G);
node_J = g_node_new (C2P ('J'));
g_node_prepend (node_G, node_J);
g_node_insert (node_G, 42, g_node_new (C2P ('K')));
g_node_insert_data (node_G, 0, C2P ('H'));
g_node_insert (node_G, 1, g_node_new (C2P ('I')));
TEST (NULL, g_node_depth (root) == 1);
TEST (NULL, g_node_max_height (root) == 4);
TEST (NULL, g_node_depth (node_G->children->next) == 4);
TEST (NULL, g_node_n_nodes (root, G_TRAVERSE_LEAFS) == 7);
TEST (NULL, g_node_n_nodes (root, G_TRAVERSE_NON_LEAFS) == 4);
TEST (NULL, g_node_n_nodes (root, G_TRAVERSE_ALL) == 11);
TEST (NULL, g_node_max_height (node_F) == 3);
TEST (NULL, g_node_n_children (node_G) == 4);
TEST (NULL, g_node_find_child (root, G_TRAVERSE_ALL, C2P ('F')) == node_F);
TEST (NULL, g_node_find (root, G_LEVEL_ORDER, G_TRAVERSE_NON_LEAFS, C2P ('I')) == NULL);
TEST (NULL, g_node_find (root, G_IN_ORDER, G_TRAVERSE_LEAFS, C2P ('J')) == node_J);
for (i = 0; i < g_node_n_children (node_B); i++)
{
node = g_node_nth_child (node_B, i);
TEST (NULL, P2C (node->data) == ('C' + i));
}
for (i = 0; i < g_node_n_children (node_G); i++)
TEST (NULL, g_node_child_position (node_G, g_node_nth_child (node_G, i)) == i);
/* we have built: A
* / \
* B F
* / | \ \
* C D E G
* / /\ \
* H I J K
*
* for in-order traversal, 'G' is considered to be the "left"
* child of 'F', which will cause 'F' to be the last node visited.
*/
tstring = NULL;
g_node_traverse (root, G_PRE_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &tstring);
TEST (tstring, strcmp (tstring, "ABCDEFGHIJK") == 0);
g_free (tstring); tstring = NULL;
g_node_traverse (root, G_POST_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &tstring);
TEST (tstring, strcmp (tstring, "CDEBHIJKGFA") == 0);
g_free (tstring); tstring = NULL;
g_node_traverse (root, G_IN_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &tstring);
TEST (tstring, strcmp (tstring, "CBDEAHGIJKF") == 0);
g_free (tstring); tstring = NULL;
g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &tstring);
TEST (tstring, strcmp (tstring, "ABFCDEGHIJK") == 0);
g_free (tstring); tstring = NULL;
g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_LEAFS, -1, node_build_string, &tstring);
TEST (tstring, strcmp (tstring, "CDEHIJK") == 0);
g_free (tstring); tstring = NULL;
g_node_traverse (root, G_PRE_ORDER, G_TRAVERSE_NON_LEAFS, -1, node_build_string, &tstring);
TEST (tstring, strcmp (tstring, "ABFG") == 0);
g_free (tstring); tstring = NULL;
g_node_reverse_children (node_B);
g_node_reverse_children (node_G);
g_node_traverse (root, G_LEVEL_ORDER, G_TRAVERSE_ALL, -1, node_build_string, &tstring);
TEST (tstring, strcmp (tstring, "ABFEDCGKJIH") == 0);
g_free (tstring); tstring = NULL;
g_node_destroy (root);
/* allocation tests */
root = g_node_new (NULL);
node = root;
for (i = 0; i < 2048; i++)
{
g_node_append (node, g_node_new (NULL));
if ((i%5) == 4)
node = node->children->next;
}
TEST (NULL, g_node_max_height (root) > 100);
TEST (NULL, g_node_n_nodes (root, G_TRAVERSE_ALL) == 1 + 2048);
g_node_destroy (root);
if (!failed)
g_print ("ok\n");
}
static gboolean
my_hash_callback_remove (gpointer key,
gpointer value,
gpointer user_data)
{
int *d = value;
if ((*d) % 2)
return TRUE;
return FALSE;
}
static void
my_hash_callback_remove_test (gpointer key,
gpointer value,
gpointer user_data)
{
int *d = value;
if ((*d) % 2)
g_print ("bad!\n");
}
static void
my_hash_callback (gpointer key,
gpointer value,
gpointer user_data)
{
int *d = value;
*d = 1;
}
static guint
my_hash (gconstpointer key)
{
return (guint) *((const gint*) key);
}
static gint
my_hash_compare (gconstpointer a,
gconstpointer b)
{
return *((const gint*) a) == *((const gint*) b);
}
static gint
my_list_compare_one (gconstpointer a, gconstpointer b)
{
gint one = *((const gint*)a);
gint two = *((const gint*)b);
return one-two;
}
static gint
my_list_compare_two (gconstpointer a, gconstpointer b)
{
gint one = *((const gint*)a);
gint two = *((const gint*)b);
return two-one;
}
/* static void
my_list_print (gpointer a, gpointer b)
{
gint three = *((gint*)a);
g_print("%d", three);
}; */
static gint
my_compare (gconstpointer a,
gconstpointer b)
{
const char *cha = a;
const char *chb = b;
return *cha - *chb;
}
static gint
my_traverse (gpointer key,
gpointer value,
gpointer data)
{
char *ch = key;
g_print ("%c ", *ch);
return FALSE;
}
int
main (int argc,
char *argv[])
{
GList *list, *t;
GSList *slist, *st;
GHashTable *hash_table;
GMemChunk *mem_chunk;
GStringChunk *string_chunk;
GTimer *timer;
gint nums[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
gint morenums[10] = { 8, 9, 7, 0, 3, 2, 5, 1, 4, 6};
gchar *string;
gchar *mem[10000], *tmp_string = NULL, *tmp_string_2;
gint i, j;
GArray *garray;
GPtrArray *gparray;
GByteArray *gbarray;
GString *string1, *string2;
GTree *tree;
char chars[62];
GRelation *relation;
GTuples *tuples;
gint data [1024];
struct {
gchar *filename;
gchar *dirname;
} dirname_checks[] = {
#ifndef NATIVE_WIN32
{ "/", "/" },
{ "////", "/" },
{ ".////", "." },
{ ".", "." },
{ "..", "." },
{ "../", ".." },
{ "..////", ".." },
{ "", "." },
{ "a/b", "a" },
{ "a/b/", "a/b" },
{ "c///", "c" },
#else
{ "\\", "\\" },
{ ".\\\\\\\\", "." },
{ ".", "." },
{ "..", "." },
{ "..\\", ".." },
{ "..\\\\\\\\", ".." },
{ "", "." },
{ "a\\b", "a" },
{ "a\\b\\", "a\\b" },
{ "c\\\\\\", "c" },
#endif
};
guint n_dirname_checks = sizeof (dirname_checks) / sizeof (dirname_checks[0]);
guint16 gu16t1 = 0x44afU, gu16t2 = 0xaf44U;
guint32 gu32t1 = 0x02a7f109U, gu32t2 = 0x09f1a702U;
#ifdef G_HAVE_GINT64
guint64 gu64t1 = G_GINT64_CONSTANT(0x1d636b02300a7aa7U),
gu64t2 = G_GINT64_CONSTANT(0xa77a0a30026b631dU);
#endif
g_print ("TestGLib v%u.%u.%u (i:%u b:%u)\n",
glib_major_version,
glib_minor_version,
glib_micro_version,
glib_interface_age,
glib_binary_age);
string = g_get_current_dir ();
g_print ("cwd: %s\n", string);
g_free (string);
g_print ("user: %s\n", g_get_user_name ());
g_print ("real: %s\n", g_get_real_name ());
g_print ("home: %s\n", g_get_home_dir ());
g_print ("tmp-dir: %s\n", g_get_tmp_dir ());
/* type sizes */
g_print ("checking size of gint8: %d", (int)sizeof (gint8));
TEST (NULL, sizeof (gint8) == 1);
g_print ("\nchecking size of gint16: %d", (int)sizeof (gint16));
TEST (NULL, sizeof (gint16) == 2);
g_print ("\nchecking size of gint32: %d", (int)sizeof (gint32));
TEST (NULL, sizeof (gint32) == 4);
#ifdef G_HAVE_GINT64
g_print ("\nchecking size of gint64: %d", (int)sizeof (gint64));
TEST (NULL, sizeof (gint64) == 8);
#endif /* G_HAVE_GINT64 */
g_print ("\n");
g_print ("checking g_dirname()...");
for (i = 0; i < n_dirname_checks; i++)
{
gchar *dirname;
dirname = g_dirname (dirname_checks[i].filename);
if (strcmp (dirname, dirname_checks[i].dirname) != 0)
{
g_print ("\nfailed for \"%s\"==\"%s\" (returned: \"%s\")\n",
dirname_checks[i].filename,
dirname_checks[i].dirname,
dirname);
n_dirname_checks = 0;
}
g_free (dirname);
}
if (n_dirname_checks)
g_print ("ok\n");
g_print ("checking doubly linked lists...");
list = NULL;
for (i = 0; i < 10; i++)
list = g_list_append (list, &nums[i]);
list = g_list_reverse (list);
for (i = 0; i < 10; i++)
{
t = g_list_nth (list, i);
if (*((gint*) t->data) != (9 - i))
g_error ("Regular insert failed");
}
for (i = 0; i < 10; i++)
if(g_list_position(list, g_list_nth (list, i)) != i)
g_error("g_list_position does not seem to be the inverse of g_list_nth\n");
g_list_free (list);
list = NULL;
for (i = 0; i < 10; i++)
list = g_list_insert_sorted (list, &morenums[i], my_list_compare_one);
/*
g_print("\n");
g_list_foreach (list, my_list_print, NULL);
*/
for (i = 0; i < 10; i++)
{
t = g_list_nth (list, i);
if (*((gint*) t->data) != i)
g_error ("Sorted insert failed");
}
g_list_free (list);
list = NULL;
for (i = 0; i < 10; i++)
list = g_list_insert_sorted (list, &morenums[i], my_list_compare_two);
/*
g_print("\n");
g_list_foreach (list, my_list_print, NULL);
*/
for (i = 0; i < 10; i++)
{
t = g_list_nth (list, i);
if (*((gint*) t->data) != (9 - i))
g_error ("Sorted insert failed");
}
g_list_free (list);
list = NULL;
for (i = 0; i < 10; i++)
list = g_list_prepend (list, &morenums[i]);
list = g_list_sort (list, my_list_compare_two);
/*
g_print("\n");
g_list_foreach (list, my_list_print, NULL);
*/
for (i = 0; i < 10; i++)
{
t = g_list_nth (list, i);
if (*((gint*) t->data) != (9 - i))
g_error ("Merge sort failed");
}
g_list_free (list);
g_print ("ok\n");
g_print ("checking singly linked lists...");
slist = NULL;
for (i = 0; i < 10; i++)
slist = g_slist_append (slist, &nums[i]);
slist = g_slist_reverse (slist);
for (i = 0; i < 10; i++)
{
st = g_slist_nth (slist, i);
if (*((gint*) st->data) != (9 - i))
g_error ("failed");
}
g_slist_free (slist);
slist = NULL;
for (i = 0; i < 10; i++)
slist = g_slist_insert_sorted (slist, &morenums[i], my_list_compare_one);
/*
g_print("\n");
g_slist_foreach (slist, my_list_print, NULL);
*/
for (i = 0; i < 10; i++)
{
st = g_slist_nth (slist, i);
if (*((gint*) st->data) != i)
g_error ("Sorted insert failed");
}
g_slist_free(slist);
slist = NULL;
for (i = 0; i < 10; i++)
slist = g_slist_insert_sorted (slist, &morenums[i], my_list_compare_two);
/*
g_print("\n");
g_slist_foreach (slist, my_list_print, NULL);
*/
for (i = 0; i < 10; i++)
{
st = g_slist_nth (slist, i);
if (*((gint*) st->data) != (9 - i))
g_error("Sorted insert failed");
}
g_slist_free(slist);
slist = NULL;
for (i = 0; i < 10; i++)
slist = g_slist_prepend (slist, &morenums[i]);
slist = g_slist_sort (slist, my_list_compare_two);
/*
g_print("\n");
g_slist_foreach (slist, my_list_print, NULL);
*/
for (i = 0; i < 10; i++)
{
st = g_slist_nth (slist, i);
if (*((gint*) st->data) != (9 - i))
g_error("Sorted insert failed");
}
g_slist_free(slist);
g_print ("ok\n");
g_print ("checking binary trees...\n");
tree = g_tree_new (my_compare);
i = 0;
for (j = 0; j < 10; j++, i++)
{
chars[i] = '0' + j;
g_tree_insert (tree, &chars[i], &chars[i]);
}
for (j = 0; j < 26; j++, i++)
{
chars[i] = 'A' + j;
g_tree_insert (tree, &chars[i], &chars[i]);
}
for (j = 0; j < 26; j++, i++)
{
chars[i] = 'a' + j;
g_tree_insert (tree, &chars[i], &chars[i]);
}
g_print ("tree height: %d\n", g_tree_height (tree));
g_print ("tree nnodes: %d\n", g_tree_nnodes (tree));
g_print ("tree: ");
g_tree_traverse (tree, my_traverse, G_IN_ORDER, NULL);
g_print ("\n");
for (i = 0; i < 10; i++)
g_tree_remove (tree, &chars[i]);
g_print ("tree height: %d\n", g_tree_height (tree));
g_print ("tree nnodes: %d\n", g_tree_nnodes (tree));
g_print ("tree: ");
g_tree_traverse (tree, my_traverse, G_IN_ORDER, NULL);
g_print ("\n");
g_print ("ok\n");
/* check n-way trees */
g_node_test ();
g_print ("checking mem chunks...");
mem_chunk = g_mem_chunk_new ("test mem chunk", 50, 100, G_ALLOC_AND_FREE);
for (i = 0; i < 10000; i++)
{
mem[i] = g_chunk_new (gchar, mem_chunk);
for (j = 0; j < 50; j++)
mem[i][j] = i * j;
}
for (i = 0; i < 10000; i++)
{
g_mem_chunk_free (mem_chunk, mem[i]);
}
g_print ("ok\n");
g_print ("checking hash tables...");
hash_table = g_hash_table_new (my_hash, my_hash_compare);
for (i = 0; i < 10000; i++)
{
array[i] = i;
g_hash_table_insert (hash_table, &array[i], &array[i]);
}
g_hash_table_foreach (hash_table, my_hash_callback, NULL);
for (i = 0; i < 10000; i++)
if (array[i] == 0)
g_print ("%d\n", i);
for (i = 0; i < 10000; i++)
g_hash_table_remove (hash_table, &array[i]);
for (i = 0; i < 10000; i++)
{
array[i] = i;
g_hash_table_insert (hash_table, &array[i], &array[i]);
}
if (g_hash_table_foreach_remove (hash_table, my_hash_callback_remove, NULL) != 5000 ||
g_hash_table_size (hash_table) != 5000)
g_print ("bad!\n");
g_hash_table_foreach (hash_table, my_hash_callback_remove_test, NULL);
g_hash_table_destroy (hash_table);
g_print ("ok\n");
g_print ("checking string chunks...");
string_chunk = g_string_chunk_new (1024);
for (i = 0; i < 100000; i ++)
{
tmp_string = g_string_chunk_insert (string_chunk, "hi pete");
if (strcmp ("hi pete", tmp_string) != 0)
g_error ("string chunks are broken.\n");
}
tmp_string_2 = g_string_chunk_insert_const (string_chunk, tmp_string);
g_assert (tmp_string_2 != tmp_string &&
strcmp(tmp_string_2, tmp_string) == 0);
tmp_string = g_string_chunk_insert_const (string_chunk, tmp_string);
g_assert (tmp_string_2 == tmp_string);
g_string_chunk_free (string_chunk);
g_print ("ok\n");
g_print ("checking arrays...");
garray = g_array_new (FALSE, FALSE, sizeof (gint));
for (i = 0; i < 10000; i++)
g_array_append_val (garray, i);
for (i = 0; i < 10000; i++)
if (g_array_index (garray, gint, i) != i)
g_print ("uh oh: %d ( %d )\n", g_array_index (garray, gint, i), i);
g_array_free (garray, TRUE);
garray = g_array_new (FALSE, FALSE, sizeof (gint));
for (i = 0; i < 100; i++)
g_array_prepend_val (garray, i);
for (i = 0; i < 100; i++)
if (g_array_index (garray, gint, i) != (100 - i - 1))
g_print ("uh oh: %d ( %d )\n", g_array_index (garray, gint, i), 100 - i - 1);
g_array_free (garray, TRUE);
g_print ("ok\n");
g_print ("checking strings...");
string1 = g_string_new ("hi pete!");
string2 = g_string_new ("");
g_assert (strcmp ("hi pete!", string1->str) == 0);
for (i = 0; i < 10000; i++)
g_string_append_c (string1, 'a'+(i%26));
#if !(defined (_MSC_VER) || defined (__LCC__))
/* MSVC and LCC use the same run-time C library, which doesn't like
the %10000.10000f format... */
g_string_sprintf (string2, "%s|%0100d|%s|%s|%0*d|%*.*f|%10000.10000f",
"this pete guy sure is a wuss, like he's the number ",
1,
" wuss. everyone agrees.\n",
string1->str,
10, 666, 15, 15, 666.666666666, 666.666666666);
#else
g_string_sprintf (string2, "%s|%0100d|%s|%s|%0*d|%*.*f|%100.100f",
"this pete guy sure is a wuss, like he's the number ",
1,
" wuss. everyone agrees.\n",
string1->str,
10, 666, 15, 15, 666.666666666, 666.666666666);
#endif
g_print ("string2 length = %d...\n", string2->len);
string2->str[70] = '\0';
g_print ("first 70 chars:\n%s\n", string2->str);
string2->str[141] = '\0';
g_print ("next 70 chars:\n%s\n", string2->str+71);
string2->str[212] = '\0';
g_print ("and next 70:\n%s\n", string2->str+142);
g_print ("last 70 chars:\n%s\n", string2->str+string2->len - 70);
g_print ("ok\n");
g_print ("checking timers...\n");
timer = g_timer_new ();
g_print (" spinning for 3 seconds...\n");
g_timer_start (timer);
while (g_timer_elapsed (timer, NULL) < 3)
;
g_timer_stop (timer);
g_timer_destroy (timer);
g_print ("ok\n");
g_print ("checking g_strcasecmp...");
g_assert (g_strcasecmp ("FroboZZ", "frobozz") == 0);
g_assert (g_strcasecmp ("frobozz", "frobozz") == 0);
g_assert (g_strcasecmp ("frobozz", "FROBOZZ") == 0);
g_assert (g_strcasecmp ("FROBOZZ", "froboz") != 0);
g_assert (g_strcasecmp ("", "") == 0);
g_assert (g_strcasecmp ("!#%&/()", "!#%&/()") == 0);
g_assert (g_strcasecmp ("a", "b") < 0);
g_assert (g_strcasecmp ("a", "B") < 0);
g_assert (g_strcasecmp ("A", "b") < 0);
g_assert (g_strcasecmp ("A", "B") < 0);
g_assert (g_strcasecmp ("b", "a") > 0);
g_assert (g_strcasecmp ("b", "A") > 0);
g_assert (g_strcasecmp ("B", "a") > 0);
g_assert (g_strcasecmp ("B", "A") > 0);
g_print ("ok\n");
g_print ("checking g_strdup...");
g_assert(g_strdup(NULL) == NULL);
string = g_strdup(GLIB_TEST_STRING);
g_assert(string != NULL);
g_assert(strcmp(string, GLIB_TEST_STRING) == 0);
g_free(string);
g_print ("ok\n");
g_print ("checking g_strconcat...");
string = g_strconcat(GLIB_TEST_STRING, NULL);
g_assert(string != NULL);
g_assert(strcmp(string, GLIB_TEST_STRING) == 0);
g_free(string);
string = g_strconcat(GLIB_TEST_STRING, GLIB_TEST_STRING,
GLIB_TEST_STRING, NULL);
g_assert(string != NULL);
g_assert(strcmp(string, GLIB_TEST_STRING GLIB_TEST_STRING
GLIB_TEST_STRING) == 0);
g_free(string);
g_print ("ok\n");
g_print ("checking g_strdup_printf...");
string = g_strdup_printf ("%05d %-5s", 21, "test");
g_assert (string != NULL);
g_assert (strcmp(string, "00021 test ") == 0);
g_free (string);
g_print ("ok\n");
/* g_debug (argv[0]); */
/* Relation tests */
g_print ("checking relations...");
relation = g_relation_new (2);
g_relation_index (relation, 0, g_int_hash, g_int_equal);
g_relation_index (relation, 1, g_int_hash, g_int_equal);
for (i = 0; i < 1024; i += 1)
data[i] = i;
for (i = 1; i < 1023; i += 1)
{
g_relation_insert (relation, data + i, data + i + 1);
g_relation_insert (relation, data + i, data + i - 1);
}
for (i = 2; i < 1022; i += 1)
{
g_assert (! g_relation_exists (relation, data + i, data + i));
g_assert (! g_relation_exists (relation, data + i, data + i + 2));
g_assert (! g_relation_exists (relation, data + i, data + i - 2));
}
for (i = 1; i < 1023; i += 1)
{
g_assert (g_relation_exists (relation, data + i, data + i + 1));
g_assert (g_relation_exists (relation, data + i, data + i - 1));
}
for (i = 2; i < 1022; i += 1)
{
g_assert (g_relation_count (relation, data + i, 0) == 2);
g_assert (g_relation_count (relation, data + i, 1) == 2);
}
g_assert (g_relation_count (relation, data, 0) == 0);
g_assert (g_relation_count (relation, data + 42, 0) == 2);
g_assert (g_relation_count (relation, data + 43, 1) == 2);
g_assert (g_relation_count (relation, data + 41, 1) == 2);
g_relation_delete (relation, data + 42, 0);
g_assert (g_relation_count (relation, data + 42, 0) == 0);
g_assert (g_relation_count (relation, data + 43, 1) == 1);
g_assert (g_relation_count (relation, data + 41, 1) == 1);
tuples = g_relation_select (relation, data + 200, 0);
g_assert (tuples->len == 2);
#if 0
for (i = 0; i < tuples->len; i += 1)
{
printf ("%d %d\n",
*(gint*) g_tuples_index (tuples, i, 0),
*(gint*) g_tuples_index (tuples, i, 1));
}
#endif
g_assert (g_relation_exists (relation, data + 300, data + 301));
g_relation_delete (relation, data + 300, 0);
g_assert (!g_relation_exists (relation, data + 300, data + 301));
g_tuples_destroy (tuples);
g_relation_destroy (relation);
relation = NULL;
g_print ("ok\n");
g_print ("checking pointer arrays...");
gparray = g_ptr_array_new ();
for (i = 0; i < 10000; i++)
g_ptr_array_add (gparray, GINT_TO_POINTER (i));
for (i = 0; i < 10000; i++)
if (g_ptr_array_index (gparray, i) != GINT_TO_POINTER (i))
g_print ("array fails: %p ( %p )\n", g_ptr_array_index (gparray, i), GINT_TO_POINTER (i));
g_ptr_array_free (gparray, TRUE);
g_print ("ok\n");
g_print ("checking byte arrays...");
gbarray = g_byte_array_new ();
for (i = 0; i < 10000; i++)
g_byte_array_append (gbarray, (guint8*) "abcd", 4);
for (i = 0; i < 10000; i++)
{
g_assert (gbarray->data[4*i] == 'a');
g_assert (gbarray->data[4*i+1] == 'b');
g_assert (gbarray->data[4*i+2] == 'c');
g_assert (gbarray->data[4*i+3] == 'd');
}
g_byte_array_free (gbarray, TRUE);
g_print ("ok\n");
g_printerr ("g_log tests:");
g_warning ("harmless warning with parameters: %d %s %#x", 42, "Boo", 12345);
g_message ("the next warning is a test:");
string = NULL;
g_print (string);
g_print ("checking endian macros (host is ");
#if G_BYTE_ORDER == G_BIG_ENDIAN
g_print ("big endian)...");
#else
g_print ("little endian)...");
#endif
g_assert (GUINT16_SWAP_LE_BE (gu16t1) == gu16t2);
g_assert (GUINT32_SWAP_LE_BE (gu32t1) == gu32t2);
#ifdef G_HAVE_GINT64
g_assert (GUINT64_SWAP_LE_BE (gu64t1) == gu64t2);
#endif
g_print ("ok\n");
return 0;
}