Initial revision
authorOwen Taylor <otaylor@src.gnome.org>
Wed, 10 Jun 1998 23:21:14 +0000 (23:21 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Wed, 10 Jun 1998 23:21:14 +0000 (23:21 +0000)
68 files changed:
.cvsignore [new file with mode: 0644]
AUTHORS [new file with mode: 0644]
COPYING [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
ChangeLog.pre-2-0 [new file with mode: 0644]
ChangeLog.pre-2-10 [new file with mode: 0644]
ChangeLog.pre-2-12 [new file with mode: 0644]
ChangeLog.pre-2-2 [new file with mode: 0644]
ChangeLog.pre-2-4 [new file with mode: 0644]
ChangeLog.pre-2-6 [new file with mode: 0644]
ChangeLog.pre-2-8 [new file with mode: 0644]
INSTALL [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
NEWS [new file with mode: 0644]
README [new file with mode: 0644]
acconfig.h [new file with mode: 0644]
autogen.sh [new file with mode: 0755]
config.guess [new file with mode: 0755]
config.h.in [new file with mode: 0644]
config.sub [new file with mode: 0755]
configure.in [new file with mode: 0644]
garray.c [new file with mode: 0644]
gbacktrace.c [new file with mode: 0644]
gcache.c [new file with mode: 0644]
gcompletion.c [new file with mode: 0644]
gdataset.c [new file with mode: 0644]
gerror.c [new file with mode: 0644]
ghash.c [new file with mode: 0644]
glib-config [new file with mode: 0755]
glib-config.in [new file with mode: 0644]
glib.m4 [new file with mode: 0644]
glib/Makefile.am [new file with mode: 0644]
glib/garray.c [new file with mode: 0644]
glib/gbacktrace.c [new file with mode: 0644]
glib/gcache.c [new file with mode: 0644]
glib/gcompletion.c [new file with mode: 0644]
glib/gdataset.c [new file with mode: 0644]
glib/gerror.c [new file with mode: 0644]
glib/ghash.c [new file with mode: 0644]
glib/glist.c [new file with mode: 0644]
glib/gmem.c [new file with mode: 0644]
glib/gmessages.c [new file with mode: 0644]
glib/gprimes.c [new file with mode: 0644]
glib/gscanner.c [new file with mode: 0644]
glib/gslist.c [new file with mode: 0644]
glib/gstring.c [new file with mode: 0644]
glib/gtimer.c [new file with mode: 0644]
glib/gtree.c [new file with mode: 0644]
glib/gutils.c [new file with mode: 0644]
glibconfig.h.in [new file with mode: 0644]
glist.c [new file with mode: 0644]
gmem.c [new file with mode: 0644]
gmessages.c [new file with mode: 0644]
gprimes.c [new file with mode: 0644]
gscanner.c [new file with mode: 0644]
gslist.c [new file with mode: 0644]
gstring.c [new file with mode: 0644]
gtimer.c [new file with mode: 0644]
gtree.c [new file with mode: 0644]
gutils.c [new file with mode: 0644]
install-sh [new file with mode: 0755]
ltconfig [new file with mode: 0755]
ltmain.sh [new file with mode: 0644]
missing [new file with mode: 0755]
mkinstalldirs [new file with mode: 0755]
stamp-h.in [new file with mode: 0644]
testglib.c [new file with mode: 0644]
tests/testglib.c [new file with mode: 0644]

diff --git a/.cvsignore b/.cvsignore
new file mode 100644 (file)
index 0000000..b03d5fc
--- /dev/null
@@ -0,0 +1,17 @@
+*.lo
+Makefile
+Makefile.in
+configure
+aclocal.m4
+.deps
+_libs
+libglib-1.1.la
+config.log
+glibconfig.h
+glib.h
+libtool
+config.status
+stamp-h
+.libs
+testglib
+config.cache
diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..67f4e56
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1 @@
+Peter Mattis (petm@xcf.berkeley.edu)
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..4b21235
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,443 @@
+Wed Jun 10 12:56:07 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * glib.h: renamed g_const_pointer => gconstpointer
+
+Tue Jun  9 17:47:33 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * glib.h: Remove #error - HP/UX.
+
+Sat May 23 19:00:01 1998  Owen Taylor  <otaylor@gtk.org>
+  [ Combination of:
+     gtk-rrh-980412-0.patch (Raja R Harinath <harinath@cs.umn.edu>)
+     gtk-jbuhler-980516-0 (Jeremy Buhler <jbuhler@cs.washington.edu>) ]
+       
+       * glib.h ghash.c gstring.c gdataset.c gutils.c:
+       - Added new typedef g_const_pointer; expunged all incorrect
+         uses of 'const gpointer'.
+       - Fixed up warnings that that created,
+       - Changed GHashFunc and GCompareFunc to take g_const_pointer
+         arguments. (Necessary, but will cause warnings in existing
+         code until fixed)
+       - Added other new const in harmless positions.
+
+Mon Jun  8 01:06:47 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h: added enum-helper macros for code generation.
+       added G_BREAKPOINT().
+
+Sat Jun  6 14:09:22 PDT 1998 Manish Singh <yosh@gimp.org>
+
+       * gmem.c: commented out MEM_PROFILE and MEM_CHECK, causing weird
+       problems
+
+Wed Jun  3 06:19:42 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h (g_chunk_new0): convenience macro, for allocating small chunks 
+       like g_chunk_new() with additional 0 initialization.
+
+Mon Jun  1 04:43:27 1998  Tim Janik  <timj@gtk.org>
+
+       * ghash.c (g_hash_table_insert): wrote a comment describing why
+       a hash node's key should not also get replaced when overriding
+       previous entries.
+
+Tue May 26 18:30:06 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h (g_string_sized_new): new function to controll the preallocated
+       size of a GString.
+
+       * glib.h (g_strreversed): new function to reverse a string.
+
+Mon May 18 22:14:39 1998  Owen Taylor  <otaylor@gtk.org>
+(Yasuhiro SHIRASAKI <joke@awa.tohoku.ac.jp> : gtk-joke-980517-0.patch)
+       
+       * gutils.c: Restored a missing prototype for g_vsprintf.
+
+Wed May 20 05:02:26 1998  Tim Janik  <timj@gtk.org>
+
+        * glib.h: conditionally define NULL, FALSE and TRUE.
+        (g_mem_chunk_create): new convenience macro as a short hand for
+        g_mem_chunk_new().
+        (g_chunk_free): new convenience macro to be consistent with g_chunk_new.
+
+Tue, 19 May 1998 09:00:02 +0200  Â§Paolo Molaro <lupus@debian.org>
+
+       * gcompletion.c: generic functions for com<TAB>pletion...
+
+Sun May 17 10:48:27 1998  Tim Janik  <timj@gtk.org>
+
+       * gscanner.c (g_scanner_unexp_token): provide usefull default
+       specifications for identifier_spec and symbol_spec.
+
+       * glib.h: new functions g_slist_nth_data and g_list_nth_data to return
+       the data of the nth element in the list.
+
+Fri May 15 22:31:49 1998  Tim Janik  <timj@gtk.org>
+
+       * gscanner.c (g_scanner_unexp_token): removed spurious va_end(args)
+       that for some reason didn't produce a compiler wrning on my machine
+       (is va_end undefined for i386?).
+
+Fri May 15 12:32:08 1998  rodo  <doulik@karlin.mff.cuni.cz>
+
+       * gscanner.c: replaced some snprintf with g_snprintf
+
+Fri May 15 00:56:59 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h: further support for gcc function attributes: G_GNUC_FORMAT,
+       G_GNUC_NORETURN and G_GNUC_CONST.
+
+       * gscanner.c (g_scanner_stat_mode): changed stat() to lstat().
+       (g_scanner_msg_handler): "\n" at end of line!
+       (g_scanner_foreach_symbol): new function to iterate over the symbol
+       table (GScanner does value-wrapping).
+
+Thu May 14 04:14:12 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h: typedef gint gboolean;
+       this is needed to provide portability with big-endian platforms (e.g.
+       try sizeof(bool) for c++ on big-endians - it's 4).
+       this is also needed to maintain some_union.d_gint==some_union.d_gboolean.
+       plus, gint to gboolean casts and vice versa need to be possible without
+       loss.
+
+Tue May 12 19:22:58 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * glib/glib.h: Added macros G[U]INT_TO_POINTER() and
+       GPOINTER_TO_[U]INT for storing small integers integers
+       inside pointers. 
+       
+       * glib/testglib.c: Print sizeof() results
+       as g_print("%ld", (glong)sizeof(foo)), to deal with
+       size_t being long on Alpha's.
+
+Tue May 12 16:54:15 1998  Owen Taylor  <otaylor@gtk.org>
+       (James A <jamesa@demon.net> : gtk-jamesa-980511-4.patch)
+       
+       * glib.h gstring.c gmessages.c: Added some missing
+       const to arguments.
+
+       * gutils.c (g_strsignal.c): Added missing return statements.
+
+Mon May 11 21:11:54 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * gutils.c gmessages.c: Moved g_error, g_warning, g_message and
+       g_print from gutils.c to new file gmessages.c, to avoid having to
+       include <unistd.h> in gutils.c which was causing problems for the
+       g_strsignal implementation on FreeBSD boxes.
+
+Mon May 11 09:53:43 1998  Tim Janik  <timj@gtk.org>
+
+       * configure.in: preserve automake CFLAGS.
+
+       * Makefile.am: fully rename the created library to libglib-1.1.la.
+       this means we need to change certain portions of the Makefile.am on
+       major/minor version bumps.
+
+       * ltmain.sh: the -release option is not required anymore.
+
+        * glib.h: provide G_GNUC_FUNCTION and G_GNUC_PRETTY_FUNCTION to
+       avoid conditionals. unconditionally define NULL, TRUE, FALSE, MAX,
+       MIN, ABS and CLAMP, these macros might be screwed from other headers.
+
+Mon May 11 01:44:10 1998  Tim Janik  <timj@gtk.org>
+
+       * gdataset.c: new file, gdatasets implement the object data
+       mechanism from GtkObject. a generic data pointer is associated with
+       a certain location and a key id.
+
+Sat May  9 20:08:12 1998  Owen Taylor  <otaylor@gtk.org>
+
+        * glib/gmem.c: Experimentally restore GMemChunk
+        to its primeval state - where mem areas are
+        freed incrementally instead of searching the tree
+        every time a mem area is completely empty. Also,
+        always keep one mem chunk around. (Reduced calls
+        to malloc() a lot, but doesn't really improve
+        performance significiantly)
+
+Thu May  7 08:17:28 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h (G_GNUC_PRINTF):
+       (G_GNUC_SCANF): macros to facilitate the printf/scanf format argument
+       checking of gcc.
+
+       * gstring.c: const corrections, string!=NULL checks at function entry.
+       (g_string_down): new function for tolower(3) conversion.
+       (g_string_up): new function for toupper(3) conversion.
+
+       * gutils.c: const corrections.
+       (g_strdown): g_string_down() counterpart.
+       (g_strup): g_string_up() counterpart.
+
+       * gscanner.c (g_scanner_unexp_token):
+       (g_scanner_error):
+       (g_scanner_warn): new functions to let a scanner put out warnings
+       or errors, especially to react on unexpected tokens.
+
+       * gslist.c:
+       (g_slist_index): find out about about the position of a
+       certain data pointer.
+       (g_slist_position): find out about about the position of a
+       certain node.
+
+       * glist.c:
+       (g_list_index): find out about about the position of a
+       certain data pointer.
+
+Thu May  7 05:14:19 1998  Tim Janik  <timj@gtk.org>
+
+       * ltmain.sh: added a new commandline flag -postfix similar to -release,
+       but will immediately change the library name.
+
+       * Makefile.am: specify -postfix and -version-info
+
+       * configure.in: version bump to 1.1.0. added GLIB_INTERFACE_AGE and
+       GLIB_BINARY_AGE. calculate LT_* variables for libtool.
+
+Fri May  1 16:36:08 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * gutils.c: (g_strcasecmp). Check for isupper before
+       taking tolower, and account for macroized tolower.
+
+       * gutils.c (g_error): Check for recursion.
+
+1998-04-27  Elliot Lee  <sopwith@cuc.ml.org>
+
+       * glist.c (g_list_position): New function to find the position of
+       a link in a list - should be the inverse of g_list_nth(), but
+       haven't tested it so poof.
+
+Thu Apr 30 21:41:30 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * gstring.c : Check arguments more carefully, 
+       (gtk-draco-980423-1.patch; ramsey@rhrk.uni-kl.de) 
+
+Tue Apr  7 19:36:48 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gutils.c (g_direct_compare): Removed, because that's what
+       a NULL comparison function means. And it wasn't 64 bit safe.
+
+Mon Apr  6 18:43:25 1998  Tim Janik  <timj@gtk.org>
+
+       * gscanner.c (g_scanner_get_token_ll): fixed a bug that caused floats
+       of the format ".xxx" to be parsed as "xxx".
+
+Fri Apr  3 20:36:35 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gutils.c (g_parse_debug_string): Make debug string
+       parsine case-insensitive
+
+Fri Apr  3 17:03:18 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * gstring.c: corrected possible overrun when inserting into
+       GStrings (thanks Elrond)
+
+Fri Apr  3 18:05:45 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * testglib.c: Removed literal german from strings
+       to appease SGI compiler.
+       
+Thu Mar 26 20:47:21 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * configure.in glib glibconfig.h.in: Add test for atexit/on_exit -
+       use on_exit if atexit not found in definition of ATEXIT.
+
+Wed Mar 25 15:23:37 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * Makefile.am: Switched glibconfig.h rule from HEADERS
+       to DATA, so that it is not added to DISTFILES
+
+Wed Mar 18 22:27:08 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * garray.c: g_rarray_truncate length done correctly
+
+Sun Mar 15 07:13:34 1998  Tim Janik  <timj@gimp.org>
+
+       * gutils.c: changed *_handler variables to be named glib_*_handler,
+       so you can easily access them from gdb.
+
+Sat Mar 14 17:47:43 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * Makefile.am: Don't refer to current directory as $(top_builddir)
+       to avoid confusing non-gmakes
+
+Sat Mar 14 01:37:35 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * Makefile.am (configincludedir): Moved glibconfig.h to
+          $(pkglibdir)/include
+
+Tue Mar 10 02:03:12 1998  Tim Janik  <timj@gimp.org>
+
+       * gscanner.c (g_scanner_destroy_symbol_table_entry): new function to
+       free symbol table entries upon destruction
+       (gtk-gronlund-980309-0.patch.gz).
+
+Mon Mar  9 15:02:21 1998  Tim Janik  <timj@gimp.org>
+
+       * glib.h: changed *_length functions to return guint.
+       changed *_nth functions to take guint as argument.
+
+       * glist.c: adapted g_list_length and g_list_length.
+
+       * gslist.c: adapted g_slist_length and g_slist_length.
+
+Mon Mar  2 17:51:18 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glib.h gutils.c : changed g_strcasecmp
+         to take gchar* not guchar*
+
+       * testglib.c: Remove trailing ; after functions
+       
+Sun Mar  1 19:04:40 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glib.h gstring.c: Added g_string_insert[_c]()
+         and g_string_erase().
+
+         From: Stefan Wille  <1wille@vsys1.informatik.uni-hamburg.de>
+
+Mon Feb 16 23:05:06 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glist.c (g_list_insert_sorted): Changed function
+         so elements are always inserted, even if they compare
+         equal with another.
+
+Thu Feb 12 22:48:11 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gstring.c glib.h: removed deprecated g_string_equal
+         and g_string_hash.
+
+Tue Feb 10 13:04:36 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * configure.in: Add check to see if the C library's
+         iswalnum can actually be used. (Not true for
+         Linux libc-5.4.38)
+
+Sat Feb  7 11:48:09 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gstring.c gutils.c: added some additional consts in
+         appropriate places to remove a warning
+
+Sat Feb  7 11:15:54 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gutils.c: include <ctype.h> for tolower()
+
+Fri Jan 30 23:57:17 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * added and autoconfigured in a new utility function
+       g_strcasecmp
+
+Wed Jan 28 23:53:27 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * glist.c
+       * gslist.c
+       * testglib.c: the sort functions compared backwards. Fixed
+       * glib.h: list iterator macros now check for NULL pointers
+
+Tue Jan 27 09:46:57 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * gstring.c: g_string_prepend and g_string_prepend_c had
+       interchanged src and dest parameters for g_memmove. Fixed.
+
+Tue Jan 27 01:38:52 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * gslist.c: fixed a really, really lame error. g_slist_insert
+       didn't hook the data in! Reworked the routine to reflect the
+       functionality of g_list
+
+Wed Jan 21 01:13:25 1998  Tim Janik  <timj@psynet.net>
+
+       * Applied patch from (Raja R Harinath <harinath@cs.umn.edu>)
+         to add function g_snprintf.
+        * configure.in (AC_CHECK_FUNCS): Check for vsnprintf.
+        * glib.h: Add prototype for g_snprintf.
+        * glibconfig.h.in: Add HAVE_VSNPRINTF.
+        * gutils.c (g_snprintf): new function.
+
+Sat Jan 17 23:52:40 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gstring.{c,h} gscanner.c:
+          renamed g_string_equal => g_str_equal
+          renamed g_string_hash => g_str_hash
+         And const corrected. Old functions left in for now.
+       
+Fri Jan  9 20:03:46 1998  Tim Janik  <timj@psynet.net>
+
+       * gutils.c (g_strerror): changed message for EAGAIN from
+       "no more processes" to "try again" since EAGAIN is used with
+       functions else than fork().
+
+       * gscanner.c (g_scanner_get_token_ll): use strtol() instead of
+       strtoul() to avoid conflicts with solaris.
+
+       * merged the glib portions from Jan 2 to Jan 7 out of gtk+/ChangeLog
+       into this file.
+
+Wed Jan  7 02:14:30 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * glib.h:
+       * glist.c:
+       * gslist.c:
+       * testglib.c: Added g_[s]list_insert_sorted function
+       and appropriate tests in testglib
+
+Sat Jan  3 20:23:25 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glib.h: Changed guint32 -> guint for bitfields.
+       (Bitfields must be int or unsigned int?)
+
+Fri Jan  2 23:52 PST 1998 Jay Painter <jpaint@serv.net>
+
+       * glib_pre1.h: 
+       * glib_pre2.h: 
+       * glib.h: reverted glibconfig.h and glib.h files back to the
+       way they were before my ugly hack.
+
+       * gscanner.c: removed inlines from clist and gscanner
+
+Tue Dec 23 02:49:51 1997  Tim Janik  <timj@psynet.net>
+
+       * gscanner.c: new file for GScanner: Flexible lexical scanner for
+       general purpose.
+       * glib_pre2.h: added GScanner includes. added g_strconcat and g_strtod.
+       gutils.c (g_strconcat): new function for string concatenation of NULL
+       terminated parameter list.
+       (g_strtod): new function to perform best string to double conversion
+       with or without consideration of the current locale.
+
+Mon Dec 15 19:33:58 1997  Tim Janik  <timj@psynet.net>
+
+       * glist.c: minor optimizations:
+       (g_list_append): `if' optimized for common code path, commented out
+       unneccessary `assert', saved one variable assignment.
+       (g_list_prepend): saved two (conditioned) variable assignment.
+       (g_list_insert): saved one  (conditioned) variable assignment,
+       saved one variable assignment.
+       (g_list_remove): `if' optimized for common code path, saved two
+       variable assignments by using `g_list_free_1' (which is even
+       faster) instead of `g_list_free'.
+       (g_list_reverse): saved allocation of one variable, saved one
+       variable assignment.
+
+Wed Dec 10 23:27:20 1997  Tim Janik  <timj@psynet.net>
+
+       * glib_pre1.h: 
+       * glib_pre2.h: 
+       * glib.h: this file now gets concatenated by makeglib_h from
+       glib_pre1.h and glib_pre2.h to merge in glibconfig.h wich got
+       created by configure (done by Jay Painter).
+
+       * glib_pre2.h: the g_assert*() and g_return_*_fail() macros
+       are wrapped by G_STMT_START and G_STMT_END now, to avoid conflicts
+       when used within if (...) g_macro(); else ... conditionals.
+       
+Tue Dec 17 13:14:07 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * glib.h: Changed 'g_return_if_fail' and 'g_return_val_if_fail' to
+       not call 'g_string' but to simply stringify the
+       expression. Calling 'g_string' causes the expression to be
+       expanded which is undesired.
+
+Sun Dec  1 01:30:48 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * Started ChangeLog
diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0
new file mode 100644 (file)
index 0000000..4b21235
--- /dev/null
@@ -0,0 +1,443 @@
+Wed Jun 10 12:56:07 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * glib.h: renamed g_const_pointer => gconstpointer
+
+Tue Jun  9 17:47:33 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * glib.h: Remove #error - HP/UX.
+
+Sat May 23 19:00:01 1998  Owen Taylor  <otaylor@gtk.org>
+  [ Combination of:
+     gtk-rrh-980412-0.patch (Raja R Harinath <harinath@cs.umn.edu>)
+     gtk-jbuhler-980516-0 (Jeremy Buhler <jbuhler@cs.washington.edu>) ]
+       
+       * glib.h ghash.c gstring.c gdataset.c gutils.c:
+       - Added new typedef g_const_pointer; expunged all incorrect
+         uses of 'const gpointer'.
+       - Fixed up warnings that that created,
+       - Changed GHashFunc and GCompareFunc to take g_const_pointer
+         arguments. (Necessary, but will cause warnings in existing
+         code until fixed)
+       - Added other new const in harmless positions.
+
+Mon Jun  8 01:06:47 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h: added enum-helper macros for code generation.
+       added G_BREAKPOINT().
+
+Sat Jun  6 14:09:22 PDT 1998 Manish Singh <yosh@gimp.org>
+
+       * gmem.c: commented out MEM_PROFILE and MEM_CHECK, causing weird
+       problems
+
+Wed Jun  3 06:19:42 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h (g_chunk_new0): convenience macro, for allocating small chunks 
+       like g_chunk_new() with additional 0 initialization.
+
+Mon Jun  1 04:43:27 1998  Tim Janik  <timj@gtk.org>
+
+       * ghash.c (g_hash_table_insert): wrote a comment describing why
+       a hash node's key should not also get replaced when overriding
+       previous entries.
+
+Tue May 26 18:30:06 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h (g_string_sized_new): new function to controll the preallocated
+       size of a GString.
+
+       * glib.h (g_strreversed): new function to reverse a string.
+
+Mon May 18 22:14:39 1998  Owen Taylor  <otaylor@gtk.org>
+(Yasuhiro SHIRASAKI <joke@awa.tohoku.ac.jp> : gtk-joke-980517-0.patch)
+       
+       * gutils.c: Restored a missing prototype for g_vsprintf.
+
+Wed May 20 05:02:26 1998  Tim Janik  <timj@gtk.org>
+
+        * glib.h: conditionally define NULL, FALSE and TRUE.
+        (g_mem_chunk_create): new convenience macro as a short hand for
+        g_mem_chunk_new().
+        (g_chunk_free): new convenience macro to be consistent with g_chunk_new.
+
+Tue, 19 May 1998 09:00:02 +0200  Â§Paolo Molaro <lupus@debian.org>
+
+       * gcompletion.c: generic functions for com<TAB>pletion...
+
+Sun May 17 10:48:27 1998  Tim Janik  <timj@gtk.org>
+
+       * gscanner.c (g_scanner_unexp_token): provide usefull default
+       specifications for identifier_spec and symbol_spec.
+
+       * glib.h: new functions g_slist_nth_data and g_list_nth_data to return
+       the data of the nth element in the list.
+
+Fri May 15 22:31:49 1998  Tim Janik  <timj@gtk.org>
+
+       * gscanner.c (g_scanner_unexp_token): removed spurious va_end(args)
+       that for some reason didn't produce a compiler wrning on my machine
+       (is va_end undefined for i386?).
+
+Fri May 15 12:32:08 1998  rodo  <doulik@karlin.mff.cuni.cz>
+
+       * gscanner.c: replaced some snprintf with g_snprintf
+
+Fri May 15 00:56:59 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h: further support for gcc function attributes: G_GNUC_FORMAT,
+       G_GNUC_NORETURN and G_GNUC_CONST.
+
+       * gscanner.c (g_scanner_stat_mode): changed stat() to lstat().
+       (g_scanner_msg_handler): "\n" at end of line!
+       (g_scanner_foreach_symbol): new function to iterate over the symbol
+       table (GScanner does value-wrapping).
+
+Thu May 14 04:14:12 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h: typedef gint gboolean;
+       this is needed to provide portability with big-endian platforms (e.g.
+       try sizeof(bool) for c++ on big-endians - it's 4).
+       this is also needed to maintain some_union.d_gint==some_union.d_gboolean.
+       plus, gint to gboolean casts and vice versa need to be possible without
+       loss.
+
+Tue May 12 19:22:58 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * glib/glib.h: Added macros G[U]INT_TO_POINTER() and
+       GPOINTER_TO_[U]INT for storing small integers integers
+       inside pointers. 
+       
+       * glib/testglib.c: Print sizeof() results
+       as g_print("%ld", (glong)sizeof(foo)), to deal with
+       size_t being long on Alpha's.
+
+Tue May 12 16:54:15 1998  Owen Taylor  <otaylor@gtk.org>
+       (James A <jamesa@demon.net> : gtk-jamesa-980511-4.patch)
+       
+       * glib.h gstring.c gmessages.c: Added some missing
+       const to arguments.
+
+       * gutils.c (g_strsignal.c): Added missing return statements.
+
+Mon May 11 21:11:54 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * gutils.c gmessages.c: Moved g_error, g_warning, g_message and
+       g_print from gutils.c to new file gmessages.c, to avoid having to
+       include <unistd.h> in gutils.c which was causing problems for the
+       g_strsignal implementation on FreeBSD boxes.
+
+Mon May 11 09:53:43 1998  Tim Janik  <timj@gtk.org>
+
+       * configure.in: preserve automake CFLAGS.
+
+       * Makefile.am: fully rename the created library to libglib-1.1.la.
+       this means we need to change certain portions of the Makefile.am on
+       major/minor version bumps.
+
+       * ltmain.sh: the -release option is not required anymore.
+
+        * glib.h: provide G_GNUC_FUNCTION and G_GNUC_PRETTY_FUNCTION to
+       avoid conditionals. unconditionally define NULL, TRUE, FALSE, MAX,
+       MIN, ABS and CLAMP, these macros might be screwed from other headers.
+
+Mon May 11 01:44:10 1998  Tim Janik  <timj@gtk.org>
+
+       * gdataset.c: new file, gdatasets implement the object data
+       mechanism from GtkObject. a generic data pointer is associated with
+       a certain location and a key id.
+
+Sat May  9 20:08:12 1998  Owen Taylor  <otaylor@gtk.org>
+
+        * glib/gmem.c: Experimentally restore GMemChunk
+        to its primeval state - where mem areas are
+        freed incrementally instead of searching the tree
+        every time a mem area is completely empty. Also,
+        always keep one mem chunk around. (Reduced calls
+        to malloc() a lot, but doesn't really improve
+        performance significiantly)
+
+Thu May  7 08:17:28 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h (G_GNUC_PRINTF):
+       (G_GNUC_SCANF): macros to facilitate the printf/scanf format argument
+       checking of gcc.
+
+       * gstring.c: const corrections, string!=NULL checks at function entry.
+       (g_string_down): new function for tolower(3) conversion.
+       (g_string_up): new function for toupper(3) conversion.
+
+       * gutils.c: const corrections.
+       (g_strdown): g_string_down() counterpart.
+       (g_strup): g_string_up() counterpart.
+
+       * gscanner.c (g_scanner_unexp_token):
+       (g_scanner_error):
+       (g_scanner_warn): new functions to let a scanner put out warnings
+       or errors, especially to react on unexpected tokens.
+
+       * gslist.c:
+       (g_slist_index): find out about about the position of a
+       certain data pointer.
+       (g_slist_position): find out about about the position of a
+       certain node.
+
+       * glist.c:
+       (g_list_index): find out about about the position of a
+       certain data pointer.
+
+Thu May  7 05:14:19 1998  Tim Janik  <timj@gtk.org>
+
+       * ltmain.sh: added a new commandline flag -postfix similar to -release,
+       but will immediately change the library name.
+
+       * Makefile.am: specify -postfix and -version-info
+
+       * configure.in: version bump to 1.1.0. added GLIB_INTERFACE_AGE and
+       GLIB_BINARY_AGE. calculate LT_* variables for libtool.
+
+Fri May  1 16:36:08 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * gutils.c: (g_strcasecmp). Check for isupper before
+       taking tolower, and account for macroized tolower.
+
+       * gutils.c (g_error): Check for recursion.
+
+1998-04-27  Elliot Lee  <sopwith@cuc.ml.org>
+
+       * glist.c (g_list_position): New function to find the position of
+       a link in a list - should be the inverse of g_list_nth(), but
+       haven't tested it so poof.
+
+Thu Apr 30 21:41:30 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * gstring.c : Check arguments more carefully, 
+       (gtk-draco-980423-1.patch; ramsey@rhrk.uni-kl.de) 
+
+Tue Apr  7 19:36:48 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gutils.c (g_direct_compare): Removed, because that's what
+       a NULL comparison function means. And it wasn't 64 bit safe.
+
+Mon Apr  6 18:43:25 1998  Tim Janik  <timj@gtk.org>
+
+       * gscanner.c (g_scanner_get_token_ll): fixed a bug that caused floats
+       of the format ".xxx" to be parsed as "xxx".
+
+Fri Apr  3 20:36:35 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gutils.c (g_parse_debug_string): Make debug string
+       parsine case-insensitive
+
+Fri Apr  3 17:03:18 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * gstring.c: corrected possible overrun when inserting into
+       GStrings (thanks Elrond)
+
+Fri Apr  3 18:05:45 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * testglib.c: Removed literal german from strings
+       to appease SGI compiler.
+       
+Thu Mar 26 20:47:21 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * configure.in glib glibconfig.h.in: Add test for atexit/on_exit -
+       use on_exit if atexit not found in definition of ATEXIT.
+
+Wed Mar 25 15:23:37 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * Makefile.am: Switched glibconfig.h rule from HEADERS
+       to DATA, so that it is not added to DISTFILES
+
+Wed Mar 18 22:27:08 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * garray.c: g_rarray_truncate length done correctly
+
+Sun Mar 15 07:13:34 1998  Tim Janik  <timj@gimp.org>
+
+       * gutils.c: changed *_handler variables to be named glib_*_handler,
+       so you can easily access them from gdb.
+
+Sat Mar 14 17:47:43 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * Makefile.am: Don't refer to current directory as $(top_builddir)
+       to avoid confusing non-gmakes
+
+Sat Mar 14 01:37:35 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * Makefile.am (configincludedir): Moved glibconfig.h to
+          $(pkglibdir)/include
+
+Tue Mar 10 02:03:12 1998  Tim Janik  <timj@gimp.org>
+
+       * gscanner.c (g_scanner_destroy_symbol_table_entry): new function to
+       free symbol table entries upon destruction
+       (gtk-gronlund-980309-0.patch.gz).
+
+Mon Mar  9 15:02:21 1998  Tim Janik  <timj@gimp.org>
+
+       * glib.h: changed *_length functions to return guint.
+       changed *_nth functions to take guint as argument.
+
+       * glist.c: adapted g_list_length and g_list_length.
+
+       * gslist.c: adapted g_slist_length and g_slist_length.
+
+Mon Mar  2 17:51:18 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glib.h gutils.c : changed g_strcasecmp
+         to take gchar* not guchar*
+
+       * testglib.c: Remove trailing ; after functions
+       
+Sun Mar  1 19:04:40 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glib.h gstring.c: Added g_string_insert[_c]()
+         and g_string_erase().
+
+         From: Stefan Wille  <1wille@vsys1.informatik.uni-hamburg.de>
+
+Mon Feb 16 23:05:06 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glist.c (g_list_insert_sorted): Changed function
+         so elements are always inserted, even if they compare
+         equal with another.
+
+Thu Feb 12 22:48:11 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gstring.c glib.h: removed deprecated g_string_equal
+         and g_string_hash.
+
+Tue Feb 10 13:04:36 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * configure.in: Add check to see if the C library's
+         iswalnum can actually be used. (Not true for
+         Linux libc-5.4.38)
+
+Sat Feb  7 11:48:09 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gstring.c gutils.c: added some additional consts in
+         appropriate places to remove a warning
+
+Sat Feb  7 11:15:54 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gutils.c: include <ctype.h> for tolower()
+
+Fri Jan 30 23:57:17 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * added and autoconfigured in a new utility function
+       g_strcasecmp
+
+Wed Jan 28 23:53:27 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * glist.c
+       * gslist.c
+       * testglib.c: the sort functions compared backwards. Fixed
+       * glib.h: list iterator macros now check for NULL pointers
+
+Tue Jan 27 09:46:57 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * gstring.c: g_string_prepend and g_string_prepend_c had
+       interchanged src and dest parameters for g_memmove. Fixed.
+
+Tue Jan 27 01:38:52 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * gslist.c: fixed a really, really lame error. g_slist_insert
+       didn't hook the data in! Reworked the routine to reflect the
+       functionality of g_list
+
+Wed Jan 21 01:13:25 1998  Tim Janik  <timj@psynet.net>
+
+       * Applied patch from (Raja R Harinath <harinath@cs.umn.edu>)
+         to add function g_snprintf.
+        * configure.in (AC_CHECK_FUNCS): Check for vsnprintf.
+        * glib.h: Add prototype for g_snprintf.
+        * glibconfig.h.in: Add HAVE_VSNPRINTF.
+        * gutils.c (g_snprintf): new function.
+
+Sat Jan 17 23:52:40 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gstring.{c,h} gscanner.c:
+          renamed g_string_equal => g_str_equal
+          renamed g_string_hash => g_str_hash
+         And const corrected. Old functions left in for now.
+       
+Fri Jan  9 20:03:46 1998  Tim Janik  <timj@psynet.net>
+
+       * gutils.c (g_strerror): changed message for EAGAIN from
+       "no more processes" to "try again" since EAGAIN is used with
+       functions else than fork().
+
+       * gscanner.c (g_scanner_get_token_ll): use strtol() instead of
+       strtoul() to avoid conflicts with solaris.
+
+       * merged the glib portions from Jan 2 to Jan 7 out of gtk+/ChangeLog
+       into this file.
+
+Wed Jan  7 02:14:30 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * glib.h:
+       * glist.c:
+       * gslist.c:
+       * testglib.c: Added g_[s]list_insert_sorted function
+       and appropriate tests in testglib
+
+Sat Jan  3 20:23:25 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glib.h: Changed guint32 -> guint for bitfields.
+       (Bitfields must be int or unsigned int?)
+
+Fri Jan  2 23:52 PST 1998 Jay Painter <jpaint@serv.net>
+
+       * glib_pre1.h: 
+       * glib_pre2.h: 
+       * glib.h: reverted glibconfig.h and glib.h files back to the
+       way they were before my ugly hack.
+
+       * gscanner.c: removed inlines from clist and gscanner
+
+Tue Dec 23 02:49:51 1997  Tim Janik  <timj@psynet.net>
+
+       * gscanner.c: new file for GScanner: Flexible lexical scanner for
+       general purpose.
+       * glib_pre2.h: added GScanner includes. added g_strconcat and g_strtod.
+       gutils.c (g_strconcat): new function for string concatenation of NULL
+       terminated parameter list.
+       (g_strtod): new function to perform best string to double conversion
+       with or without consideration of the current locale.
+
+Mon Dec 15 19:33:58 1997  Tim Janik  <timj@psynet.net>
+
+       * glist.c: minor optimizations:
+       (g_list_append): `if' optimized for common code path, commented out
+       unneccessary `assert', saved one variable assignment.
+       (g_list_prepend): saved two (conditioned) variable assignment.
+       (g_list_insert): saved one  (conditioned) variable assignment,
+       saved one variable assignment.
+       (g_list_remove): `if' optimized for common code path, saved two
+       variable assignments by using `g_list_free_1' (which is even
+       faster) instead of `g_list_free'.
+       (g_list_reverse): saved allocation of one variable, saved one
+       variable assignment.
+
+Wed Dec 10 23:27:20 1997  Tim Janik  <timj@psynet.net>
+
+       * glib_pre1.h: 
+       * glib_pre2.h: 
+       * glib.h: this file now gets concatenated by makeglib_h from
+       glib_pre1.h and glib_pre2.h to merge in glibconfig.h wich got
+       created by configure (done by Jay Painter).
+
+       * glib_pre2.h: the g_assert*() and g_return_*_fail() macros
+       are wrapped by G_STMT_START and G_STMT_END now, to avoid conflicts
+       when used within if (...) g_macro(); else ... conditionals.
+       
+Tue Dec 17 13:14:07 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * glib.h: Changed 'g_return_if_fail' and 'g_return_val_if_fail' to
+       not call 'g_string' but to simply stringify the
+       expression. Calling 'g_string' causes the expression to be
+       expanded which is undesired.
+
+Sun Dec  1 01:30:48 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * Started ChangeLog
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
new file mode 100644 (file)
index 0000000..4b21235
--- /dev/null
@@ -0,0 +1,443 @@
+Wed Jun 10 12:56:07 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * glib.h: renamed g_const_pointer => gconstpointer
+
+Tue Jun  9 17:47:33 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * glib.h: Remove #error - HP/UX.
+
+Sat May 23 19:00:01 1998  Owen Taylor  <otaylor@gtk.org>
+  [ Combination of:
+     gtk-rrh-980412-0.patch (Raja R Harinath <harinath@cs.umn.edu>)
+     gtk-jbuhler-980516-0 (Jeremy Buhler <jbuhler@cs.washington.edu>) ]
+       
+       * glib.h ghash.c gstring.c gdataset.c gutils.c:
+       - Added new typedef g_const_pointer; expunged all incorrect
+         uses of 'const gpointer'.
+       - Fixed up warnings that that created,
+       - Changed GHashFunc and GCompareFunc to take g_const_pointer
+         arguments. (Necessary, but will cause warnings in existing
+         code until fixed)
+       - Added other new const in harmless positions.
+
+Mon Jun  8 01:06:47 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h: added enum-helper macros for code generation.
+       added G_BREAKPOINT().
+
+Sat Jun  6 14:09:22 PDT 1998 Manish Singh <yosh@gimp.org>
+
+       * gmem.c: commented out MEM_PROFILE and MEM_CHECK, causing weird
+       problems
+
+Wed Jun  3 06:19:42 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h (g_chunk_new0): convenience macro, for allocating small chunks 
+       like g_chunk_new() with additional 0 initialization.
+
+Mon Jun  1 04:43:27 1998  Tim Janik  <timj@gtk.org>
+
+       * ghash.c (g_hash_table_insert): wrote a comment describing why
+       a hash node's key should not also get replaced when overriding
+       previous entries.
+
+Tue May 26 18:30:06 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h (g_string_sized_new): new function to controll the preallocated
+       size of a GString.
+
+       * glib.h (g_strreversed): new function to reverse a string.
+
+Mon May 18 22:14:39 1998  Owen Taylor  <otaylor@gtk.org>
+(Yasuhiro SHIRASAKI <joke@awa.tohoku.ac.jp> : gtk-joke-980517-0.patch)
+       
+       * gutils.c: Restored a missing prototype for g_vsprintf.
+
+Wed May 20 05:02:26 1998  Tim Janik  <timj@gtk.org>
+
+        * glib.h: conditionally define NULL, FALSE and TRUE.
+        (g_mem_chunk_create): new convenience macro as a short hand for
+        g_mem_chunk_new().
+        (g_chunk_free): new convenience macro to be consistent with g_chunk_new.
+
+Tue, 19 May 1998 09:00:02 +0200  Â§Paolo Molaro <lupus@debian.org>
+
+       * gcompletion.c: generic functions for com<TAB>pletion...
+
+Sun May 17 10:48:27 1998  Tim Janik  <timj@gtk.org>
+
+       * gscanner.c (g_scanner_unexp_token): provide usefull default
+       specifications for identifier_spec and symbol_spec.
+
+       * glib.h: new functions g_slist_nth_data and g_list_nth_data to return
+       the data of the nth element in the list.
+
+Fri May 15 22:31:49 1998  Tim Janik  <timj@gtk.org>
+
+       * gscanner.c (g_scanner_unexp_token): removed spurious va_end(args)
+       that for some reason didn't produce a compiler wrning on my machine
+       (is va_end undefined for i386?).
+
+Fri May 15 12:32:08 1998  rodo  <doulik@karlin.mff.cuni.cz>
+
+       * gscanner.c: replaced some snprintf with g_snprintf
+
+Fri May 15 00:56:59 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h: further support for gcc function attributes: G_GNUC_FORMAT,
+       G_GNUC_NORETURN and G_GNUC_CONST.
+
+       * gscanner.c (g_scanner_stat_mode): changed stat() to lstat().
+       (g_scanner_msg_handler): "\n" at end of line!
+       (g_scanner_foreach_symbol): new function to iterate over the symbol
+       table (GScanner does value-wrapping).
+
+Thu May 14 04:14:12 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h: typedef gint gboolean;
+       this is needed to provide portability with big-endian platforms (e.g.
+       try sizeof(bool) for c++ on big-endians - it's 4).
+       this is also needed to maintain some_union.d_gint==some_union.d_gboolean.
+       plus, gint to gboolean casts and vice versa need to be possible without
+       loss.
+
+Tue May 12 19:22:58 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * glib/glib.h: Added macros G[U]INT_TO_POINTER() and
+       GPOINTER_TO_[U]INT for storing small integers integers
+       inside pointers. 
+       
+       * glib/testglib.c: Print sizeof() results
+       as g_print("%ld", (glong)sizeof(foo)), to deal with
+       size_t being long on Alpha's.
+
+Tue May 12 16:54:15 1998  Owen Taylor  <otaylor@gtk.org>
+       (James A <jamesa@demon.net> : gtk-jamesa-980511-4.patch)
+       
+       * glib.h gstring.c gmessages.c: Added some missing
+       const to arguments.
+
+       * gutils.c (g_strsignal.c): Added missing return statements.
+
+Mon May 11 21:11:54 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * gutils.c gmessages.c: Moved g_error, g_warning, g_message and
+       g_print from gutils.c to new file gmessages.c, to avoid having to
+       include <unistd.h> in gutils.c which was causing problems for the
+       g_strsignal implementation on FreeBSD boxes.
+
+Mon May 11 09:53:43 1998  Tim Janik  <timj@gtk.org>
+
+       * configure.in: preserve automake CFLAGS.
+
+       * Makefile.am: fully rename the created library to libglib-1.1.la.
+       this means we need to change certain portions of the Makefile.am on
+       major/minor version bumps.
+
+       * ltmain.sh: the -release option is not required anymore.
+
+        * glib.h: provide G_GNUC_FUNCTION and G_GNUC_PRETTY_FUNCTION to
+       avoid conditionals. unconditionally define NULL, TRUE, FALSE, MAX,
+       MIN, ABS and CLAMP, these macros might be screwed from other headers.
+
+Mon May 11 01:44:10 1998  Tim Janik  <timj@gtk.org>
+
+       * gdataset.c: new file, gdatasets implement the object data
+       mechanism from GtkObject. a generic data pointer is associated with
+       a certain location and a key id.
+
+Sat May  9 20:08:12 1998  Owen Taylor  <otaylor@gtk.org>
+
+        * glib/gmem.c: Experimentally restore GMemChunk
+        to its primeval state - where mem areas are
+        freed incrementally instead of searching the tree
+        every time a mem area is completely empty. Also,
+        always keep one mem chunk around. (Reduced calls
+        to malloc() a lot, but doesn't really improve
+        performance significiantly)
+
+Thu May  7 08:17:28 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h (G_GNUC_PRINTF):
+       (G_GNUC_SCANF): macros to facilitate the printf/scanf format argument
+       checking of gcc.
+
+       * gstring.c: const corrections, string!=NULL checks at function entry.
+       (g_string_down): new function for tolower(3) conversion.
+       (g_string_up): new function for toupper(3) conversion.
+
+       * gutils.c: const corrections.
+       (g_strdown): g_string_down() counterpart.
+       (g_strup): g_string_up() counterpart.
+
+       * gscanner.c (g_scanner_unexp_token):
+       (g_scanner_error):
+       (g_scanner_warn): new functions to let a scanner put out warnings
+       or errors, especially to react on unexpected tokens.
+
+       * gslist.c:
+       (g_slist_index): find out about about the position of a
+       certain data pointer.
+       (g_slist_position): find out about about the position of a
+       certain node.
+
+       * glist.c:
+       (g_list_index): find out about about the position of a
+       certain data pointer.
+
+Thu May  7 05:14:19 1998  Tim Janik  <timj@gtk.org>
+
+       * ltmain.sh: added a new commandline flag -postfix similar to -release,
+       but will immediately change the library name.
+
+       * Makefile.am: specify -postfix and -version-info
+
+       * configure.in: version bump to 1.1.0. added GLIB_INTERFACE_AGE and
+       GLIB_BINARY_AGE. calculate LT_* variables for libtool.
+
+Fri May  1 16:36:08 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * gutils.c: (g_strcasecmp). Check for isupper before
+       taking tolower, and account for macroized tolower.
+
+       * gutils.c (g_error): Check for recursion.
+
+1998-04-27  Elliot Lee  <sopwith@cuc.ml.org>
+
+       * glist.c (g_list_position): New function to find the position of
+       a link in a list - should be the inverse of g_list_nth(), but
+       haven't tested it so poof.
+
+Thu Apr 30 21:41:30 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * gstring.c : Check arguments more carefully, 
+       (gtk-draco-980423-1.patch; ramsey@rhrk.uni-kl.de) 
+
+Tue Apr  7 19:36:48 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gutils.c (g_direct_compare): Removed, because that's what
+       a NULL comparison function means. And it wasn't 64 bit safe.
+
+Mon Apr  6 18:43:25 1998  Tim Janik  <timj@gtk.org>
+
+       * gscanner.c (g_scanner_get_token_ll): fixed a bug that caused floats
+       of the format ".xxx" to be parsed as "xxx".
+
+Fri Apr  3 20:36:35 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gutils.c (g_parse_debug_string): Make debug string
+       parsine case-insensitive
+
+Fri Apr  3 17:03:18 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * gstring.c: corrected possible overrun when inserting into
+       GStrings (thanks Elrond)
+
+Fri Apr  3 18:05:45 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * testglib.c: Removed literal german from strings
+       to appease SGI compiler.
+       
+Thu Mar 26 20:47:21 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * configure.in glib glibconfig.h.in: Add test for atexit/on_exit -
+       use on_exit if atexit not found in definition of ATEXIT.
+
+Wed Mar 25 15:23:37 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * Makefile.am: Switched glibconfig.h rule from HEADERS
+       to DATA, so that it is not added to DISTFILES
+
+Wed Mar 18 22:27:08 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * garray.c: g_rarray_truncate length done correctly
+
+Sun Mar 15 07:13:34 1998  Tim Janik  <timj@gimp.org>
+
+       * gutils.c: changed *_handler variables to be named glib_*_handler,
+       so you can easily access them from gdb.
+
+Sat Mar 14 17:47:43 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * Makefile.am: Don't refer to current directory as $(top_builddir)
+       to avoid confusing non-gmakes
+
+Sat Mar 14 01:37:35 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * Makefile.am (configincludedir): Moved glibconfig.h to
+          $(pkglibdir)/include
+
+Tue Mar 10 02:03:12 1998  Tim Janik  <timj@gimp.org>
+
+       * gscanner.c (g_scanner_destroy_symbol_table_entry): new function to
+       free symbol table entries upon destruction
+       (gtk-gronlund-980309-0.patch.gz).
+
+Mon Mar  9 15:02:21 1998  Tim Janik  <timj@gimp.org>
+
+       * glib.h: changed *_length functions to return guint.
+       changed *_nth functions to take guint as argument.
+
+       * glist.c: adapted g_list_length and g_list_length.
+
+       * gslist.c: adapted g_slist_length and g_slist_length.
+
+Mon Mar  2 17:51:18 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glib.h gutils.c : changed g_strcasecmp
+         to take gchar* not guchar*
+
+       * testglib.c: Remove trailing ; after functions
+       
+Sun Mar  1 19:04:40 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glib.h gstring.c: Added g_string_insert[_c]()
+         and g_string_erase().
+
+         From: Stefan Wille  <1wille@vsys1.informatik.uni-hamburg.de>
+
+Mon Feb 16 23:05:06 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glist.c (g_list_insert_sorted): Changed function
+         so elements are always inserted, even if they compare
+         equal with another.
+
+Thu Feb 12 22:48:11 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gstring.c glib.h: removed deprecated g_string_equal
+         and g_string_hash.
+
+Tue Feb 10 13:04:36 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * configure.in: Add check to see if the C library's
+         iswalnum can actually be used. (Not true for
+         Linux libc-5.4.38)
+
+Sat Feb  7 11:48:09 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gstring.c gutils.c: added some additional consts in
+         appropriate places to remove a warning
+
+Sat Feb  7 11:15:54 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gutils.c: include <ctype.h> for tolower()
+
+Fri Jan 30 23:57:17 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * added and autoconfigured in a new utility function
+       g_strcasecmp
+
+Wed Jan 28 23:53:27 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * glist.c
+       * gslist.c
+       * testglib.c: the sort functions compared backwards. Fixed
+       * glib.h: list iterator macros now check for NULL pointers
+
+Tue Jan 27 09:46:57 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * gstring.c: g_string_prepend and g_string_prepend_c had
+       interchanged src and dest parameters for g_memmove. Fixed.
+
+Tue Jan 27 01:38:52 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * gslist.c: fixed a really, really lame error. g_slist_insert
+       didn't hook the data in! Reworked the routine to reflect the
+       functionality of g_list
+
+Wed Jan 21 01:13:25 1998  Tim Janik  <timj@psynet.net>
+
+       * Applied patch from (Raja R Harinath <harinath@cs.umn.edu>)
+         to add function g_snprintf.
+        * configure.in (AC_CHECK_FUNCS): Check for vsnprintf.
+        * glib.h: Add prototype for g_snprintf.
+        * glibconfig.h.in: Add HAVE_VSNPRINTF.
+        * gutils.c (g_snprintf): new function.
+
+Sat Jan 17 23:52:40 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gstring.{c,h} gscanner.c:
+          renamed g_string_equal => g_str_equal
+          renamed g_string_hash => g_str_hash
+         And const corrected. Old functions left in for now.
+       
+Fri Jan  9 20:03:46 1998  Tim Janik  <timj@psynet.net>
+
+       * gutils.c (g_strerror): changed message for EAGAIN from
+       "no more processes" to "try again" since EAGAIN is used with
+       functions else than fork().
+
+       * gscanner.c (g_scanner_get_token_ll): use strtol() instead of
+       strtoul() to avoid conflicts with solaris.
+
+       * merged the glib portions from Jan 2 to Jan 7 out of gtk+/ChangeLog
+       into this file.
+
+Wed Jan  7 02:14:30 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * glib.h:
+       * glist.c:
+       * gslist.c:
+       * testglib.c: Added g_[s]list_insert_sorted function
+       and appropriate tests in testglib
+
+Sat Jan  3 20:23:25 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glib.h: Changed guint32 -> guint for bitfields.
+       (Bitfields must be int or unsigned int?)
+
+Fri Jan  2 23:52 PST 1998 Jay Painter <jpaint@serv.net>
+
+       * glib_pre1.h: 
+       * glib_pre2.h: 
+       * glib.h: reverted glibconfig.h and glib.h files back to the
+       way they were before my ugly hack.
+
+       * gscanner.c: removed inlines from clist and gscanner
+
+Tue Dec 23 02:49:51 1997  Tim Janik  <timj@psynet.net>
+
+       * gscanner.c: new file for GScanner: Flexible lexical scanner for
+       general purpose.
+       * glib_pre2.h: added GScanner includes. added g_strconcat and g_strtod.
+       gutils.c (g_strconcat): new function for string concatenation of NULL
+       terminated parameter list.
+       (g_strtod): new function to perform best string to double conversion
+       with or without consideration of the current locale.
+
+Mon Dec 15 19:33:58 1997  Tim Janik  <timj@psynet.net>
+
+       * glist.c: minor optimizations:
+       (g_list_append): `if' optimized for common code path, commented out
+       unneccessary `assert', saved one variable assignment.
+       (g_list_prepend): saved two (conditioned) variable assignment.
+       (g_list_insert): saved one  (conditioned) variable assignment,
+       saved one variable assignment.
+       (g_list_remove): `if' optimized for common code path, saved two
+       variable assignments by using `g_list_free_1' (which is even
+       faster) instead of `g_list_free'.
+       (g_list_reverse): saved allocation of one variable, saved one
+       variable assignment.
+
+Wed Dec 10 23:27:20 1997  Tim Janik  <timj@psynet.net>
+
+       * glib_pre1.h: 
+       * glib_pre2.h: 
+       * glib.h: this file now gets concatenated by makeglib_h from
+       glib_pre1.h and glib_pre2.h to merge in glibconfig.h wich got
+       created by configure (done by Jay Painter).
+
+       * glib_pre2.h: the g_assert*() and g_return_*_fail() macros
+       are wrapped by G_STMT_START and G_STMT_END now, to avoid conflicts
+       when used within if (...) g_macro(); else ... conditionals.
+       
+Tue Dec 17 13:14:07 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * glib.h: Changed 'g_return_if_fail' and 'g_return_val_if_fail' to
+       not call 'g_string' but to simply stringify the
+       expression. Calling 'g_string' causes the expression to be
+       expanded which is undesired.
+
+Sun Dec  1 01:30:48 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * Started ChangeLog
diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12
new file mode 100644 (file)
index 0000000..4b21235
--- /dev/null
@@ -0,0 +1,443 @@
+Wed Jun 10 12:56:07 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * glib.h: renamed g_const_pointer => gconstpointer
+
+Tue Jun  9 17:47:33 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * glib.h: Remove #error - HP/UX.
+
+Sat May 23 19:00:01 1998  Owen Taylor  <otaylor@gtk.org>
+  [ Combination of:
+     gtk-rrh-980412-0.patch (Raja R Harinath <harinath@cs.umn.edu>)
+     gtk-jbuhler-980516-0 (Jeremy Buhler <jbuhler@cs.washington.edu>) ]
+       
+       * glib.h ghash.c gstring.c gdataset.c gutils.c:
+       - Added new typedef g_const_pointer; expunged all incorrect
+         uses of 'const gpointer'.
+       - Fixed up warnings that that created,
+       - Changed GHashFunc and GCompareFunc to take g_const_pointer
+         arguments. (Necessary, but will cause warnings in existing
+         code until fixed)
+       - Added other new const in harmless positions.
+
+Mon Jun  8 01:06:47 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h: added enum-helper macros for code generation.
+       added G_BREAKPOINT().
+
+Sat Jun  6 14:09:22 PDT 1998 Manish Singh <yosh@gimp.org>
+
+       * gmem.c: commented out MEM_PROFILE and MEM_CHECK, causing weird
+       problems
+
+Wed Jun  3 06:19:42 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h (g_chunk_new0): convenience macro, for allocating small chunks 
+       like g_chunk_new() with additional 0 initialization.
+
+Mon Jun  1 04:43:27 1998  Tim Janik  <timj@gtk.org>
+
+       * ghash.c (g_hash_table_insert): wrote a comment describing why
+       a hash node's key should not also get replaced when overriding
+       previous entries.
+
+Tue May 26 18:30:06 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h (g_string_sized_new): new function to controll the preallocated
+       size of a GString.
+
+       * glib.h (g_strreversed): new function to reverse a string.
+
+Mon May 18 22:14:39 1998  Owen Taylor  <otaylor@gtk.org>
+(Yasuhiro SHIRASAKI <joke@awa.tohoku.ac.jp> : gtk-joke-980517-0.patch)
+       
+       * gutils.c: Restored a missing prototype for g_vsprintf.
+
+Wed May 20 05:02:26 1998  Tim Janik  <timj@gtk.org>
+
+        * glib.h: conditionally define NULL, FALSE and TRUE.
+        (g_mem_chunk_create): new convenience macro as a short hand for
+        g_mem_chunk_new().
+        (g_chunk_free): new convenience macro to be consistent with g_chunk_new.
+
+Tue, 19 May 1998 09:00:02 +0200  Â§Paolo Molaro <lupus@debian.org>
+
+       * gcompletion.c: generic functions for com<TAB>pletion...
+
+Sun May 17 10:48:27 1998  Tim Janik  <timj@gtk.org>
+
+       * gscanner.c (g_scanner_unexp_token): provide usefull default
+       specifications for identifier_spec and symbol_spec.
+
+       * glib.h: new functions g_slist_nth_data and g_list_nth_data to return
+       the data of the nth element in the list.
+
+Fri May 15 22:31:49 1998  Tim Janik  <timj@gtk.org>
+
+       * gscanner.c (g_scanner_unexp_token): removed spurious va_end(args)
+       that for some reason didn't produce a compiler wrning on my machine
+       (is va_end undefined for i386?).
+
+Fri May 15 12:32:08 1998  rodo  <doulik@karlin.mff.cuni.cz>
+
+       * gscanner.c: replaced some snprintf with g_snprintf
+
+Fri May 15 00:56:59 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h: further support for gcc function attributes: G_GNUC_FORMAT,
+       G_GNUC_NORETURN and G_GNUC_CONST.
+
+       * gscanner.c (g_scanner_stat_mode): changed stat() to lstat().
+       (g_scanner_msg_handler): "\n" at end of line!
+       (g_scanner_foreach_symbol): new function to iterate over the symbol
+       table (GScanner does value-wrapping).
+
+Thu May 14 04:14:12 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h: typedef gint gboolean;
+       this is needed to provide portability with big-endian platforms (e.g.
+       try sizeof(bool) for c++ on big-endians - it's 4).
+       this is also needed to maintain some_union.d_gint==some_union.d_gboolean.
+       plus, gint to gboolean casts and vice versa need to be possible without
+       loss.
+
+Tue May 12 19:22:58 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * glib/glib.h: Added macros G[U]INT_TO_POINTER() and
+       GPOINTER_TO_[U]INT for storing small integers integers
+       inside pointers. 
+       
+       * glib/testglib.c: Print sizeof() results
+       as g_print("%ld", (glong)sizeof(foo)), to deal with
+       size_t being long on Alpha's.
+
+Tue May 12 16:54:15 1998  Owen Taylor  <otaylor@gtk.org>
+       (James A <jamesa@demon.net> : gtk-jamesa-980511-4.patch)
+       
+       * glib.h gstring.c gmessages.c: Added some missing
+       const to arguments.
+
+       * gutils.c (g_strsignal.c): Added missing return statements.
+
+Mon May 11 21:11:54 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * gutils.c gmessages.c: Moved g_error, g_warning, g_message and
+       g_print from gutils.c to new file gmessages.c, to avoid having to
+       include <unistd.h> in gutils.c which was causing problems for the
+       g_strsignal implementation on FreeBSD boxes.
+
+Mon May 11 09:53:43 1998  Tim Janik  <timj@gtk.org>
+
+       * configure.in: preserve automake CFLAGS.
+
+       * Makefile.am: fully rename the created library to libglib-1.1.la.
+       this means we need to change certain portions of the Makefile.am on
+       major/minor version bumps.
+
+       * ltmain.sh: the -release option is not required anymore.
+
+        * glib.h: provide G_GNUC_FUNCTION and G_GNUC_PRETTY_FUNCTION to
+       avoid conditionals. unconditionally define NULL, TRUE, FALSE, MAX,
+       MIN, ABS and CLAMP, these macros might be screwed from other headers.
+
+Mon May 11 01:44:10 1998  Tim Janik  <timj@gtk.org>
+
+       * gdataset.c: new file, gdatasets implement the object data
+       mechanism from GtkObject. a generic data pointer is associated with
+       a certain location and a key id.
+
+Sat May  9 20:08:12 1998  Owen Taylor  <otaylor@gtk.org>
+
+        * glib/gmem.c: Experimentally restore GMemChunk
+        to its primeval state - where mem areas are
+        freed incrementally instead of searching the tree
+        every time a mem area is completely empty. Also,
+        always keep one mem chunk around. (Reduced calls
+        to malloc() a lot, but doesn't really improve
+        performance significiantly)
+
+Thu May  7 08:17:28 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h (G_GNUC_PRINTF):
+       (G_GNUC_SCANF): macros to facilitate the printf/scanf format argument
+       checking of gcc.
+
+       * gstring.c: const corrections, string!=NULL checks at function entry.
+       (g_string_down): new function for tolower(3) conversion.
+       (g_string_up): new function for toupper(3) conversion.
+
+       * gutils.c: const corrections.
+       (g_strdown): g_string_down() counterpart.
+       (g_strup): g_string_up() counterpart.
+
+       * gscanner.c (g_scanner_unexp_token):
+       (g_scanner_error):
+       (g_scanner_warn): new functions to let a scanner put out warnings
+       or errors, especially to react on unexpected tokens.
+
+       * gslist.c:
+       (g_slist_index): find out about about the position of a
+       certain data pointer.
+       (g_slist_position): find out about about the position of a
+       certain node.
+
+       * glist.c:
+       (g_list_index): find out about about the position of a
+       certain data pointer.
+
+Thu May  7 05:14:19 1998  Tim Janik  <timj@gtk.org>
+
+       * ltmain.sh: added a new commandline flag -postfix similar to -release,
+       but will immediately change the library name.
+
+       * Makefile.am: specify -postfix and -version-info
+
+       * configure.in: version bump to 1.1.0. added GLIB_INTERFACE_AGE and
+       GLIB_BINARY_AGE. calculate LT_* variables for libtool.
+
+Fri May  1 16:36:08 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * gutils.c: (g_strcasecmp). Check for isupper before
+       taking tolower, and account for macroized tolower.
+
+       * gutils.c (g_error): Check for recursion.
+
+1998-04-27  Elliot Lee  <sopwith@cuc.ml.org>
+
+       * glist.c (g_list_position): New function to find the position of
+       a link in a list - should be the inverse of g_list_nth(), but
+       haven't tested it so poof.
+
+Thu Apr 30 21:41:30 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * gstring.c : Check arguments more carefully, 
+       (gtk-draco-980423-1.patch; ramsey@rhrk.uni-kl.de) 
+
+Tue Apr  7 19:36:48 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gutils.c (g_direct_compare): Removed, because that's what
+       a NULL comparison function means. And it wasn't 64 bit safe.
+
+Mon Apr  6 18:43:25 1998  Tim Janik  <timj@gtk.org>
+
+       * gscanner.c (g_scanner_get_token_ll): fixed a bug that caused floats
+       of the format ".xxx" to be parsed as "xxx".
+
+Fri Apr  3 20:36:35 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gutils.c (g_parse_debug_string): Make debug string
+       parsine case-insensitive
+
+Fri Apr  3 17:03:18 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * gstring.c: corrected possible overrun when inserting into
+       GStrings (thanks Elrond)
+
+Fri Apr  3 18:05:45 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * testglib.c: Removed literal german from strings
+       to appease SGI compiler.
+       
+Thu Mar 26 20:47:21 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * configure.in glib glibconfig.h.in: Add test for atexit/on_exit -
+       use on_exit if atexit not found in definition of ATEXIT.
+
+Wed Mar 25 15:23:37 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * Makefile.am: Switched glibconfig.h rule from HEADERS
+       to DATA, so that it is not added to DISTFILES
+
+Wed Mar 18 22:27:08 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * garray.c: g_rarray_truncate length done correctly
+
+Sun Mar 15 07:13:34 1998  Tim Janik  <timj@gimp.org>
+
+       * gutils.c: changed *_handler variables to be named glib_*_handler,
+       so you can easily access them from gdb.
+
+Sat Mar 14 17:47:43 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * Makefile.am: Don't refer to current directory as $(top_builddir)
+       to avoid confusing non-gmakes
+
+Sat Mar 14 01:37:35 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * Makefile.am (configincludedir): Moved glibconfig.h to
+          $(pkglibdir)/include
+
+Tue Mar 10 02:03:12 1998  Tim Janik  <timj@gimp.org>
+
+       * gscanner.c (g_scanner_destroy_symbol_table_entry): new function to
+       free symbol table entries upon destruction
+       (gtk-gronlund-980309-0.patch.gz).
+
+Mon Mar  9 15:02:21 1998  Tim Janik  <timj@gimp.org>
+
+       * glib.h: changed *_length functions to return guint.
+       changed *_nth functions to take guint as argument.
+
+       * glist.c: adapted g_list_length and g_list_length.
+
+       * gslist.c: adapted g_slist_length and g_slist_length.
+
+Mon Mar  2 17:51:18 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glib.h gutils.c : changed g_strcasecmp
+         to take gchar* not guchar*
+
+       * testglib.c: Remove trailing ; after functions
+       
+Sun Mar  1 19:04:40 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glib.h gstring.c: Added g_string_insert[_c]()
+         and g_string_erase().
+
+         From: Stefan Wille  <1wille@vsys1.informatik.uni-hamburg.de>
+
+Mon Feb 16 23:05:06 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glist.c (g_list_insert_sorted): Changed function
+         so elements are always inserted, even if they compare
+         equal with another.
+
+Thu Feb 12 22:48:11 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gstring.c glib.h: removed deprecated g_string_equal
+         and g_string_hash.
+
+Tue Feb 10 13:04:36 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * configure.in: Add check to see if the C library's
+         iswalnum can actually be used. (Not true for
+         Linux libc-5.4.38)
+
+Sat Feb  7 11:48:09 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gstring.c gutils.c: added some additional consts in
+         appropriate places to remove a warning
+
+Sat Feb  7 11:15:54 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gutils.c: include <ctype.h> for tolower()
+
+Fri Jan 30 23:57:17 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * added and autoconfigured in a new utility function
+       g_strcasecmp
+
+Wed Jan 28 23:53:27 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * glist.c
+       * gslist.c
+       * testglib.c: the sort functions compared backwards. Fixed
+       * glib.h: list iterator macros now check for NULL pointers
+
+Tue Jan 27 09:46:57 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * gstring.c: g_string_prepend and g_string_prepend_c had
+       interchanged src and dest parameters for g_memmove. Fixed.
+
+Tue Jan 27 01:38:52 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * gslist.c: fixed a really, really lame error. g_slist_insert
+       didn't hook the data in! Reworked the routine to reflect the
+       functionality of g_list
+
+Wed Jan 21 01:13:25 1998  Tim Janik  <timj@psynet.net>
+
+       * Applied patch from (Raja R Harinath <harinath@cs.umn.edu>)
+         to add function g_snprintf.
+        * configure.in (AC_CHECK_FUNCS): Check for vsnprintf.
+        * glib.h: Add prototype for g_snprintf.
+        * glibconfig.h.in: Add HAVE_VSNPRINTF.
+        * gutils.c (g_snprintf): new function.
+
+Sat Jan 17 23:52:40 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gstring.{c,h} gscanner.c:
+          renamed g_string_equal => g_str_equal
+          renamed g_string_hash => g_str_hash
+         And const corrected. Old functions left in for now.
+       
+Fri Jan  9 20:03:46 1998  Tim Janik  <timj@psynet.net>
+
+       * gutils.c (g_strerror): changed message for EAGAIN from
+       "no more processes" to "try again" since EAGAIN is used with
+       functions else than fork().
+
+       * gscanner.c (g_scanner_get_token_ll): use strtol() instead of
+       strtoul() to avoid conflicts with solaris.
+
+       * merged the glib portions from Jan 2 to Jan 7 out of gtk+/ChangeLog
+       into this file.
+
+Wed Jan  7 02:14:30 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * glib.h:
+       * glist.c:
+       * gslist.c:
+       * testglib.c: Added g_[s]list_insert_sorted function
+       and appropriate tests in testglib
+
+Sat Jan  3 20:23:25 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glib.h: Changed guint32 -> guint for bitfields.
+       (Bitfields must be int or unsigned int?)
+
+Fri Jan  2 23:52 PST 1998 Jay Painter <jpaint@serv.net>
+
+       * glib_pre1.h: 
+       * glib_pre2.h: 
+       * glib.h: reverted glibconfig.h and glib.h files back to the
+       way they were before my ugly hack.
+
+       * gscanner.c: removed inlines from clist and gscanner
+
+Tue Dec 23 02:49:51 1997  Tim Janik  <timj@psynet.net>
+
+       * gscanner.c: new file for GScanner: Flexible lexical scanner for
+       general purpose.
+       * glib_pre2.h: added GScanner includes. added g_strconcat and g_strtod.
+       gutils.c (g_strconcat): new function for string concatenation of NULL
+       terminated parameter list.
+       (g_strtod): new function to perform best string to double conversion
+       with or without consideration of the current locale.
+
+Mon Dec 15 19:33:58 1997  Tim Janik  <timj@psynet.net>
+
+       * glist.c: minor optimizations:
+       (g_list_append): `if' optimized for common code path, commented out
+       unneccessary `assert', saved one variable assignment.
+       (g_list_prepend): saved two (conditioned) variable assignment.
+       (g_list_insert): saved one  (conditioned) variable assignment,
+       saved one variable assignment.
+       (g_list_remove): `if' optimized for common code path, saved two
+       variable assignments by using `g_list_free_1' (which is even
+       faster) instead of `g_list_free'.
+       (g_list_reverse): saved allocation of one variable, saved one
+       variable assignment.
+
+Wed Dec 10 23:27:20 1997  Tim Janik  <timj@psynet.net>
+
+       * glib_pre1.h: 
+       * glib_pre2.h: 
+       * glib.h: this file now gets concatenated by makeglib_h from
+       glib_pre1.h and glib_pre2.h to merge in glibconfig.h wich got
+       created by configure (done by Jay Painter).
+
+       * glib_pre2.h: the g_assert*() and g_return_*_fail() macros
+       are wrapped by G_STMT_START and G_STMT_END now, to avoid conflicts
+       when used within if (...) g_macro(); else ... conditionals.
+       
+Tue Dec 17 13:14:07 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * glib.h: Changed 'g_return_if_fail' and 'g_return_val_if_fail' to
+       not call 'g_string' but to simply stringify the
+       expression. Calling 'g_string' causes the expression to be
+       expanded which is undesired.
+
+Sun Dec  1 01:30:48 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * Started ChangeLog
diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2
new file mode 100644 (file)
index 0000000..4b21235
--- /dev/null
@@ -0,0 +1,443 @@
+Wed Jun 10 12:56:07 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * glib.h: renamed g_const_pointer => gconstpointer
+
+Tue Jun  9 17:47:33 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * glib.h: Remove #error - HP/UX.
+
+Sat May 23 19:00:01 1998  Owen Taylor  <otaylor@gtk.org>
+  [ Combination of:
+     gtk-rrh-980412-0.patch (Raja R Harinath <harinath@cs.umn.edu>)
+     gtk-jbuhler-980516-0 (Jeremy Buhler <jbuhler@cs.washington.edu>) ]
+       
+       * glib.h ghash.c gstring.c gdataset.c gutils.c:
+       - Added new typedef g_const_pointer; expunged all incorrect
+         uses of 'const gpointer'.
+       - Fixed up warnings that that created,
+       - Changed GHashFunc and GCompareFunc to take g_const_pointer
+         arguments. (Necessary, but will cause warnings in existing
+         code until fixed)
+       - Added other new const in harmless positions.
+
+Mon Jun  8 01:06:47 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h: added enum-helper macros for code generation.
+       added G_BREAKPOINT().
+
+Sat Jun  6 14:09:22 PDT 1998 Manish Singh <yosh@gimp.org>
+
+       * gmem.c: commented out MEM_PROFILE and MEM_CHECK, causing weird
+       problems
+
+Wed Jun  3 06:19:42 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h (g_chunk_new0): convenience macro, for allocating small chunks 
+       like g_chunk_new() with additional 0 initialization.
+
+Mon Jun  1 04:43:27 1998  Tim Janik  <timj@gtk.org>
+
+       * ghash.c (g_hash_table_insert): wrote a comment describing why
+       a hash node's key should not also get replaced when overriding
+       previous entries.
+
+Tue May 26 18:30:06 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h (g_string_sized_new): new function to controll the preallocated
+       size of a GString.
+
+       * glib.h (g_strreversed): new function to reverse a string.
+
+Mon May 18 22:14:39 1998  Owen Taylor  <otaylor@gtk.org>
+(Yasuhiro SHIRASAKI <joke@awa.tohoku.ac.jp> : gtk-joke-980517-0.patch)
+       
+       * gutils.c: Restored a missing prototype for g_vsprintf.
+
+Wed May 20 05:02:26 1998  Tim Janik  <timj@gtk.org>
+
+        * glib.h: conditionally define NULL, FALSE and TRUE.
+        (g_mem_chunk_create): new convenience macro as a short hand for
+        g_mem_chunk_new().
+        (g_chunk_free): new convenience macro to be consistent with g_chunk_new.
+
+Tue, 19 May 1998 09:00:02 +0200  Â§Paolo Molaro <lupus@debian.org>
+
+       * gcompletion.c: generic functions for com<TAB>pletion...
+
+Sun May 17 10:48:27 1998  Tim Janik  <timj@gtk.org>
+
+       * gscanner.c (g_scanner_unexp_token): provide usefull default
+       specifications for identifier_spec and symbol_spec.
+
+       * glib.h: new functions g_slist_nth_data and g_list_nth_data to return
+       the data of the nth element in the list.
+
+Fri May 15 22:31:49 1998  Tim Janik  <timj@gtk.org>
+
+       * gscanner.c (g_scanner_unexp_token): removed spurious va_end(args)
+       that for some reason didn't produce a compiler wrning on my machine
+       (is va_end undefined for i386?).
+
+Fri May 15 12:32:08 1998  rodo  <doulik@karlin.mff.cuni.cz>
+
+       * gscanner.c: replaced some snprintf with g_snprintf
+
+Fri May 15 00:56:59 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h: further support for gcc function attributes: G_GNUC_FORMAT,
+       G_GNUC_NORETURN and G_GNUC_CONST.
+
+       * gscanner.c (g_scanner_stat_mode): changed stat() to lstat().
+       (g_scanner_msg_handler): "\n" at end of line!
+       (g_scanner_foreach_symbol): new function to iterate over the symbol
+       table (GScanner does value-wrapping).
+
+Thu May 14 04:14:12 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h: typedef gint gboolean;
+       this is needed to provide portability with big-endian platforms (e.g.
+       try sizeof(bool) for c++ on big-endians - it's 4).
+       this is also needed to maintain some_union.d_gint==some_union.d_gboolean.
+       plus, gint to gboolean casts and vice versa need to be possible without
+       loss.
+
+Tue May 12 19:22:58 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * glib/glib.h: Added macros G[U]INT_TO_POINTER() and
+       GPOINTER_TO_[U]INT for storing small integers integers
+       inside pointers. 
+       
+       * glib/testglib.c: Print sizeof() results
+       as g_print("%ld", (glong)sizeof(foo)), to deal with
+       size_t being long on Alpha's.
+
+Tue May 12 16:54:15 1998  Owen Taylor  <otaylor@gtk.org>
+       (James A <jamesa@demon.net> : gtk-jamesa-980511-4.patch)
+       
+       * glib.h gstring.c gmessages.c: Added some missing
+       const to arguments.
+
+       * gutils.c (g_strsignal.c): Added missing return statements.
+
+Mon May 11 21:11:54 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * gutils.c gmessages.c: Moved g_error, g_warning, g_message and
+       g_print from gutils.c to new file gmessages.c, to avoid having to
+       include <unistd.h> in gutils.c which was causing problems for the
+       g_strsignal implementation on FreeBSD boxes.
+
+Mon May 11 09:53:43 1998  Tim Janik  <timj@gtk.org>
+
+       * configure.in: preserve automake CFLAGS.
+
+       * Makefile.am: fully rename the created library to libglib-1.1.la.
+       this means we need to change certain portions of the Makefile.am on
+       major/minor version bumps.
+
+       * ltmain.sh: the -release option is not required anymore.
+
+        * glib.h: provide G_GNUC_FUNCTION and G_GNUC_PRETTY_FUNCTION to
+       avoid conditionals. unconditionally define NULL, TRUE, FALSE, MAX,
+       MIN, ABS and CLAMP, these macros might be screwed from other headers.
+
+Mon May 11 01:44:10 1998  Tim Janik  <timj@gtk.org>
+
+       * gdataset.c: new file, gdatasets implement the object data
+       mechanism from GtkObject. a generic data pointer is associated with
+       a certain location and a key id.
+
+Sat May  9 20:08:12 1998  Owen Taylor  <otaylor@gtk.org>
+
+        * glib/gmem.c: Experimentally restore GMemChunk
+        to its primeval state - where mem areas are
+        freed incrementally instead of searching the tree
+        every time a mem area is completely empty. Also,
+        always keep one mem chunk around. (Reduced calls
+        to malloc() a lot, but doesn't really improve
+        performance significiantly)
+
+Thu May  7 08:17:28 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h (G_GNUC_PRINTF):
+       (G_GNUC_SCANF): macros to facilitate the printf/scanf format argument
+       checking of gcc.
+
+       * gstring.c: const corrections, string!=NULL checks at function entry.
+       (g_string_down): new function for tolower(3) conversion.
+       (g_string_up): new function for toupper(3) conversion.
+
+       * gutils.c: const corrections.
+       (g_strdown): g_string_down() counterpart.
+       (g_strup): g_string_up() counterpart.
+
+       * gscanner.c (g_scanner_unexp_token):
+       (g_scanner_error):
+       (g_scanner_warn): new functions to let a scanner put out warnings
+       or errors, especially to react on unexpected tokens.
+
+       * gslist.c:
+       (g_slist_index): find out about about the position of a
+       certain data pointer.
+       (g_slist_position): find out about about the position of a
+       certain node.
+
+       * glist.c:
+       (g_list_index): find out about about the position of a
+       certain data pointer.
+
+Thu May  7 05:14:19 1998  Tim Janik  <timj@gtk.org>
+
+       * ltmain.sh: added a new commandline flag -postfix similar to -release,
+       but will immediately change the library name.
+
+       * Makefile.am: specify -postfix and -version-info
+
+       * configure.in: version bump to 1.1.0. added GLIB_INTERFACE_AGE and
+       GLIB_BINARY_AGE. calculate LT_* variables for libtool.
+
+Fri May  1 16:36:08 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * gutils.c: (g_strcasecmp). Check for isupper before
+       taking tolower, and account for macroized tolower.
+
+       * gutils.c (g_error): Check for recursion.
+
+1998-04-27  Elliot Lee  <sopwith@cuc.ml.org>
+
+       * glist.c (g_list_position): New function to find the position of
+       a link in a list - should be the inverse of g_list_nth(), but
+       haven't tested it so poof.
+
+Thu Apr 30 21:41:30 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * gstring.c : Check arguments more carefully, 
+       (gtk-draco-980423-1.patch; ramsey@rhrk.uni-kl.de) 
+
+Tue Apr  7 19:36:48 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gutils.c (g_direct_compare): Removed, because that's what
+       a NULL comparison function means. And it wasn't 64 bit safe.
+
+Mon Apr  6 18:43:25 1998  Tim Janik  <timj@gtk.org>
+
+       * gscanner.c (g_scanner_get_token_ll): fixed a bug that caused floats
+       of the format ".xxx" to be parsed as "xxx".
+
+Fri Apr  3 20:36:35 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gutils.c (g_parse_debug_string): Make debug string
+       parsine case-insensitive
+
+Fri Apr  3 17:03:18 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * gstring.c: corrected possible overrun when inserting into
+       GStrings (thanks Elrond)
+
+Fri Apr  3 18:05:45 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * testglib.c: Removed literal german from strings
+       to appease SGI compiler.
+       
+Thu Mar 26 20:47:21 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * configure.in glib glibconfig.h.in: Add test for atexit/on_exit -
+       use on_exit if atexit not found in definition of ATEXIT.
+
+Wed Mar 25 15:23:37 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * Makefile.am: Switched glibconfig.h rule from HEADERS
+       to DATA, so that it is not added to DISTFILES
+
+Wed Mar 18 22:27:08 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * garray.c: g_rarray_truncate length done correctly
+
+Sun Mar 15 07:13:34 1998  Tim Janik  <timj@gimp.org>
+
+       * gutils.c: changed *_handler variables to be named glib_*_handler,
+       so you can easily access them from gdb.
+
+Sat Mar 14 17:47:43 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * Makefile.am: Don't refer to current directory as $(top_builddir)
+       to avoid confusing non-gmakes
+
+Sat Mar 14 01:37:35 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * Makefile.am (configincludedir): Moved glibconfig.h to
+          $(pkglibdir)/include
+
+Tue Mar 10 02:03:12 1998  Tim Janik  <timj@gimp.org>
+
+       * gscanner.c (g_scanner_destroy_symbol_table_entry): new function to
+       free symbol table entries upon destruction
+       (gtk-gronlund-980309-0.patch.gz).
+
+Mon Mar  9 15:02:21 1998  Tim Janik  <timj@gimp.org>
+
+       * glib.h: changed *_length functions to return guint.
+       changed *_nth functions to take guint as argument.
+
+       * glist.c: adapted g_list_length and g_list_length.
+
+       * gslist.c: adapted g_slist_length and g_slist_length.
+
+Mon Mar  2 17:51:18 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glib.h gutils.c : changed g_strcasecmp
+         to take gchar* not guchar*
+
+       * testglib.c: Remove trailing ; after functions
+       
+Sun Mar  1 19:04:40 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glib.h gstring.c: Added g_string_insert[_c]()
+         and g_string_erase().
+
+         From: Stefan Wille  <1wille@vsys1.informatik.uni-hamburg.de>
+
+Mon Feb 16 23:05:06 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glist.c (g_list_insert_sorted): Changed function
+         so elements are always inserted, even if they compare
+         equal with another.
+
+Thu Feb 12 22:48:11 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gstring.c glib.h: removed deprecated g_string_equal
+         and g_string_hash.
+
+Tue Feb 10 13:04:36 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * configure.in: Add check to see if the C library's
+         iswalnum can actually be used. (Not true for
+         Linux libc-5.4.38)
+
+Sat Feb  7 11:48:09 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gstring.c gutils.c: added some additional consts in
+         appropriate places to remove a warning
+
+Sat Feb  7 11:15:54 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gutils.c: include <ctype.h> for tolower()
+
+Fri Jan 30 23:57:17 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * added and autoconfigured in a new utility function
+       g_strcasecmp
+
+Wed Jan 28 23:53:27 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * glist.c
+       * gslist.c
+       * testglib.c: the sort functions compared backwards. Fixed
+       * glib.h: list iterator macros now check for NULL pointers
+
+Tue Jan 27 09:46:57 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * gstring.c: g_string_prepend and g_string_prepend_c had
+       interchanged src and dest parameters for g_memmove. Fixed.
+
+Tue Jan 27 01:38:52 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * gslist.c: fixed a really, really lame error. g_slist_insert
+       didn't hook the data in! Reworked the routine to reflect the
+       functionality of g_list
+
+Wed Jan 21 01:13:25 1998  Tim Janik  <timj@psynet.net>
+
+       * Applied patch from (Raja R Harinath <harinath@cs.umn.edu>)
+         to add function g_snprintf.
+        * configure.in (AC_CHECK_FUNCS): Check for vsnprintf.
+        * glib.h: Add prototype for g_snprintf.
+        * glibconfig.h.in: Add HAVE_VSNPRINTF.
+        * gutils.c (g_snprintf): new function.
+
+Sat Jan 17 23:52:40 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gstring.{c,h} gscanner.c:
+          renamed g_string_equal => g_str_equal
+          renamed g_string_hash => g_str_hash
+         And const corrected. Old functions left in for now.
+       
+Fri Jan  9 20:03:46 1998  Tim Janik  <timj@psynet.net>
+
+       * gutils.c (g_strerror): changed message for EAGAIN from
+       "no more processes" to "try again" since EAGAIN is used with
+       functions else than fork().
+
+       * gscanner.c (g_scanner_get_token_ll): use strtol() instead of
+       strtoul() to avoid conflicts with solaris.
+
+       * merged the glib portions from Jan 2 to Jan 7 out of gtk+/ChangeLog
+       into this file.
+
+Wed Jan  7 02:14:30 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * glib.h:
+       * glist.c:
+       * gslist.c:
+       * testglib.c: Added g_[s]list_insert_sorted function
+       and appropriate tests in testglib
+
+Sat Jan  3 20:23:25 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glib.h: Changed guint32 -> guint for bitfields.
+       (Bitfields must be int or unsigned int?)
+
+Fri Jan  2 23:52 PST 1998 Jay Painter <jpaint@serv.net>
+
+       * glib_pre1.h: 
+       * glib_pre2.h: 
+       * glib.h: reverted glibconfig.h and glib.h files back to the
+       way they were before my ugly hack.
+
+       * gscanner.c: removed inlines from clist and gscanner
+
+Tue Dec 23 02:49:51 1997  Tim Janik  <timj@psynet.net>
+
+       * gscanner.c: new file for GScanner: Flexible lexical scanner for
+       general purpose.
+       * glib_pre2.h: added GScanner includes. added g_strconcat and g_strtod.
+       gutils.c (g_strconcat): new function for string concatenation of NULL
+       terminated parameter list.
+       (g_strtod): new function to perform best string to double conversion
+       with or without consideration of the current locale.
+
+Mon Dec 15 19:33:58 1997  Tim Janik  <timj@psynet.net>
+
+       * glist.c: minor optimizations:
+       (g_list_append): `if' optimized for common code path, commented out
+       unneccessary `assert', saved one variable assignment.
+       (g_list_prepend): saved two (conditioned) variable assignment.
+       (g_list_insert): saved one  (conditioned) variable assignment,
+       saved one variable assignment.
+       (g_list_remove): `if' optimized for common code path, saved two
+       variable assignments by using `g_list_free_1' (which is even
+       faster) instead of `g_list_free'.
+       (g_list_reverse): saved allocation of one variable, saved one
+       variable assignment.
+
+Wed Dec 10 23:27:20 1997  Tim Janik  <timj@psynet.net>
+
+       * glib_pre1.h: 
+       * glib_pre2.h: 
+       * glib.h: this file now gets concatenated by makeglib_h from
+       glib_pre1.h and glib_pre2.h to merge in glibconfig.h wich got
+       created by configure (done by Jay Painter).
+
+       * glib_pre2.h: the g_assert*() and g_return_*_fail() macros
+       are wrapped by G_STMT_START and G_STMT_END now, to avoid conflicts
+       when used within if (...) g_macro(); else ... conditionals.
+       
+Tue Dec 17 13:14:07 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * glib.h: Changed 'g_return_if_fail' and 'g_return_val_if_fail' to
+       not call 'g_string' but to simply stringify the
+       expression. Calling 'g_string' causes the expression to be
+       expanded which is undesired.
+
+Sun Dec  1 01:30:48 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * Started ChangeLog
diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4
new file mode 100644 (file)
index 0000000..4b21235
--- /dev/null
@@ -0,0 +1,443 @@
+Wed Jun 10 12:56:07 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * glib.h: renamed g_const_pointer => gconstpointer
+
+Tue Jun  9 17:47:33 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * glib.h: Remove #error - HP/UX.
+
+Sat May 23 19:00:01 1998  Owen Taylor  <otaylor@gtk.org>
+  [ Combination of:
+     gtk-rrh-980412-0.patch (Raja R Harinath <harinath@cs.umn.edu>)
+     gtk-jbuhler-980516-0 (Jeremy Buhler <jbuhler@cs.washington.edu>) ]
+       
+       * glib.h ghash.c gstring.c gdataset.c gutils.c:
+       - Added new typedef g_const_pointer; expunged all incorrect
+         uses of 'const gpointer'.
+       - Fixed up warnings that that created,
+       - Changed GHashFunc and GCompareFunc to take g_const_pointer
+         arguments. (Necessary, but will cause warnings in existing
+         code until fixed)
+       - Added other new const in harmless positions.
+
+Mon Jun  8 01:06:47 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h: added enum-helper macros for code generation.
+       added G_BREAKPOINT().
+
+Sat Jun  6 14:09:22 PDT 1998 Manish Singh <yosh@gimp.org>
+
+       * gmem.c: commented out MEM_PROFILE and MEM_CHECK, causing weird
+       problems
+
+Wed Jun  3 06:19:42 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h (g_chunk_new0): convenience macro, for allocating small chunks 
+       like g_chunk_new() with additional 0 initialization.
+
+Mon Jun  1 04:43:27 1998  Tim Janik  <timj@gtk.org>
+
+       * ghash.c (g_hash_table_insert): wrote a comment describing why
+       a hash node's key should not also get replaced when overriding
+       previous entries.
+
+Tue May 26 18:30:06 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h (g_string_sized_new): new function to controll the preallocated
+       size of a GString.
+
+       * glib.h (g_strreversed): new function to reverse a string.
+
+Mon May 18 22:14:39 1998  Owen Taylor  <otaylor@gtk.org>
+(Yasuhiro SHIRASAKI <joke@awa.tohoku.ac.jp> : gtk-joke-980517-0.patch)
+       
+       * gutils.c: Restored a missing prototype for g_vsprintf.
+
+Wed May 20 05:02:26 1998  Tim Janik  <timj@gtk.org>
+
+        * glib.h: conditionally define NULL, FALSE and TRUE.
+        (g_mem_chunk_create): new convenience macro as a short hand for
+        g_mem_chunk_new().
+        (g_chunk_free): new convenience macro to be consistent with g_chunk_new.
+
+Tue, 19 May 1998 09:00:02 +0200  Â§Paolo Molaro <lupus@debian.org>
+
+       * gcompletion.c: generic functions for com<TAB>pletion...
+
+Sun May 17 10:48:27 1998  Tim Janik  <timj@gtk.org>
+
+       * gscanner.c (g_scanner_unexp_token): provide usefull default
+       specifications for identifier_spec and symbol_spec.
+
+       * glib.h: new functions g_slist_nth_data and g_list_nth_data to return
+       the data of the nth element in the list.
+
+Fri May 15 22:31:49 1998  Tim Janik  <timj@gtk.org>
+
+       * gscanner.c (g_scanner_unexp_token): removed spurious va_end(args)
+       that for some reason didn't produce a compiler wrning on my machine
+       (is va_end undefined for i386?).
+
+Fri May 15 12:32:08 1998  rodo  <doulik@karlin.mff.cuni.cz>
+
+       * gscanner.c: replaced some snprintf with g_snprintf
+
+Fri May 15 00:56:59 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h: further support for gcc function attributes: G_GNUC_FORMAT,
+       G_GNUC_NORETURN and G_GNUC_CONST.
+
+       * gscanner.c (g_scanner_stat_mode): changed stat() to lstat().
+       (g_scanner_msg_handler): "\n" at end of line!
+       (g_scanner_foreach_symbol): new function to iterate over the symbol
+       table (GScanner does value-wrapping).
+
+Thu May 14 04:14:12 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h: typedef gint gboolean;
+       this is needed to provide portability with big-endian platforms (e.g.
+       try sizeof(bool) for c++ on big-endians - it's 4).
+       this is also needed to maintain some_union.d_gint==some_union.d_gboolean.
+       plus, gint to gboolean casts and vice versa need to be possible without
+       loss.
+
+Tue May 12 19:22:58 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * glib/glib.h: Added macros G[U]INT_TO_POINTER() and
+       GPOINTER_TO_[U]INT for storing small integers integers
+       inside pointers. 
+       
+       * glib/testglib.c: Print sizeof() results
+       as g_print("%ld", (glong)sizeof(foo)), to deal with
+       size_t being long on Alpha's.
+
+Tue May 12 16:54:15 1998  Owen Taylor  <otaylor@gtk.org>
+       (James A <jamesa@demon.net> : gtk-jamesa-980511-4.patch)
+       
+       * glib.h gstring.c gmessages.c: Added some missing
+       const to arguments.
+
+       * gutils.c (g_strsignal.c): Added missing return statements.
+
+Mon May 11 21:11:54 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * gutils.c gmessages.c: Moved g_error, g_warning, g_message and
+       g_print from gutils.c to new file gmessages.c, to avoid having to
+       include <unistd.h> in gutils.c which was causing problems for the
+       g_strsignal implementation on FreeBSD boxes.
+
+Mon May 11 09:53:43 1998  Tim Janik  <timj@gtk.org>
+
+       * configure.in: preserve automake CFLAGS.
+
+       * Makefile.am: fully rename the created library to libglib-1.1.la.
+       this means we need to change certain portions of the Makefile.am on
+       major/minor version bumps.
+
+       * ltmain.sh: the -release option is not required anymore.
+
+        * glib.h: provide G_GNUC_FUNCTION and G_GNUC_PRETTY_FUNCTION to
+       avoid conditionals. unconditionally define NULL, TRUE, FALSE, MAX,
+       MIN, ABS and CLAMP, these macros might be screwed from other headers.
+
+Mon May 11 01:44:10 1998  Tim Janik  <timj@gtk.org>
+
+       * gdataset.c: new file, gdatasets implement the object data
+       mechanism from GtkObject. a generic data pointer is associated with
+       a certain location and a key id.
+
+Sat May  9 20:08:12 1998  Owen Taylor  <otaylor@gtk.org>
+
+        * glib/gmem.c: Experimentally restore GMemChunk
+        to its primeval state - where mem areas are
+        freed incrementally instead of searching the tree
+        every time a mem area is completely empty. Also,
+        always keep one mem chunk around. (Reduced calls
+        to malloc() a lot, but doesn't really improve
+        performance significiantly)
+
+Thu May  7 08:17:28 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h (G_GNUC_PRINTF):
+       (G_GNUC_SCANF): macros to facilitate the printf/scanf format argument
+       checking of gcc.
+
+       * gstring.c: const corrections, string!=NULL checks at function entry.
+       (g_string_down): new function for tolower(3) conversion.
+       (g_string_up): new function for toupper(3) conversion.
+
+       * gutils.c: const corrections.
+       (g_strdown): g_string_down() counterpart.
+       (g_strup): g_string_up() counterpart.
+
+       * gscanner.c (g_scanner_unexp_token):
+       (g_scanner_error):
+       (g_scanner_warn): new functions to let a scanner put out warnings
+       or errors, especially to react on unexpected tokens.
+
+       * gslist.c:
+       (g_slist_index): find out about about the position of a
+       certain data pointer.
+       (g_slist_position): find out about about the position of a
+       certain node.
+
+       * glist.c:
+       (g_list_index): find out about about the position of a
+       certain data pointer.
+
+Thu May  7 05:14:19 1998  Tim Janik  <timj@gtk.org>
+
+       * ltmain.sh: added a new commandline flag -postfix similar to -release,
+       but will immediately change the library name.
+
+       * Makefile.am: specify -postfix and -version-info
+
+       * configure.in: version bump to 1.1.0. added GLIB_INTERFACE_AGE and
+       GLIB_BINARY_AGE. calculate LT_* variables for libtool.
+
+Fri May  1 16:36:08 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * gutils.c: (g_strcasecmp). Check for isupper before
+       taking tolower, and account for macroized tolower.
+
+       * gutils.c (g_error): Check for recursion.
+
+1998-04-27  Elliot Lee  <sopwith@cuc.ml.org>
+
+       * glist.c (g_list_position): New function to find the position of
+       a link in a list - should be the inverse of g_list_nth(), but
+       haven't tested it so poof.
+
+Thu Apr 30 21:41:30 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * gstring.c : Check arguments more carefully, 
+       (gtk-draco-980423-1.patch; ramsey@rhrk.uni-kl.de) 
+
+Tue Apr  7 19:36:48 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gutils.c (g_direct_compare): Removed, because that's what
+       a NULL comparison function means. And it wasn't 64 bit safe.
+
+Mon Apr  6 18:43:25 1998  Tim Janik  <timj@gtk.org>
+
+       * gscanner.c (g_scanner_get_token_ll): fixed a bug that caused floats
+       of the format ".xxx" to be parsed as "xxx".
+
+Fri Apr  3 20:36:35 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gutils.c (g_parse_debug_string): Make debug string
+       parsine case-insensitive
+
+Fri Apr  3 17:03:18 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * gstring.c: corrected possible overrun when inserting into
+       GStrings (thanks Elrond)
+
+Fri Apr  3 18:05:45 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * testglib.c: Removed literal german from strings
+       to appease SGI compiler.
+       
+Thu Mar 26 20:47:21 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * configure.in glib glibconfig.h.in: Add test for atexit/on_exit -
+       use on_exit if atexit not found in definition of ATEXIT.
+
+Wed Mar 25 15:23:37 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * Makefile.am: Switched glibconfig.h rule from HEADERS
+       to DATA, so that it is not added to DISTFILES
+
+Wed Mar 18 22:27:08 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * garray.c: g_rarray_truncate length done correctly
+
+Sun Mar 15 07:13:34 1998  Tim Janik  <timj@gimp.org>
+
+       * gutils.c: changed *_handler variables to be named glib_*_handler,
+       so you can easily access them from gdb.
+
+Sat Mar 14 17:47:43 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * Makefile.am: Don't refer to current directory as $(top_builddir)
+       to avoid confusing non-gmakes
+
+Sat Mar 14 01:37:35 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * Makefile.am (configincludedir): Moved glibconfig.h to
+          $(pkglibdir)/include
+
+Tue Mar 10 02:03:12 1998  Tim Janik  <timj@gimp.org>
+
+       * gscanner.c (g_scanner_destroy_symbol_table_entry): new function to
+       free symbol table entries upon destruction
+       (gtk-gronlund-980309-0.patch.gz).
+
+Mon Mar  9 15:02:21 1998  Tim Janik  <timj@gimp.org>
+
+       * glib.h: changed *_length functions to return guint.
+       changed *_nth functions to take guint as argument.
+
+       * glist.c: adapted g_list_length and g_list_length.
+
+       * gslist.c: adapted g_slist_length and g_slist_length.
+
+Mon Mar  2 17:51:18 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glib.h gutils.c : changed g_strcasecmp
+         to take gchar* not guchar*
+
+       * testglib.c: Remove trailing ; after functions
+       
+Sun Mar  1 19:04:40 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glib.h gstring.c: Added g_string_insert[_c]()
+         and g_string_erase().
+
+         From: Stefan Wille  <1wille@vsys1.informatik.uni-hamburg.de>
+
+Mon Feb 16 23:05:06 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glist.c (g_list_insert_sorted): Changed function
+         so elements are always inserted, even if they compare
+         equal with another.
+
+Thu Feb 12 22:48:11 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gstring.c glib.h: removed deprecated g_string_equal
+         and g_string_hash.
+
+Tue Feb 10 13:04:36 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * configure.in: Add check to see if the C library's
+         iswalnum can actually be used. (Not true for
+         Linux libc-5.4.38)
+
+Sat Feb  7 11:48:09 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gstring.c gutils.c: added some additional consts in
+         appropriate places to remove a warning
+
+Sat Feb  7 11:15:54 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gutils.c: include <ctype.h> for tolower()
+
+Fri Jan 30 23:57:17 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * added and autoconfigured in a new utility function
+       g_strcasecmp
+
+Wed Jan 28 23:53:27 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * glist.c
+       * gslist.c
+       * testglib.c: the sort functions compared backwards. Fixed
+       * glib.h: list iterator macros now check for NULL pointers
+
+Tue Jan 27 09:46:57 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * gstring.c: g_string_prepend and g_string_prepend_c had
+       interchanged src and dest parameters for g_memmove. Fixed.
+
+Tue Jan 27 01:38:52 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * gslist.c: fixed a really, really lame error. g_slist_insert
+       didn't hook the data in! Reworked the routine to reflect the
+       functionality of g_list
+
+Wed Jan 21 01:13:25 1998  Tim Janik  <timj@psynet.net>
+
+       * Applied patch from (Raja R Harinath <harinath@cs.umn.edu>)
+         to add function g_snprintf.
+        * configure.in (AC_CHECK_FUNCS): Check for vsnprintf.
+        * glib.h: Add prototype for g_snprintf.
+        * glibconfig.h.in: Add HAVE_VSNPRINTF.
+        * gutils.c (g_snprintf): new function.
+
+Sat Jan 17 23:52:40 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gstring.{c,h} gscanner.c:
+          renamed g_string_equal => g_str_equal
+          renamed g_string_hash => g_str_hash
+         And const corrected. Old functions left in for now.
+       
+Fri Jan  9 20:03:46 1998  Tim Janik  <timj@psynet.net>
+
+       * gutils.c (g_strerror): changed message for EAGAIN from
+       "no more processes" to "try again" since EAGAIN is used with
+       functions else than fork().
+
+       * gscanner.c (g_scanner_get_token_ll): use strtol() instead of
+       strtoul() to avoid conflicts with solaris.
+
+       * merged the glib portions from Jan 2 to Jan 7 out of gtk+/ChangeLog
+       into this file.
+
+Wed Jan  7 02:14:30 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * glib.h:
+       * glist.c:
+       * gslist.c:
+       * testglib.c: Added g_[s]list_insert_sorted function
+       and appropriate tests in testglib
+
+Sat Jan  3 20:23:25 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glib.h: Changed guint32 -> guint for bitfields.
+       (Bitfields must be int or unsigned int?)
+
+Fri Jan  2 23:52 PST 1998 Jay Painter <jpaint@serv.net>
+
+       * glib_pre1.h: 
+       * glib_pre2.h: 
+       * glib.h: reverted glibconfig.h and glib.h files back to the
+       way they were before my ugly hack.
+
+       * gscanner.c: removed inlines from clist and gscanner
+
+Tue Dec 23 02:49:51 1997  Tim Janik  <timj@psynet.net>
+
+       * gscanner.c: new file for GScanner: Flexible lexical scanner for
+       general purpose.
+       * glib_pre2.h: added GScanner includes. added g_strconcat and g_strtod.
+       gutils.c (g_strconcat): new function for string concatenation of NULL
+       terminated parameter list.
+       (g_strtod): new function to perform best string to double conversion
+       with or without consideration of the current locale.
+
+Mon Dec 15 19:33:58 1997  Tim Janik  <timj@psynet.net>
+
+       * glist.c: minor optimizations:
+       (g_list_append): `if' optimized for common code path, commented out
+       unneccessary `assert', saved one variable assignment.
+       (g_list_prepend): saved two (conditioned) variable assignment.
+       (g_list_insert): saved one  (conditioned) variable assignment,
+       saved one variable assignment.
+       (g_list_remove): `if' optimized for common code path, saved two
+       variable assignments by using `g_list_free_1' (which is even
+       faster) instead of `g_list_free'.
+       (g_list_reverse): saved allocation of one variable, saved one
+       variable assignment.
+
+Wed Dec 10 23:27:20 1997  Tim Janik  <timj@psynet.net>
+
+       * glib_pre1.h: 
+       * glib_pre2.h: 
+       * glib.h: this file now gets concatenated by makeglib_h from
+       glib_pre1.h and glib_pre2.h to merge in glibconfig.h wich got
+       created by configure (done by Jay Painter).
+
+       * glib_pre2.h: the g_assert*() and g_return_*_fail() macros
+       are wrapped by G_STMT_START and G_STMT_END now, to avoid conflicts
+       when used within if (...) g_macro(); else ... conditionals.
+       
+Tue Dec 17 13:14:07 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * glib.h: Changed 'g_return_if_fail' and 'g_return_val_if_fail' to
+       not call 'g_string' but to simply stringify the
+       expression. Calling 'g_string' causes the expression to be
+       expanded which is undesired.
+
+Sun Dec  1 01:30:48 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * Started ChangeLog
diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6
new file mode 100644 (file)
index 0000000..4b21235
--- /dev/null
@@ -0,0 +1,443 @@
+Wed Jun 10 12:56:07 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * glib.h: renamed g_const_pointer => gconstpointer
+
+Tue Jun  9 17:47:33 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * glib.h: Remove #error - HP/UX.
+
+Sat May 23 19:00:01 1998  Owen Taylor  <otaylor@gtk.org>
+  [ Combination of:
+     gtk-rrh-980412-0.patch (Raja R Harinath <harinath@cs.umn.edu>)
+     gtk-jbuhler-980516-0 (Jeremy Buhler <jbuhler@cs.washington.edu>) ]
+       
+       * glib.h ghash.c gstring.c gdataset.c gutils.c:
+       - Added new typedef g_const_pointer; expunged all incorrect
+         uses of 'const gpointer'.
+       - Fixed up warnings that that created,
+       - Changed GHashFunc and GCompareFunc to take g_const_pointer
+         arguments. (Necessary, but will cause warnings in existing
+         code until fixed)
+       - Added other new const in harmless positions.
+
+Mon Jun  8 01:06:47 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h: added enum-helper macros for code generation.
+       added G_BREAKPOINT().
+
+Sat Jun  6 14:09:22 PDT 1998 Manish Singh <yosh@gimp.org>
+
+       * gmem.c: commented out MEM_PROFILE and MEM_CHECK, causing weird
+       problems
+
+Wed Jun  3 06:19:42 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h (g_chunk_new0): convenience macro, for allocating small chunks 
+       like g_chunk_new() with additional 0 initialization.
+
+Mon Jun  1 04:43:27 1998  Tim Janik  <timj@gtk.org>
+
+       * ghash.c (g_hash_table_insert): wrote a comment describing why
+       a hash node's key should not also get replaced when overriding
+       previous entries.
+
+Tue May 26 18:30:06 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h (g_string_sized_new): new function to controll the preallocated
+       size of a GString.
+
+       * glib.h (g_strreversed): new function to reverse a string.
+
+Mon May 18 22:14:39 1998  Owen Taylor  <otaylor@gtk.org>
+(Yasuhiro SHIRASAKI <joke@awa.tohoku.ac.jp> : gtk-joke-980517-0.patch)
+       
+       * gutils.c: Restored a missing prototype for g_vsprintf.
+
+Wed May 20 05:02:26 1998  Tim Janik  <timj@gtk.org>
+
+        * glib.h: conditionally define NULL, FALSE and TRUE.
+        (g_mem_chunk_create): new convenience macro as a short hand for
+        g_mem_chunk_new().
+        (g_chunk_free): new convenience macro to be consistent with g_chunk_new.
+
+Tue, 19 May 1998 09:00:02 +0200  Â§Paolo Molaro <lupus@debian.org>
+
+       * gcompletion.c: generic functions for com<TAB>pletion...
+
+Sun May 17 10:48:27 1998  Tim Janik  <timj@gtk.org>
+
+       * gscanner.c (g_scanner_unexp_token): provide usefull default
+       specifications for identifier_spec and symbol_spec.
+
+       * glib.h: new functions g_slist_nth_data and g_list_nth_data to return
+       the data of the nth element in the list.
+
+Fri May 15 22:31:49 1998  Tim Janik  <timj@gtk.org>
+
+       * gscanner.c (g_scanner_unexp_token): removed spurious va_end(args)
+       that for some reason didn't produce a compiler wrning on my machine
+       (is va_end undefined for i386?).
+
+Fri May 15 12:32:08 1998  rodo  <doulik@karlin.mff.cuni.cz>
+
+       * gscanner.c: replaced some snprintf with g_snprintf
+
+Fri May 15 00:56:59 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h: further support for gcc function attributes: G_GNUC_FORMAT,
+       G_GNUC_NORETURN and G_GNUC_CONST.
+
+       * gscanner.c (g_scanner_stat_mode): changed stat() to lstat().
+       (g_scanner_msg_handler): "\n" at end of line!
+       (g_scanner_foreach_symbol): new function to iterate over the symbol
+       table (GScanner does value-wrapping).
+
+Thu May 14 04:14:12 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h: typedef gint gboolean;
+       this is needed to provide portability with big-endian platforms (e.g.
+       try sizeof(bool) for c++ on big-endians - it's 4).
+       this is also needed to maintain some_union.d_gint==some_union.d_gboolean.
+       plus, gint to gboolean casts and vice versa need to be possible without
+       loss.
+
+Tue May 12 19:22:58 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * glib/glib.h: Added macros G[U]INT_TO_POINTER() and
+       GPOINTER_TO_[U]INT for storing small integers integers
+       inside pointers. 
+       
+       * glib/testglib.c: Print sizeof() results
+       as g_print("%ld", (glong)sizeof(foo)), to deal with
+       size_t being long on Alpha's.
+
+Tue May 12 16:54:15 1998  Owen Taylor  <otaylor@gtk.org>
+       (James A <jamesa@demon.net> : gtk-jamesa-980511-4.patch)
+       
+       * glib.h gstring.c gmessages.c: Added some missing
+       const to arguments.
+
+       * gutils.c (g_strsignal.c): Added missing return statements.
+
+Mon May 11 21:11:54 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * gutils.c gmessages.c: Moved g_error, g_warning, g_message and
+       g_print from gutils.c to new file gmessages.c, to avoid having to
+       include <unistd.h> in gutils.c which was causing problems for the
+       g_strsignal implementation on FreeBSD boxes.
+
+Mon May 11 09:53:43 1998  Tim Janik  <timj@gtk.org>
+
+       * configure.in: preserve automake CFLAGS.
+
+       * Makefile.am: fully rename the created library to libglib-1.1.la.
+       this means we need to change certain portions of the Makefile.am on
+       major/minor version bumps.
+
+       * ltmain.sh: the -release option is not required anymore.
+
+        * glib.h: provide G_GNUC_FUNCTION and G_GNUC_PRETTY_FUNCTION to
+       avoid conditionals. unconditionally define NULL, TRUE, FALSE, MAX,
+       MIN, ABS and CLAMP, these macros might be screwed from other headers.
+
+Mon May 11 01:44:10 1998  Tim Janik  <timj@gtk.org>
+
+       * gdataset.c: new file, gdatasets implement the object data
+       mechanism from GtkObject. a generic data pointer is associated with
+       a certain location and a key id.
+
+Sat May  9 20:08:12 1998  Owen Taylor  <otaylor@gtk.org>
+
+        * glib/gmem.c: Experimentally restore GMemChunk
+        to its primeval state - where mem areas are
+        freed incrementally instead of searching the tree
+        every time a mem area is completely empty. Also,
+        always keep one mem chunk around. (Reduced calls
+        to malloc() a lot, but doesn't really improve
+        performance significiantly)
+
+Thu May  7 08:17:28 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h (G_GNUC_PRINTF):
+       (G_GNUC_SCANF): macros to facilitate the printf/scanf format argument
+       checking of gcc.
+
+       * gstring.c: const corrections, string!=NULL checks at function entry.
+       (g_string_down): new function for tolower(3) conversion.
+       (g_string_up): new function for toupper(3) conversion.
+
+       * gutils.c: const corrections.
+       (g_strdown): g_string_down() counterpart.
+       (g_strup): g_string_up() counterpart.
+
+       * gscanner.c (g_scanner_unexp_token):
+       (g_scanner_error):
+       (g_scanner_warn): new functions to let a scanner put out warnings
+       or errors, especially to react on unexpected tokens.
+
+       * gslist.c:
+       (g_slist_index): find out about about the position of a
+       certain data pointer.
+       (g_slist_position): find out about about the position of a
+       certain node.
+
+       * glist.c:
+       (g_list_index): find out about about the position of a
+       certain data pointer.
+
+Thu May  7 05:14:19 1998  Tim Janik  <timj@gtk.org>
+
+       * ltmain.sh: added a new commandline flag -postfix similar to -release,
+       but will immediately change the library name.
+
+       * Makefile.am: specify -postfix and -version-info
+
+       * configure.in: version bump to 1.1.0. added GLIB_INTERFACE_AGE and
+       GLIB_BINARY_AGE. calculate LT_* variables for libtool.
+
+Fri May  1 16:36:08 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * gutils.c: (g_strcasecmp). Check for isupper before
+       taking tolower, and account for macroized tolower.
+
+       * gutils.c (g_error): Check for recursion.
+
+1998-04-27  Elliot Lee  <sopwith@cuc.ml.org>
+
+       * glist.c (g_list_position): New function to find the position of
+       a link in a list - should be the inverse of g_list_nth(), but
+       haven't tested it so poof.
+
+Thu Apr 30 21:41:30 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * gstring.c : Check arguments more carefully, 
+       (gtk-draco-980423-1.patch; ramsey@rhrk.uni-kl.de) 
+
+Tue Apr  7 19:36:48 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gutils.c (g_direct_compare): Removed, because that's what
+       a NULL comparison function means. And it wasn't 64 bit safe.
+
+Mon Apr  6 18:43:25 1998  Tim Janik  <timj@gtk.org>
+
+       * gscanner.c (g_scanner_get_token_ll): fixed a bug that caused floats
+       of the format ".xxx" to be parsed as "xxx".
+
+Fri Apr  3 20:36:35 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gutils.c (g_parse_debug_string): Make debug string
+       parsine case-insensitive
+
+Fri Apr  3 17:03:18 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * gstring.c: corrected possible overrun when inserting into
+       GStrings (thanks Elrond)
+
+Fri Apr  3 18:05:45 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * testglib.c: Removed literal german from strings
+       to appease SGI compiler.
+       
+Thu Mar 26 20:47:21 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * configure.in glib glibconfig.h.in: Add test for atexit/on_exit -
+       use on_exit if atexit not found in definition of ATEXIT.
+
+Wed Mar 25 15:23:37 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * Makefile.am: Switched glibconfig.h rule from HEADERS
+       to DATA, so that it is not added to DISTFILES
+
+Wed Mar 18 22:27:08 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * garray.c: g_rarray_truncate length done correctly
+
+Sun Mar 15 07:13:34 1998  Tim Janik  <timj@gimp.org>
+
+       * gutils.c: changed *_handler variables to be named glib_*_handler,
+       so you can easily access them from gdb.
+
+Sat Mar 14 17:47:43 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * Makefile.am: Don't refer to current directory as $(top_builddir)
+       to avoid confusing non-gmakes
+
+Sat Mar 14 01:37:35 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * Makefile.am (configincludedir): Moved glibconfig.h to
+          $(pkglibdir)/include
+
+Tue Mar 10 02:03:12 1998  Tim Janik  <timj@gimp.org>
+
+       * gscanner.c (g_scanner_destroy_symbol_table_entry): new function to
+       free symbol table entries upon destruction
+       (gtk-gronlund-980309-0.patch.gz).
+
+Mon Mar  9 15:02:21 1998  Tim Janik  <timj@gimp.org>
+
+       * glib.h: changed *_length functions to return guint.
+       changed *_nth functions to take guint as argument.
+
+       * glist.c: adapted g_list_length and g_list_length.
+
+       * gslist.c: adapted g_slist_length and g_slist_length.
+
+Mon Mar  2 17:51:18 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glib.h gutils.c : changed g_strcasecmp
+         to take gchar* not guchar*
+
+       * testglib.c: Remove trailing ; after functions
+       
+Sun Mar  1 19:04:40 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glib.h gstring.c: Added g_string_insert[_c]()
+         and g_string_erase().
+
+         From: Stefan Wille  <1wille@vsys1.informatik.uni-hamburg.de>
+
+Mon Feb 16 23:05:06 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glist.c (g_list_insert_sorted): Changed function
+         so elements are always inserted, even if they compare
+         equal with another.
+
+Thu Feb 12 22:48:11 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gstring.c glib.h: removed deprecated g_string_equal
+         and g_string_hash.
+
+Tue Feb 10 13:04:36 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * configure.in: Add check to see if the C library's
+         iswalnum can actually be used. (Not true for
+         Linux libc-5.4.38)
+
+Sat Feb  7 11:48:09 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gstring.c gutils.c: added some additional consts in
+         appropriate places to remove a warning
+
+Sat Feb  7 11:15:54 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gutils.c: include <ctype.h> for tolower()
+
+Fri Jan 30 23:57:17 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * added and autoconfigured in a new utility function
+       g_strcasecmp
+
+Wed Jan 28 23:53:27 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * glist.c
+       * gslist.c
+       * testglib.c: the sort functions compared backwards. Fixed
+       * glib.h: list iterator macros now check for NULL pointers
+
+Tue Jan 27 09:46:57 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * gstring.c: g_string_prepend and g_string_prepend_c had
+       interchanged src and dest parameters for g_memmove. Fixed.
+
+Tue Jan 27 01:38:52 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * gslist.c: fixed a really, really lame error. g_slist_insert
+       didn't hook the data in! Reworked the routine to reflect the
+       functionality of g_list
+
+Wed Jan 21 01:13:25 1998  Tim Janik  <timj@psynet.net>
+
+       * Applied patch from (Raja R Harinath <harinath@cs.umn.edu>)
+         to add function g_snprintf.
+        * configure.in (AC_CHECK_FUNCS): Check for vsnprintf.
+        * glib.h: Add prototype for g_snprintf.
+        * glibconfig.h.in: Add HAVE_VSNPRINTF.
+        * gutils.c (g_snprintf): new function.
+
+Sat Jan 17 23:52:40 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gstring.{c,h} gscanner.c:
+          renamed g_string_equal => g_str_equal
+          renamed g_string_hash => g_str_hash
+         And const corrected. Old functions left in for now.
+       
+Fri Jan  9 20:03:46 1998  Tim Janik  <timj@psynet.net>
+
+       * gutils.c (g_strerror): changed message for EAGAIN from
+       "no more processes" to "try again" since EAGAIN is used with
+       functions else than fork().
+
+       * gscanner.c (g_scanner_get_token_ll): use strtol() instead of
+       strtoul() to avoid conflicts with solaris.
+
+       * merged the glib portions from Jan 2 to Jan 7 out of gtk+/ChangeLog
+       into this file.
+
+Wed Jan  7 02:14:30 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * glib.h:
+       * glist.c:
+       * gslist.c:
+       * testglib.c: Added g_[s]list_insert_sorted function
+       and appropriate tests in testglib
+
+Sat Jan  3 20:23:25 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glib.h: Changed guint32 -> guint for bitfields.
+       (Bitfields must be int or unsigned int?)
+
+Fri Jan  2 23:52 PST 1998 Jay Painter <jpaint@serv.net>
+
+       * glib_pre1.h: 
+       * glib_pre2.h: 
+       * glib.h: reverted glibconfig.h and glib.h files back to the
+       way they were before my ugly hack.
+
+       * gscanner.c: removed inlines from clist and gscanner
+
+Tue Dec 23 02:49:51 1997  Tim Janik  <timj@psynet.net>
+
+       * gscanner.c: new file for GScanner: Flexible lexical scanner for
+       general purpose.
+       * glib_pre2.h: added GScanner includes. added g_strconcat and g_strtod.
+       gutils.c (g_strconcat): new function for string concatenation of NULL
+       terminated parameter list.
+       (g_strtod): new function to perform best string to double conversion
+       with or without consideration of the current locale.
+
+Mon Dec 15 19:33:58 1997  Tim Janik  <timj@psynet.net>
+
+       * glist.c: minor optimizations:
+       (g_list_append): `if' optimized for common code path, commented out
+       unneccessary `assert', saved one variable assignment.
+       (g_list_prepend): saved two (conditioned) variable assignment.
+       (g_list_insert): saved one  (conditioned) variable assignment,
+       saved one variable assignment.
+       (g_list_remove): `if' optimized for common code path, saved two
+       variable assignments by using `g_list_free_1' (which is even
+       faster) instead of `g_list_free'.
+       (g_list_reverse): saved allocation of one variable, saved one
+       variable assignment.
+
+Wed Dec 10 23:27:20 1997  Tim Janik  <timj@psynet.net>
+
+       * glib_pre1.h: 
+       * glib_pre2.h: 
+       * glib.h: this file now gets concatenated by makeglib_h from
+       glib_pre1.h and glib_pre2.h to merge in glibconfig.h wich got
+       created by configure (done by Jay Painter).
+
+       * glib_pre2.h: the g_assert*() and g_return_*_fail() macros
+       are wrapped by G_STMT_START and G_STMT_END now, to avoid conflicts
+       when used within if (...) g_macro(); else ... conditionals.
+       
+Tue Dec 17 13:14:07 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * glib.h: Changed 'g_return_if_fail' and 'g_return_val_if_fail' to
+       not call 'g_string' but to simply stringify the
+       expression. Calling 'g_string' causes the expression to be
+       expanded which is undesired.
+
+Sun Dec  1 01:30:48 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * Started ChangeLog
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
new file mode 100644 (file)
index 0000000..4b21235
--- /dev/null
@@ -0,0 +1,443 @@
+Wed Jun 10 12:56:07 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * glib.h: renamed g_const_pointer => gconstpointer
+
+Tue Jun  9 17:47:33 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * glib.h: Remove #error - HP/UX.
+
+Sat May 23 19:00:01 1998  Owen Taylor  <otaylor@gtk.org>
+  [ Combination of:
+     gtk-rrh-980412-0.patch (Raja R Harinath <harinath@cs.umn.edu>)
+     gtk-jbuhler-980516-0 (Jeremy Buhler <jbuhler@cs.washington.edu>) ]
+       
+       * glib.h ghash.c gstring.c gdataset.c gutils.c:
+       - Added new typedef g_const_pointer; expunged all incorrect
+         uses of 'const gpointer'.
+       - Fixed up warnings that that created,
+       - Changed GHashFunc and GCompareFunc to take g_const_pointer
+         arguments. (Necessary, but will cause warnings in existing
+         code until fixed)
+       - Added other new const in harmless positions.
+
+Mon Jun  8 01:06:47 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h: added enum-helper macros for code generation.
+       added G_BREAKPOINT().
+
+Sat Jun  6 14:09:22 PDT 1998 Manish Singh <yosh@gimp.org>
+
+       * gmem.c: commented out MEM_PROFILE and MEM_CHECK, causing weird
+       problems
+
+Wed Jun  3 06:19:42 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h (g_chunk_new0): convenience macro, for allocating small chunks 
+       like g_chunk_new() with additional 0 initialization.
+
+Mon Jun  1 04:43:27 1998  Tim Janik  <timj@gtk.org>
+
+       * ghash.c (g_hash_table_insert): wrote a comment describing why
+       a hash node's key should not also get replaced when overriding
+       previous entries.
+
+Tue May 26 18:30:06 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h (g_string_sized_new): new function to controll the preallocated
+       size of a GString.
+
+       * glib.h (g_strreversed): new function to reverse a string.
+
+Mon May 18 22:14:39 1998  Owen Taylor  <otaylor@gtk.org>
+(Yasuhiro SHIRASAKI <joke@awa.tohoku.ac.jp> : gtk-joke-980517-0.patch)
+       
+       * gutils.c: Restored a missing prototype for g_vsprintf.
+
+Wed May 20 05:02:26 1998  Tim Janik  <timj@gtk.org>
+
+        * glib.h: conditionally define NULL, FALSE and TRUE.
+        (g_mem_chunk_create): new convenience macro as a short hand for
+        g_mem_chunk_new().
+        (g_chunk_free): new convenience macro to be consistent with g_chunk_new.
+
+Tue, 19 May 1998 09:00:02 +0200  Â§Paolo Molaro <lupus@debian.org>
+
+       * gcompletion.c: generic functions for com<TAB>pletion...
+
+Sun May 17 10:48:27 1998  Tim Janik  <timj@gtk.org>
+
+       * gscanner.c (g_scanner_unexp_token): provide usefull default
+       specifications for identifier_spec and symbol_spec.
+
+       * glib.h: new functions g_slist_nth_data and g_list_nth_data to return
+       the data of the nth element in the list.
+
+Fri May 15 22:31:49 1998  Tim Janik  <timj@gtk.org>
+
+       * gscanner.c (g_scanner_unexp_token): removed spurious va_end(args)
+       that for some reason didn't produce a compiler wrning on my machine
+       (is va_end undefined for i386?).
+
+Fri May 15 12:32:08 1998  rodo  <doulik@karlin.mff.cuni.cz>
+
+       * gscanner.c: replaced some snprintf with g_snprintf
+
+Fri May 15 00:56:59 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h: further support for gcc function attributes: G_GNUC_FORMAT,
+       G_GNUC_NORETURN and G_GNUC_CONST.
+
+       * gscanner.c (g_scanner_stat_mode): changed stat() to lstat().
+       (g_scanner_msg_handler): "\n" at end of line!
+       (g_scanner_foreach_symbol): new function to iterate over the symbol
+       table (GScanner does value-wrapping).
+
+Thu May 14 04:14:12 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h: typedef gint gboolean;
+       this is needed to provide portability with big-endian platforms (e.g.
+       try sizeof(bool) for c++ on big-endians - it's 4).
+       this is also needed to maintain some_union.d_gint==some_union.d_gboolean.
+       plus, gint to gboolean casts and vice versa need to be possible without
+       loss.
+
+Tue May 12 19:22:58 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * glib/glib.h: Added macros G[U]INT_TO_POINTER() and
+       GPOINTER_TO_[U]INT for storing small integers integers
+       inside pointers. 
+       
+       * glib/testglib.c: Print sizeof() results
+       as g_print("%ld", (glong)sizeof(foo)), to deal with
+       size_t being long on Alpha's.
+
+Tue May 12 16:54:15 1998  Owen Taylor  <otaylor@gtk.org>
+       (James A <jamesa@demon.net> : gtk-jamesa-980511-4.patch)
+       
+       * glib.h gstring.c gmessages.c: Added some missing
+       const to arguments.
+
+       * gutils.c (g_strsignal.c): Added missing return statements.
+
+Mon May 11 21:11:54 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * gutils.c gmessages.c: Moved g_error, g_warning, g_message and
+       g_print from gutils.c to new file gmessages.c, to avoid having to
+       include <unistd.h> in gutils.c which was causing problems for the
+       g_strsignal implementation on FreeBSD boxes.
+
+Mon May 11 09:53:43 1998  Tim Janik  <timj@gtk.org>
+
+       * configure.in: preserve automake CFLAGS.
+
+       * Makefile.am: fully rename the created library to libglib-1.1.la.
+       this means we need to change certain portions of the Makefile.am on
+       major/minor version bumps.
+
+       * ltmain.sh: the -release option is not required anymore.
+
+        * glib.h: provide G_GNUC_FUNCTION and G_GNUC_PRETTY_FUNCTION to
+       avoid conditionals. unconditionally define NULL, TRUE, FALSE, MAX,
+       MIN, ABS and CLAMP, these macros might be screwed from other headers.
+
+Mon May 11 01:44:10 1998  Tim Janik  <timj@gtk.org>
+
+       * gdataset.c: new file, gdatasets implement the object data
+       mechanism from GtkObject. a generic data pointer is associated with
+       a certain location and a key id.
+
+Sat May  9 20:08:12 1998  Owen Taylor  <otaylor@gtk.org>
+
+        * glib/gmem.c: Experimentally restore GMemChunk
+        to its primeval state - where mem areas are
+        freed incrementally instead of searching the tree
+        every time a mem area is completely empty. Also,
+        always keep one mem chunk around. (Reduced calls
+        to malloc() a lot, but doesn't really improve
+        performance significiantly)
+
+Thu May  7 08:17:28 1998  Tim Janik  <timj@gtk.org>
+
+       * glib.h (G_GNUC_PRINTF):
+       (G_GNUC_SCANF): macros to facilitate the printf/scanf format argument
+       checking of gcc.
+
+       * gstring.c: const corrections, string!=NULL checks at function entry.
+       (g_string_down): new function for tolower(3) conversion.
+       (g_string_up): new function for toupper(3) conversion.
+
+       * gutils.c: const corrections.
+       (g_strdown): g_string_down() counterpart.
+       (g_strup): g_string_up() counterpart.
+
+       * gscanner.c (g_scanner_unexp_token):
+       (g_scanner_error):
+       (g_scanner_warn): new functions to let a scanner put out warnings
+       or errors, especially to react on unexpected tokens.
+
+       * gslist.c:
+       (g_slist_index): find out about about the position of a
+       certain data pointer.
+       (g_slist_position): find out about about the position of a
+       certain node.
+
+       * glist.c:
+       (g_list_index): find out about about the position of a
+       certain data pointer.
+
+Thu May  7 05:14:19 1998  Tim Janik  <timj@gtk.org>
+
+       * ltmain.sh: added a new commandline flag -postfix similar to -release,
+       but will immediately change the library name.
+
+       * Makefile.am: specify -postfix and -version-info
+
+       * configure.in: version bump to 1.1.0. added GLIB_INTERFACE_AGE and
+       GLIB_BINARY_AGE. calculate LT_* variables for libtool.
+
+Fri May  1 16:36:08 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * gutils.c: (g_strcasecmp). Check for isupper before
+       taking tolower, and account for macroized tolower.
+
+       * gutils.c (g_error): Check for recursion.
+
+1998-04-27  Elliot Lee  <sopwith@cuc.ml.org>
+
+       * glist.c (g_list_position): New function to find the position of
+       a link in a list - should be the inverse of g_list_nth(), but
+       haven't tested it so poof.
+
+Thu Apr 30 21:41:30 1998  Owen Taylor  <otaylor@gtk.org>
+
+       * gstring.c : Check arguments more carefully, 
+       (gtk-draco-980423-1.patch; ramsey@rhrk.uni-kl.de) 
+
+Tue Apr  7 19:36:48 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gutils.c (g_direct_compare): Removed, because that's what
+       a NULL comparison function means. And it wasn't 64 bit safe.
+
+Mon Apr  6 18:43:25 1998  Tim Janik  <timj@gtk.org>
+
+       * gscanner.c (g_scanner_get_token_ll): fixed a bug that caused floats
+       of the format ".xxx" to be parsed as "xxx".
+
+Fri Apr  3 20:36:35 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gutils.c (g_parse_debug_string): Make debug string
+       parsine case-insensitive
+
+Fri Apr  3 17:03:18 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * gstring.c: corrected possible overrun when inserting into
+       GStrings (thanks Elrond)
+
+Fri Apr  3 18:05:45 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * testglib.c: Removed literal german from strings
+       to appease SGI compiler.
+       
+Thu Mar 26 20:47:21 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * configure.in glib glibconfig.h.in: Add test for atexit/on_exit -
+       use on_exit if atexit not found in definition of ATEXIT.
+
+Wed Mar 25 15:23:37 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * Makefile.am: Switched glibconfig.h rule from HEADERS
+       to DATA, so that it is not added to DISTFILES
+
+Wed Mar 18 22:27:08 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * garray.c: g_rarray_truncate length done correctly
+
+Sun Mar 15 07:13:34 1998  Tim Janik  <timj@gimp.org>
+
+       * gutils.c: changed *_handler variables to be named glib_*_handler,
+       so you can easily access them from gdb.
+
+Sat Mar 14 17:47:43 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * Makefile.am: Don't refer to current directory as $(top_builddir)
+       to avoid confusing non-gmakes
+
+Sat Mar 14 01:37:35 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * Makefile.am (configincludedir): Moved glibconfig.h to
+          $(pkglibdir)/include
+
+Tue Mar 10 02:03:12 1998  Tim Janik  <timj@gimp.org>
+
+       * gscanner.c (g_scanner_destroy_symbol_table_entry): new function to
+       free symbol table entries upon destruction
+       (gtk-gronlund-980309-0.patch.gz).
+
+Mon Mar  9 15:02:21 1998  Tim Janik  <timj@gimp.org>
+
+       * glib.h: changed *_length functions to return guint.
+       changed *_nth functions to take guint as argument.
+
+       * glist.c: adapted g_list_length and g_list_length.
+
+       * gslist.c: adapted g_slist_length and g_slist_length.
+
+Mon Mar  2 17:51:18 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glib.h gutils.c : changed g_strcasecmp
+         to take gchar* not guchar*
+
+       * testglib.c: Remove trailing ; after functions
+       
+Sun Mar  1 19:04:40 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glib.h gstring.c: Added g_string_insert[_c]()
+         and g_string_erase().
+
+         From: Stefan Wille  <1wille@vsys1.informatik.uni-hamburg.de>
+
+Mon Feb 16 23:05:06 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glist.c (g_list_insert_sorted): Changed function
+         so elements are always inserted, even if they compare
+         equal with another.
+
+Thu Feb 12 22:48:11 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gstring.c glib.h: removed deprecated g_string_equal
+         and g_string_hash.
+
+Tue Feb 10 13:04:36 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * configure.in: Add check to see if the C library's
+         iswalnum can actually be used. (Not true for
+         Linux libc-5.4.38)
+
+Sat Feb  7 11:48:09 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gstring.c gutils.c: added some additional consts in
+         appropriate places to remove a warning
+
+Sat Feb  7 11:15:54 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gutils.c: include <ctype.h> for tolower()
+
+Fri Jan 30 23:57:17 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * added and autoconfigured in a new utility function
+       g_strcasecmp
+
+Wed Jan 28 23:53:27 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * glist.c
+       * gslist.c
+       * testglib.c: the sort functions compared backwards. Fixed
+       * glib.h: list iterator macros now check for NULL pointers
+
+Tue Jan 27 09:46:57 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * gstring.c: g_string_prepend and g_string_prepend_c had
+       interchanged src and dest parameters for g_memmove. Fixed.
+
+Tue Jan 27 01:38:52 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * gslist.c: fixed a really, really lame error. g_slist_insert
+       didn't hook the data in! Reworked the routine to reflect the
+       functionality of g_list
+
+Wed Jan 21 01:13:25 1998  Tim Janik  <timj@psynet.net>
+
+       * Applied patch from (Raja R Harinath <harinath@cs.umn.edu>)
+         to add function g_snprintf.
+        * configure.in (AC_CHECK_FUNCS): Check for vsnprintf.
+        * glib.h: Add prototype for g_snprintf.
+        * glibconfig.h.in: Add HAVE_VSNPRINTF.
+        * gutils.c (g_snprintf): new function.
+
+Sat Jan 17 23:52:40 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * gstring.{c,h} gscanner.c:
+          renamed g_string_equal => g_str_equal
+          renamed g_string_hash => g_str_hash
+         And const corrected. Old functions left in for now.
+       
+Fri Jan  9 20:03:46 1998  Tim Janik  <timj@psynet.net>
+
+       * gutils.c (g_strerror): changed message for EAGAIN from
+       "no more processes" to "try again" since EAGAIN is used with
+       functions else than fork().
+
+       * gscanner.c (g_scanner_get_token_ll): use strtol() instead of
+       strtoul() to avoid conflicts with solaris.
+
+       * merged the glib portions from Jan 2 to Jan 7 out of gtk+/ChangeLog
+       into this file.
+
+Wed Jan  7 02:14:30 PST 1998 Manish Singh <yosh@gimp.org>
+
+       * glib.h:
+       * glist.c:
+       * gslist.c:
+       * testglib.c: Added g_[s]list_insert_sorted function
+       and appropriate tests in testglib
+
+Sat Jan  3 20:23:25 1998  Owen Taylor  <owt1@cornell.edu>
+
+       * glib.h: Changed guint32 -> guint for bitfields.
+       (Bitfields must be int or unsigned int?)
+
+Fri Jan  2 23:52 PST 1998 Jay Painter <jpaint@serv.net>
+
+       * glib_pre1.h: 
+       * glib_pre2.h: 
+       * glib.h: reverted glibconfig.h and glib.h files back to the
+       way they were before my ugly hack.
+
+       * gscanner.c: removed inlines from clist and gscanner
+
+Tue Dec 23 02:49:51 1997  Tim Janik  <timj@psynet.net>
+
+       * gscanner.c: new file for GScanner: Flexible lexical scanner for
+       general purpose.
+       * glib_pre2.h: added GScanner includes. added g_strconcat and g_strtod.
+       gutils.c (g_strconcat): new function for string concatenation of NULL
+       terminated parameter list.
+       (g_strtod): new function to perform best string to double conversion
+       with or without consideration of the current locale.
+
+Mon Dec 15 19:33:58 1997  Tim Janik  <timj@psynet.net>
+
+       * glist.c: minor optimizations:
+       (g_list_append): `if' optimized for common code path, commented out
+       unneccessary `assert', saved one variable assignment.
+       (g_list_prepend): saved two (conditioned) variable assignment.
+       (g_list_insert): saved one  (conditioned) variable assignment,
+       saved one variable assignment.
+       (g_list_remove): `if' optimized for common code path, saved two
+       variable assignments by using `g_list_free_1' (which is even
+       faster) instead of `g_list_free'.
+       (g_list_reverse): saved allocation of one variable, saved one
+       variable assignment.
+
+Wed Dec 10 23:27:20 1997  Tim Janik  <timj@psynet.net>
+
+       * glib_pre1.h: 
+       * glib_pre2.h: 
+       * glib.h: this file now gets concatenated by makeglib_h from
+       glib_pre1.h and glib_pre2.h to merge in glibconfig.h wich got
+       created by configure (done by Jay Painter).
+
+       * glib_pre2.h: the g_assert*() and g_return_*_fail() macros
+       are wrapped by G_STMT_START and G_STMT_END now, to avoid conflicts
+       when used within if (...) g_macro(); else ... conditionals.
+       
+Tue Dec 17 13:14:07 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * glib.h: Changed 'g_return_if_fail' and 'g_return_val_if_fail' to
+       not call 'g_string' but to simply stringify the
+       expression. Calling 'g_string' causes the expression to be
+       expanded which is undesired.
+
+Sun Dec  1 01:30:48 1996  Peter Mattis  <pmattis@charnley.HIP.Berkeley.EDU>
+
+       * Started ChangeLog
diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..84f5635
--- /dev/null
@@ -0,0 +1,54 @@
+## Process this file with automake to produce Makefile.in
+
+configincludedir = $(pkglibdir)/include
+
+bin_SCRIPTS=glib-config
+
+EXTRA_DIST =   \
+               glib.m4
+
+lib_LTLIBRARIES = libglib-1.1.la
+
+libglib_1_1_la_SOURCES = \
+               garray.c        \
+               gcache.c        \
+               gcompletion.c   \
+               gdataset.c      \
+               gerror.c        \
+               ghash.c         \
+               glist.c         \
+               gmem.c          \
+               gmessages.c     \
+               gprimes.c       \
+               gslist.c        \
+               gtimer.c        \
+               gtree.c         \
+               gstring.c       \
+               gscanner.c      \
+               gutils.c
+
+include_HEADERS = \
+               glib.h
+
+configinclude_DATA = \
+               glibconfig.h
+
+libglib_1_1_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
+
+INCLUDES = -I$(top_srcdir)
+
+noinst_PROGRAMS = testglib
+testglib_LDADD = libglib-@LT_RELEASE@.la
+
+m4datadir = $(datadir)/aclocal
+m4data_DATA = glib.m4
+
+.PHONY: files release
+
+files:
+       @files=`ls $(DISTFILES) 2> /dev/null `; for p in $$files; do \
+         echo $$p; \
+       done
+
+release:
+       $(MAKE) dist distdir=$(PACKAGE)`date +"%y%m%d"`
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/acconfig.h b/acconfig.h
new file mode 100644 (file)
index 0000000..e79f1d6
--- /dev/null
@@ -0,0 +1,76 @@
+/* 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.
+ */
+/* acconfig.h
+   This file is in the public domain.
+
+   Descriptive text for the C preprocessor macros that
+   the distributed Autoconf macros can define.
+   No software package will use all of them; autoheader copies the ones
+   your configure.in uses into your configuration header file templates.
+
+   The entries are in sort -df order: alphabetical, case insensitive,
+   ignoring punctuation (such as underscores).  Although this order
+   can split up related entries, it makes it easier to check whether
+   a given entry is in the file.
+
+   Leave the following blank line there!!  Autoheader needs it.  */
+\f
+
+/* Other stuff */
+
+#undef ENABLE_MEM_CHECK
+#undef ENABLE_MEM_PROFILE
+
+#undef G_COMPILED_WITH_DEBUGGING
+#undef HAVE_BROKEN_WCTYPE
+#undef HAVE_DOPRNT
+#undef HAVE_FLOAT_H
+#undef HAVE_LIMITS_H
+#undef HAVE_LONG_DOUBLE
+#undef HAVE_SYS_SELECT_H
+#undef HAVE_STRERROR
+#undef HAVE_STRSIGNAL
+#undef HAVE_VSNPRINTF
+#undef HAVE_VALUES_H
+#undef HAVE_VPRINTF
+#undef HAVE_WCHAR_H
+#undef HAVE_WCTYPE_H
+
+#undef NO_FD_SET
+#undef NO_SYS_ERRLIST
+#undef NO_SYS_SIGLIST
+
+#undef SIZEOF_CHAR
+#undef SIZEOF_SHORT
+#undef SIZEOF_LONG
+#undef SIZEOF_INT
+#undef SIZEOF_VOID_P
+
+#undef GLIB_MAJOR_VERSION
+#undef GLIB_MINOR_VERSION
+#undef GLIB_MICRO_VERSION
+
+/* #undef PACKAGE */
+/* #undef VERSION */
+
+\f
+/* Leave that blank line there!!  Autoheader needs it.
+   If you're adding to this file, keep in mind:
+   The entries are in sort -df order: alphabetical, case insensitive,
+   ignoring punctuation (such as underscores).  */
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..d9da49b
--- /dev/null
@@ -0,0 +1,50 @@
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+
+DIE=0
+
+(autoconf --version) < /dev/null > /dev/null 2>&1 || {
+       echo
+       echo "You must have autoconf installed to compile GLIB."
+       echo "Download the appropriate package for your distribution,"
+       echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
+       DIE=1
+}
+
+(libtool --version) < /dev/null > /dev/null 2>&1 || {
+       echo
+       echo "You must have libtool installed to compile GLIB."
+       echo "Get ftp://alpha.gnu.org/gnu/libtool-1.0h.tar.gz"
+       echo "(or a newer version if it is available)"
+       DIE=1
+}
+
+(automake --version) < /dev/null > /dev/null 2>&1 || {
+       echo
+       echo "You must have automake installed to compile GLIB."
+       echo "Get ftp://ftp.cygnus.com/pub/home/tromey/automake-1.2d.tar.gz"
+       echo "(or a newer version if it is available)"
+       DIE=1
+}
+
+if test "$DIE" -eq 1; then
+       exit 1
+fi
+
+test -f glib.h || {
+       echo "You must run this script in the top-level GLIB directory"
+       exit 1
+}
+
+if test -z "$*"; then
+       echo "I am going to run ./configure with no arguments - if you wish "
+        echo "to pass any to it, please specify them on the $0 command line."
+fi
+
+aclocal
+automake
+autoconf
+./configure "$@"
+
+echo 
+echo "Now type 'make' to compile GLIB."
diff --git a/config.guess b/config.guess
new file mode 100755 (executable)
index 0000000..413ed41
--- /dev/null
@@ -0,0 +1,883 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# The master version of this file is at the FSF in /home/gd/gnu/lib.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit system type (host/target name).
+#
+# Only a few systems have been added to this list; please add others
+# (but try to keep the structure clean).
+#
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 8/24/94.)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+       PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    alpha:OSF1:*:*)
+       if test $UNAME_RELEASE = "V4.0"; then
+               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+       fi
+       # A Vn.n version is a released version.
+       # A Tn.n version is a released field test version.
+       # A Xn.n version is an unreleased experimental baselevel.
+       # 1.2 uses "1.2" for uname -r.
+       cat <<EOF >dummy.s
+       .globl main
+       .ent main
+main:
+       .frame \$30,0,\$26,0
+       .prologue 0
+       .long 0x47e03d80 # implver $0
+       lda \$2,259
+       .long 0x47e20c21 # amask $2,$1
+       srl \$1,8,\$2
+       sll \$2,2,\$2
+       sll \$0,3,\$0
+       addl \$1,\$0,\$0
+       addl \$2,\$0,\$0
+       ret \$31,(\$26),1
+       .end main
+EOF
+       ${CC-cc} dummy.s -o dummy 2>/dev/null
+       if test "$?" = 0 ; then
+               ./dummy
+               case "$?" in
+                       7)
+                               UNAME_MACHINE="alpha"
+                               ;;
+                       15)
+                               UNAME_MACHINE="alphaev5"
+                               ;;
+                       14)
+                               UNAME_MACHINE="alphaev56"
+                               ;;
+                       10)
+                               UNAME_MACHINE="alphapca56"
+                               ;;
+                       16)
+                               UNAME_MACHINE="alphaev6"
+                               ;;
+               esac
+       fi
+       rm -f dummy.s dummy
+       echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]`
+       exit 0 ;;
+    21064:Windows_NT:50:3)
+       echo alpha-dec-winnt3.5
+       exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+       echo m68k-cbm-sysv4
+       exit 0;;
+    amiga:NetBSD:*:*)
+      echo m68k-cbm-netbsd${UNAME_RELEASE}
+      exit 0 ;;
+    amiga:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    arc64:OpenBSD:*:*)
+       echo mips64el-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    arc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    hkmips:OpenBSD:*:*)
+       echo mips-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    pmax:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sgi:OpenBSD:*:*)
+       echo mips-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+       echo arm-acorn-riscix${UNAME_RELEASE}
+       exit 0;;
+    arm32:NetBSD:*:*)
+       echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       exit 0 ;;
+    SR2?01:HI-UX/MPP:*:*)
+       echo hppa1.1-hitachi-hiuxmpp
+       exit 0;;
+    Pyramid*:OSx*:*:*|MIS*:OSx*:*:*)
+       # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+       if test "`(/bin/universe) 2>/dev/null`" = att ; then
+               echo pyramid-pyramid-sysv3
+       else
+               echo pyramid-pyramid-bsd
+       fi
+       exit 0 ;;
+    NILE:*:*:dcosx)
+       echo pyramid-pyramid-svr4
+       exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+       echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    i86pc:SunOS:5.*:*)
+       echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:6*:*)
+       # According to config.sub, this is the proper way to canonicalize
+       # SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+       # it's likely to be more like Solaris than SunOS4.
+       echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:*:*)
+       case "`/usr/bin/arch -k`" in
+           Series*|S4*)
+               UNAME_RELEASE=`uname -v`
+               ;;
+       esac
+       # Japanese Language versions have a version number like `4.1.3-JL'.
+       echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+       exit 0 ;;
+    sun3*:SunOS:*:*)
+       echo m68k-sun-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    sun*:*:4.2BSD:*)
+       UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+       test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+       case "`/bin/arch`" in
+           sun3)
+               echo m68k-sun-sunos${UNAME_RELEASE}
+               ;;
+           sun4)
+               echo sparc-sun-sunos${UNAME_RELEASE}
+               ;;
+       esac
+       exit 0 ;;
+    aushp:SunOS:*:*)
+       echo sparc-auspex-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:NetBSD:*:*)
+       echo m68k-atari-netbsd${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sun3*:NetBSD:*:*)
+       echo m68k-sun-netbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sun3*:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mac68k:NetBSD:*:*)
+       echo m68k-apple-netbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mac68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+       echo m88k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    powerpc:machten:*:*)
+       echo powerpc-apple-machten${UNAME_RELEASE}
+       exit 0 ;;
+    RISC*:Mach:*:*)
+       echo mips-dec-mach_bsd4.3
+       exit 0 ;;
+    RISC*:ULTRIX:*:*)
+       echo mips-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+       echo vax-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    2020:CLIX:*:*)
+       echo clipper-intergraph-clix${UNAME_RELEASE}
+       exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+       sed 's/^        //' << EOF >dummy.c
+       int main (argc, argv) int argc; char **argv; {
+       #if defined (host_mips) && defined (MIPSEB)
+       #if defined (SYSTYPE_SYSV)
+         printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_SVR4)
+         printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+         printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+       #endif
+       #endif
+         exit (-1);
+       }
+EOF
+       ${CC-cc} dummy.c -o dummy \
+         && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+         && rm dummy.c dummy && exit 0
+       rm -f dummy.c dummy
+       echo mips-mips-riscos${UNAME_RELEASE}
+       exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+       echo powerpc-harris-powerunix
+       exit 0 ;;
+    m88k:CX/UX:7*:*)
+       echo m88k-harris-cxux7
+       exit 0 ;;
+    m88k:*:4*:R4*)
+       echo m88k-motorola-sysv4
+       exit 0 ;;
+    m88k:*:3*:R3*)
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+        if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
+       if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
+            -o ${TARGET_BINARY_INTERFACE}x = x ] ; then
+               echo m88k-dg-dgux${UNAME_RELEASE}
+       else
+               echo m88k-dg-dguxbcs${UNAME_RELEASE}
+       fi
+        else echo i586-dg-dgux${UNAME_RELEASE}
+        fi
+       exit 0 ;;
+    M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
+       echo m88k-dolphin-sysv3
+       exit 0 ;;
+    M88*:*:R3*:*)
+       # Delta 88k system running SVR3
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+       echo m88k-tektronix-sysv3
+       exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+       echo m68k-tektronix-bsd
+       exit 0 ;;
+    *:IRIX*:*:*)
+       echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+       exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+       echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+       exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i?86:AIX:*:*)
+       echo i386-ibm-aix
+       exit 0 ;;
+    *:AIX:2:3)
+       if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+               sed 's/^                //' << EOF >dummy.c
+               #include <sys/systemcfg.h>
+
+               main()
+                       {
+                       if (!__power_pc())
+                               exit(1);
+                       puts("powerpc-ibm-aix3.2.5");
+                       exit(0);
+                       }
+EOF
+               ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
+               rm -f dummy.c dummy
+               echo rs6000-ibm-aix3.2.5
+       elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+               echo rs6000-ibm-aix3.2.4
+       else
+               echo rs6000-ibm-aix3.2
+       fi
+       exit 0 ;;
+    *:AIX:*:4)
+       if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
+               IBM_ARCH=rs6000
+       else
+               IBM_ARCH=powerpc
+       fi
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=4.${UNAME_RELEASE}
+       fi
+       echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+       exit 0 ;;
+    *:AIX:*:*)
+       echo rs6000-ibm-aix
+       exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+       echo romp-ibm-bsd4.4
+       exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC NetBSD and
+       echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+       exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+       echo rs6000-bull-bosx
+       exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+       echo m68k-bull-sysv3
+       exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+       echo m68k-hp-bsd
+       exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+       echo m68k-hp-bsd4.4
+       exit 0 ;;
+    9000/[3478]??:HP-UX:*:*)
+       case "${UNAME_MACHINE}" in
+           9000/31? )            HP_ARCH=m68000 ;;
+           9000/[34]?? )         HP_ARCH=m68k ;;
+           9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;;
+           9000/8?? )            HP_ARCH=hppa1.0 ;;
+       esac
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+       exit 0 ;;
+    3050*:HI-UX:*:*)
+       sed 's/^        //' << EOF >dummy.c
+       #include <unistd.h>
+       int
+       main ()
+       {
+         long cpu = sysconf (_SC_CPU_VERSION);
+         /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+            true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+            results, however.  */
+         if (CPU_IS_PA_RISC (cpu))
+           {
+             switch (cpu)
+               {
+                 case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+                 default: puts ("hppa-hitachi-hiuxwe2"); break;
+               }
+           }
+         else if (CPU_IS_HP_MC68K (cpu))
+           puts ("m68k-hitachi-hiuxwe2");
+         else puts ("unknown-hitachi-hiuxwe2");
+         exit (0);
+       }
+EOF
+       ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
+       rm -f dummy.c dummy
+       echo unknown-hitachi-hiuxwe2
+       exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+       echo hppa1.1-hp-bsd
+       exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+       echo hppa1.0-hp-bsd
+       exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+       echo hppa1.1-hp-osf
+       exit 0 ;;
+    hp8??:OSF1:*:*)
+       echo hppa1.0-hp-osf
+       exit 0 ;;
+    i?86:OSF1:*:*)
+       if [ -x /usr/sbin/sysversion ] ; then
+           echo ${UNAME_MACHINE}-unknown-osf1mk
+       else
+           echo ${UNAME_MACHINE}-unknown-osf1
+       fi
+       exit 0 ;;
+    parisc*:Lites*:*:*)
+       echo hppa1.1-hp-lites
+       exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+       echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+       echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+       echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+       echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*X-MP:*:*:*)
+       echo xmp-cray-unicos
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+       echo ymp-cray-unicos${UNAME_RELEASE}
+       exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+       echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+       | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+             -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+       exit 0 ;;
+    CRAY*TS:*:*:*)
+       echo t90-cray-unicos${UNAME_RELEASE}
+       exit 0 ;;
+    CRAY-2:*:*:*)
+       echo cray2-cray-unicos
+        exit 0 ;;
+    F300:UNIX_System_V:*:*)
+        FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    F301:UNIX_System_V:*:*)
+       echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
+       exit 0 ;;
+    hp3[0-9][05]:NetBSD:*:*)
+       echo m68k-hp-netbsd${UNAME_RELEASE}
+       exit 0 ;;
+    hp300:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    i?86:BSD/386:*:* | *:BSD/OS:*:*)
+       echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:FreeBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+       exit 0 ;;
+    *:NetBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       exit 0 ;;
+    *:OpenBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       exit 0 ;;
+    i*:CYGWIN*:*)
+       echo i386-pc-cygwin32
+       exit 0 ;;
+    i*:MINGW*:*)
+       echo i386-pc-mingw32
+       exit 0 ;;
+    p*:CYGWIN*:*)
+       echo powerpcle-unknown-cygwin32
+       exit 0 ;;
+    prep*:SunOS:5.*:*)
+       echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    *:GNU:*:*)
+       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+       exit 0 ;;
+    *:Linux:*:*)
+       # The BFD linker knows what the default object file format is, so
+       # first see if it will tell us.
+       ld_help_string=`ld --help 2>&1`
+       ld_supported_emulations=`echo $ld_help_string \
+                        | sed -ne '/supported emulations:/!d
+                                   s/[         ][      ]*/ /g
+                                   s/.*supported emulations: *//
+                                   s/ .*//
+                                   p'`
+        case "$ld_supported_emulations" in
+         i?86linux)  echo "${UNAME_MACHINE}-pc-linux-gnuaout"      ; exit 0 ;;
+         i?86coff)   echo "${UNAME_MACHINE}-pc-linux-gnucoff"      ; exit 0 ;;
+         sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+         m68klinux)  echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+         elf32ppc)   echo "powerpc-unknown-linux-gnu"              ; exit 0 ;;
+       esac
+
+       if test "${UNAME_MACHINE}" = "alpha" ; then
+               sed 's/^        //'  <<EOF >dummy.s
+               .globl main
+               .ent main
+       main:
+               .frame \$30,0,\$26,0
+               .prologue 0
+               .long 0x47e03d80 # implver $0
+               lda \$2,259
+               .long 0x47e20c21 # amask $2,$1
+               srl \$1,8,\$2
+               sll \$2,2,\$2
+               sll \$0,3,\$0
+               addl \$1,\$0,\$0
+               addl \$2,\$0,\$0
+               ret \$31,(\$26),1
+               .end main
+EOF
+               LIBC=""
+               ${CC-cc} dummy.s -o dummy 2>/dev/null
+               if test "$?" = 0 ; then
+                       ./dummy
+                       case "$?" in
+                       7)
+                               UNAME_MACHINE="alpha"
+                               ;;
+                       15)
+                               UNAME_MACHINE="alphaev5"
+                               ;;
+                       14)
+                               UNAME_MACHINE="alphaev56"
+                               ;;
+                       10)
+                               UNAME_MACHINE="alphapca56"
+                               ;;
+                       16)
+                               UNAME_MACHINE="alphaev6"
+                               ;;
+                       esac    
+
+                       objdump --private-headers dummy | \
+                         grep ld.so.1 > /dev/null
+                       if test "$?" = 0 ; then
+                               LIBC="libc1"
+                       fi
+               fi      
+               rm -f dummy.s dummy
+               echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
+       elif test "${UNAME_MACHINE}" = "mips" ; then
+         cat >dummy.c <<EOF
+main(argc, argv)
+     int argc;
+     char *argv[];
+{
+#ifdef __MIPSEB__
+  printf ("%s-unknown-linux-gnu\n", argv[1]);
+#endif
+#ifdef __MIPSEL__
+  printf ("%sel-unknown-linux-gnu\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+         ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
+         rm -f dummy.c dummy
+       else
+         # Either a pre-BFD a.out linker (linux-gnuoldld)
+         # or one that does not give us useful --help.
+         # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
+         # If ld does not provide *any* "supported emulations:"
+         # that means it is gnuoldld.
+         echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
+         test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
+
+         case "${UNAME_MACHINE}" in
+         i?86)
+           VENDOR=pc;
+           ;;
+         *)
+           VENDOR=unknown;
+           ;;
+         esac
+         # Determine whether the default compiler is a.out or elf
+         cat >dummy.c <<EOF
+#include <features.h>
+main(argc, argv)
+     int argc;
+     char *argv[];
+{
+#ifdef __ELF__
+# ifdef __GLIBC__
+#  if __GLIBC__ >= 2
+    printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
+#  else
+    printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+#  endif
+# else
+   printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+  printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+         ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
+         rm -f dummy.c dummy
+       fi ;;
+# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.  earlier versions
+# are messed up and put the nodename in both sysname and nodename.
+    i?86:DYNIX/ptx:4*:*)
+       echo i386-sequent-sysv4
+       exit 0 ;;
+    i?86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+       # I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+       echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+       exit 0 ;;
+    i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
+       if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+               echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
+       else
+               echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
+       fi
+       exit 0 ;;
+    i?86:*:3.2:*)
+       if test -f /usr/options/cb.name; then
+               UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+               echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+       elif /bin/uname -X 2>/dev/null >/dev/null ; then
+               UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+               (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+               (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+                       && UNAME_MACHINE=i586
+               echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+       else
+               echo ${UNAME_MACHINE}-pc-sysv32
+       fi
+       exit 0 ;;
+    pc:*:*:*)
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+       echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+       echo i386-pc-mach3
+       exit 0 ;;
+    paragon:*:*:*)
+       echo i860-intel-osf1
+       exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+       if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+         echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+       else # Add other i860-SVR4 vendors below as they are discovered.
+         echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+       fi
+       exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+       # "miniframe"
+       echo m68010-convergent-sysv
+       exit 0 ;;
+    M68*:*:R3V[567]*:*)
+       test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+       OS_REL=''
+       test -r /etc/.relid \
+       && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+         && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+       /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+         && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:*)
+       echo m68k-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+       echo m68k-atari-sysv4
+       exit 0 ;;
+    i?86:LynxOS:2.*:*)
+       echo i386-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+       echo sparc-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
+       echo rs6000-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+       echo mips-dde-sysv${UNAME_RELEASE}
+       exit 0 ;;
+    RM*:SINIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    *:SINIX-*:*:*)
+       if uname -p 2>/dev/null >/dev/null ; then
+               UNAME_MACHINE=`(uname -p) 2>/dev/null`
+               echo ${UNAME_MACHINE}-sni-sysv4
+       else
+               echo ns32k-sni-sysv
+       fi
+       exit 0 ;;
+    PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                           # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+       # From Gerald Hewes <hewes@openmarket.com>.
+       # How about differentiating between stratus architectures? -djm
+       echo hppa1.1-stratus-sysv4
+       exit 0 ;;
+    *:*:*:FTX*)
+       # From seanf@swdc.stratus.com.
+       echo i860-stratus-sysv4
+       exit 0 ;;
+    mc68*:A/UX:*:*)
+       echo m68k-apple-aux${UNAME_RELEASE}
+       exit 0 ;;
+    news*:NEWS-OS:*:6*)
+       echo mips-sony-newsos6
+       exit 0 ;;
+    R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*)
+       if [ -d /usr/nec ]; then
+               echo mips-nec-sysv${UNAME_RELEASE}
+       else
+               echo mips-unknown-sysv${UNAME_RELEASE}
+       fi
+        exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+         ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+       printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+       printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+  printf ("vax-dec-bsd\n"); exit (0);
+#else
+  printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
+rm -f dummy.c dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+       echo c1-convex-bsd
+       exit 0 ;;
+    c2*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+       exit 0 ;;
+    c34*)
+       echo c34-convex-bsd
+       exit 0 ;;
+    c38*)
+       echo c38-convex-bsd
+       exit 0 ;;
+    c4*)
+       echo c4-convex-bsd
+       exit 0 ;;
+    esac
+fi
+
+#echo '(Unable to guess system type)' 1>&2
+
+exit 1
diff --git a/config.h.in b/config.h.in
new file mode 100644 (file)
index 0000000..97e6082
--- /dev/null
@@ -0,0 +1,81 @@
+/* config.h.in.  Generated automatically from configure.in by autoheader.  */
+
+/* Define to empty if the keyword does not work.  */
+#undef const
+
+/* Define if you don't have vprintf but do have _doprnt.  */
+#undef HAVE_DOPRNT
+
+/* Define if you have the vprintf function.  */
+#undef HAVE_VPRINTF
+
+/* Define as __inline if that's what the C compiler calls it.  */
+#undef inline
+
+/* Define if you have the ANSI C header files.  */
+#undef STDC_HEADERS
+
+/* Other stuff */
+#undef G_COMPILED_WITH_DEBUGGING
+#undef HAVE_BROKEN_WCTYPE
+#undef HAVE_DOPRNT
+#undef HAVE_FLOAT_H
+#undef HAVE_LIMITS_H
+#undef HAVE_LONG_DOUBLE
+#undef HAVE_SYS_SELECT_H
+#undef HAVE_STRERROR
+#undef HAVE_STRSIGNAL
+#undef HAVE_VSNPRINTF
+#undef HAVE_VALUES_H
+#undef HAVE_VPRINTF
+#undef HAVE_WCHAR_H
+#undef HAVE_WCTYPE_H
+
+#undef NO_FD_SET
+#undef NO_SYS_ERRLIST
+#undef NO_SYS_SIGLIST
+
+/* The number of bytes in a char.  */
+#undef SIZEOF_CHAR
+
+/* The number of bytes in a int.  */
+#undef SIZEOF_INT
+
+/* The number of bytes in a long.  */
+#undef SIZEOF_LONG
+
+/* The number of bytes in a short.  */
+#undef SIZEOF_SHORT
+
+/* The number of bytes in a void *.  */
+#undef SIZEOF_VOID_P
+
+/* Define if you have the atexit function.  */
+#undef HAVE_ATEXIT
+
+/* Define if you have the memmove function.  */
+#undef HAVE_MEMMOVE
+
+/* Define if you have the on_exit function.  */
+#undef HAVE_ON_EXIT
+
+/* Define if you have the strcasecmp function.  */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the strerror function.  */
+#undef HAVE_STRERROR
+
+/* Define if you have the strsignal function.  */
+#undef HAVE_STRSIGNAL
+
+/* Define if you have the vsnprintf function.  */
+#undef HAVE_VSNPRINTF
+
+/* Define if you have the <float.h> header file.  */
+#undef HAVE_FLOAT_H
+
+/* Define if you have the <limits.h> header file.  */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <values.h> header file.  */
+#undef HAVE_VALUES_H
diff --git a/config.sub b/config.sub
new file mode 100755 (executable)
index 0000000..213a6d4
--- /dev/null
@@ -0,0 +1,954 @@
+#! /bin/sh
+# Configuration validation subroutine script, version 1.1.
+#   Copyright (C) 1991, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#      CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#      CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+if [ x$1 = x ]
+then
+       echo Configuration name missing. 1>&2
+       echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
+       echo "or     $0 ALIAS" 1>&2
+       echo where ALIAS is a recognized configuration type. 1>&2
+       exit 1
+fi
+
+# First pass through any local machine types.
+case $1 in
+       *local*)
+               echo $1
+               exit 0
+               ;;
+       *)
+       ;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  linux-gnu*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+       -sun*os*)
+               # Prevent following clause from handling this invalid input.
+               ;;
+       -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+       -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+       -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+       -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+       -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+       -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+       -apple)
+               os=
+               basic_machine=$1
+               ;;
+       -hiux*)
+               os=-hiuxwe2
+               ;;
+       -sco5)
+               os=sco3.2v5
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco4)
+               os=-sco3.2v4
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2.[4-9]*)
+               os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2v[4-9]*)
+               # Don't forget version if it is 3.2v4 or newer.
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco*)
+               os=-sco3.2v2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -isc)
+               os=-isc2.2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -clix*)
+               basic_machine=clipper-intergraph
+               ;;
+       -isc*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -lynx*)
+               os=-lynxos
+               ;;
+       -ptx*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+               ;;
+       -windowsnt*)
+               os=`echo $os | sed -e 's/windowsnt/winnt/'`
+               ;;
+       -psos*)
+               os=-psos
+               ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+       # Recognize the basic CPU types without company name.
+       # Some are omitted here because they have special meanings below.
+       tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
+               | arme[lb] | pyramid | mn10200 | mn10300 \
+               | tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \
+               | alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \
+               | i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \
+               | mips64 | mipsel | mips64el | mips64orion | mips64orionel \
+               | mipstx39 | mipstx39el \
+               | sparc | sparclet | sparclite | sparc64 | v850)
+               basic_machine=$basic_machine-unknown
+               ;;
+       # We use `pc' rather than `unknown'
+       # because (1) that's what they normally are, and
+       # (2) the word "unknown" tends to confuse beginning users.
+       i[3456]86)
+         basic_machine=$basic_machine-pc
+         ;;
+       # Object if more than one company name word.
+       *-*-*)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+       # Recognize the basic CPU types with company name.
+       vax-* | tahoe-* | i[3456]86-* | i860-* | m32r-* | m68k-* | m68000-* \
+             | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
+             | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+             | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \
+             | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* \
+             | alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \
+             | ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \
+             | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
+             | sparc64-* | mips64-* | mipsel-* \
+             | mips64el-* | mips64orion-* | mips64orionel-*  \
+             | mipstx39-* | mipstx39el-* \
+             | f301-*)
+               ;;
+       # Recognize the various machine names and aliases which stand
+       # for a CPU type and a company and sometimes even an OS.
+       3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+               basic_machine=m68000-att
+               ;;
+       3b*)
+               basic_machine=we32k-att
+               ;;
+       alliant | fx80)
+               basic_machine=fx80-alliant
+               ;;
+       altos | altos3068)
+               basic_machine=m68k-altos
+               ;;
+       am29k)
+               basic_machine=a29k-none
+               os=-bsd
+               ;;
+       amdahl)
+               basic_machine=580-amdahl
+               os=-sysv
+               ;;
+       amiga | amiga-*)
+               basic_machine=m68k-cbm
+               ;;
+       amigaos | amigados)
+               basic_machine=m68k-cbm
+               os=-amigaos
+               ;;
+       amigaunix | amix)
+               basic_machine=m68k-cbm
+               os=-sysv4
+               ;;
+       apollo68)
+               basic_machine=m68k-apollo
+               os=-sysv
+               ;;
+       aux)
+               basic_machine=m68k-apple
+               os=-aux
+               ;;
+       balance)
+               basic_machine=ns32k-sequent
+               os=-dynix
+               ;;
+       convex-c1)
+               basic_machine=c1-convex
+               os=-bsd
+               ;;
+       convex-c2)
+               basic_machine=c2-convex
+               os=-bsd
+               ;;
+       convex-c32)
+               basic_machine=c32-convex
+               os=-bsd
+               ;;
+       convex-c34)
+               basic_machine=c34-convex
+               os=-bsd
+               ;;
+       convex-c38)
+               basic_machine=c38-convex
+               os=-bsd
+               ;;
+       cray | ymp)
+               basic_machine=ymp-cray
+               os=-unicos
+               ;;
+       cray2)
+               basic_machine=cray2-cray
+               os=-unicos
+               ;;
+       [ctj]90-cray)
+               basic_machine=c90-cray
+               os=-unicos
+               ;;
+       crds | unos)
+               basic_machine=m68k-crds
+               ;;
+       da30 | da30-*)
+               basic_machine=m68k-da30
+               ;;
+       decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+               basic_machine=mips-dec
+               ;;
+       delta | 3300 | motorola-3300 | motorola-delta \
+             | 3300-motorola | delta-motorola)
+               basic_machine=m68k-motorola
+               ;;
+       delta88)
+               basic_machine=m88k-motorola
+               os=-sysv3
+               ;;
+       dpx20 | dpx20-*)
+               basic_machine=rs6000-bull
+               os=-bosx
+               ;;
+       dpx2* | dpx2*-bull)
+               basic_machine=m68k-bull
+               os=-sysv3
+               ;;
+       ebmon29k)
+               basic_machine=a29k-amd
+               os=-ebmon
+               ;;
+       elxsi)
+               basic_machine=elxsi-elxsi
+               os=-bsd
+               ;;
+       encore | umax | mmax)
+               basic_machine=ns32k-encore
+               ;;
+       fx2800)
+               basic_machine=i860-alliant
+               ;;
+       genix)
+               basic_machine=ns32k-ns
+               ;;
+       gmicro)
+               basic_machine=tron-gmicro
+               os=-sysv
+               ;;
+       h3050r* | hiux*)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       h8300hms)
+               basic_machine=h8300-hitachi
+               os=-hms
+               ;;
+       harris)
+               basic_machine=m88k-harris
+               os=-sysv3
+               ;;
+       hp300-*)
+               basic_machine=m68k-hp
+               ;;
+       hp300bsd)
+               basic_machine=m68k-hp
+               os=-bsd
+               ;;
+       hp300hpux)
+               basic_machine=m68k-hp
+               os=-hpux
+               ;;
+       hp9k2[0-9][0-9] | hp9k31[0-9])
+               basic_machine=m68000-hp
+               ;;
+       hp9k3[2-9][0-9])
+               basic_machine=m68k-hp
+               ;;
+       hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7)
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][0-9] | hp8[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hppa-next)
+               os=-nextstep3
+               ;;
+       i370-ibm* | ibm*)
+               basic_machine=i370-ibm
+               os=-mvs
+               ;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+       i[3456]86v32)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv32
+               ;;
+       i[3456]86v4*)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv4
+               ;;
+       i[3456]86v)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv
+               ;;
+       i[3456]86sol2)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-solaris2
+               ;;
+       iris | iris4d)
+               basic_machine=mips-sgi
+               case $os in
+                   -irix*)
+                       ;;
+                   *)
+                       os=-irix4
+                       ;;
+               esac
+               ;;
+       isi68 | isi)
+               basic_machine=m68k-isi
+               os=-sysv
+               ;;
+       m88k-omron*)
+               basic_machine=m88k-omron
+               ;;
+       magnum | m3230)
+               basic_machine=mips-mips
+               os=-sysv
+               ;;
+       merlin)
+               basic_machine=ns32k-utek
+               os=-sysv
+               ;;
+       miniframe)
+               basic_machine=m68000-convergent
+               ;;
+       mipsel*-linux*)
+               basic_machine=mipsel-unknown
+               os=-linux-gnu
+               ;;
+       mips*-linux*)
+               basic_machine=mips-unknown
+               os=-linux-gnu
+               ;;
+       mips3*-*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+               ;;
+       mips3*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+               ;;
+       ncr3000)
+               basic_machine=i486-ncr
+               os=-sysv4
+               ;;
+       news | news700 | news800 | news900)
+               basic_machine=m68k-sony
+               os=-newsos
+               ;;
+       news1000)
+               basic_machine=m68030-sony
+               os=-newsos
+               ;;
+       news-3600 | risc-news)
+               basic_machine=mips-sony
+               os=-newsos
+               ;;
+       next | m*-next )
+               basic_machine=m68k-next
+               case $os in
+                   -nextstep* )
+                       ;;
+                   -ns2*)
+                     os=-nextstep2
+                       ;;
+                   *)
+                     os=-nextstep3
+                       ;;
+               esac
+               ;;
+       nh3000)
+               basic_machine=m68k-harris
+               os=-cxux
+               ;;
+       nh[45]000)
+               basic_machine=m88k-harris
+               os=-cxux
+               ;;
+       nindy960)
+               basic_machine=i960-intel
+               os=-nindy
+               ;;
+       np1)
+               basic_machine=np1-gould
+               ;;
+       pa-hitachi)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       paragon)
+               basic_machine=i860-intel
+               os=-osf
+               ;;
+       pbd)
+               basic_machine=sparc-tti
+               ;;
+       pbb)
+               basic_machine=m68k-tti
+               ;;
+        pc532 | pc532-*)
+               basic_machine=ns32k-pc532
+               ;;
+       pentium | p5)
+               basic_machine=i586-intel
+               ;;
+       pentiumpro | p6)
+               basic_machine=i686-intel
+               ;;
+       pentium-* | p5-*)
+               basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumpro-* | p6-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       k5)
+               # We don't have specific support for AMD's K5 yet, so just call it a Pentium
+               basic_machine=i586-amd
+               ;;
+       nexen)
+               # We don't have specific support for Nexgen yet, so just call it a Pentium
+               basic_machine=i586-nexgen
+               ;;
+       pn)
+               basic_machine=pn-gould
+               ;;
+       power)  basic_machine=rs6000-ibm
+               ;;
+       ppc)    basic_machine=powerpc-unknown
+               ;;
+       ppc-*)  basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppcle | powerpclittle | ppc-le | powerpc-little)
+               basic_machine=powerpcle-unknown
+               ;;
+       ppcle-* | powerpclittle-*)
+               basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ps2)
+               basic_machine=i386-ibm
+               ;;
+       rm[46]00)
+               basic_machine=mips-siemens
+               ;;
+       rtpc | rtpc-*)
+               basic_machine=romp-ibm
+               ;;
+       sequent)
+               basic_machine=i386-sequent
+               ;;
+       sh)
+               basic_machine=sh-hitachi
+               os=-hms
+               ;;
+       sps7)
+               basic_machine=m68k-bull
+               os=-sysv2
+               ;;
+       spur)
+               basic_machine=spur-unknown
+               ;;
+       sun2)
+               basic_machine=m68000-sun
+               ;;
+       sun2os3)
+               basic_machine=m68000-sun
+               os=-sunos3
+               ;;
+       sun2os4)
+               basic_machine=m68000-sun
+               os=-sunos4
+               ;;
+       sun3os3)
+               basic_machine=m68k-sun
+               os=-sunos3
+               ;;
+       sun3os4)
+               basic_machine=m68k-sun
+               os=-sunos4
+               ;;
+       sun4os3)
+               basic_machine=sparc-sun
+               os=-sunos3
+               ;;
+       sun4os4)
+               basic_machine=sparc-sun
+               os=-sunos4
+               ;;
+       sun4sol2)
+               basic_machine=sparc-sun
+               os=-solaris2
+               ;;
+       sun3 | sun3-*)
+               basic_machine=m68k-sun
+               ;;
+       sun4)
+               basic_machine=sparc-sun
+               ;;
+       sun386 | sun386i | roadrunner)
+               basic_machine=i386-sun
+               ;;
+       symmetry)
+               basic_machine=i386-sequent
+               os=-dynix
+               ;;
+       tx39)
+               basic_machine=mipstx39-unknown
+               ;;
+       tx39el)
+               basic_machine=mipstx39el-unknown
+               ;;
+       tower | tower-32)
+               basic_machine=m68k-ncr
+               ;;
+       udi29k)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       ultra3)
+               basic_machine=a29k-nyu
+               os=-sym1
+               ;;
+       vaxv)
+               basic_machine=vax-dec
+               os=-sysv
+               ;;
+       vms)
+               basic_machine=vax-dec
+               os=-vms
+               ;;
+       vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+       vxworks960)
+               basic_machine=i960-wrs
+               os=-vxworks
+               ;;
+       vxworks68)
+               basic_machine=m68k-wrs
+               os=-vxworks
+               ;;
+       vxworks29k)
+               basic_machine=a29k-wrs
+               os=-vxworks
+               ;;
+       xmp)
+               basic_machine=xmp-cray
+               os=-unicos
+               ;;
+        xps | xps100)
+               basic_machine=xps100-honeywell
+               ;;
+       none)
+               basic_machine=none-none
+               os=-none
+               ;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+       mips)
+               if [ x$os = x-linux-gnu ]; then
+                       basic_machine=mips-unknown
+               else
+                       basic_machine=mips-mips
+               fi
+               ;;
+       romp)
+               basic_machine=romp-ibm
+               ;;
+       rs6000)
+               basic_machine=rs6000-ibm
+               ;;
+       vax)
+               basic_machine=vax-dec
+               ;;
+       pdp11)
+               basic_machine=pdp11-dec
+               ;;
+       we32k)
+               basic_machine=we32k-att
+               ;;
+       sparc)
+               basic_machine=sparc-sun
+               ;;
+        cydra)
+               basic_machine=cydra-cydrome
+               ;;
+       orion)
+               basic_machine=orion-highlevel
+               ;;
+       orion105)
+               basic_machine=clipper-highlevel
+               ;;
+       *)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+       *-digital*)
+               basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+               ;;
+       *-commodore*)
+               basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+               ;;
+       *)
+               ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+       # -solaris* is a basic system type, with this one exception.
+       -solaris1 | -solaris1.*)
+               os=`echo $os | sed -e 's|solaris1|sunos4|'`
+               ;;
+       -solaris)
+               os=-solaris2
+               ;;
+       -svr4*)
+               os=-sysv4
+               ;;
+       -unixware*)
+               os=-sysv4.2uw
+               ;;
+       -gnu/linux*)
+               os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+               ;;
+       # First accept the basic system types.
+       # The portable systems comes first.
+       # Each alternative MUST END IN A *, to match a version number.
+       # -sysv* is not here because it comes later, after sysvr4.
+       -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+             | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+             | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+             | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+             | -aos* \
+             | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+             | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+             | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+             | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
+             | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+             | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+             | -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+             | -mingw32* | -linux-gnu* | -uxpv*)
+       # Remember, each alternative MUST END IN *, to match a version number.
+               ;;
+       -linux*)
+               os=`echo $os | sed -e 's|linux|linux-gnu|'`
+               ;;
+       -sunos5*)
+               os=`echo $os | sed -e 's|sunos5|solaris2|'`
+               ;;
+       -sunos6*)
+               os=`echo $os | sed -e 's|sunos6|solaris3|'`
+               ;;
+       -osfrose*)
+               os=-osfrose
+               ;;
+       -osf*)
+               os=-osf
+               ;;
+       -utek*)
+               os=-bsd
+               ;;
+       -dynix*)
+               os=-bsd
+               ;;
+       -acis*)
+               os=-aos
+               ;;
+       -ctix* | -uts*)
+               os=-sysv
+               ;;
+       -ns2 )
+               os=-nextstep2
+               ;;
+       # Preserve the version number of sinix5.
+       -sinix5.*)
+               os=`echo $os | sed -e 's|sinix|sysv|'`
+               ;;
+       -sinix*)
+               os=-sysv4
+               ;;
+       -triton*)
+               os=-sysv3
+               ;;
+       -oss*)
+               os=-sysv3
+               ;;
+       -svr4)
+               os=-sysv4
+               ;;
+       -svr3)
+               os=-sysv3
+               ;;
+       -sysvr4)
+               os=-sysv4
+               ;;
+       # This must come after -sysvr4.
+       -sysv*)
+               ;;
+       -xenix)
+               os=-xenix
+               ;;
+       -none)
+               ;;
+       *)
+               # Get rid of the `-' at the beginning of $os.
+               os=`echo $os | sed 's/[^-]*-//'`
+               echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+       *-acorn)
+               os=-riscix1.2
+               ;;
+       arm*-semi)
+               os=-aout
+               ;;
+        pdp11-*)
+               os=-none
+               ;;
+       *-dec | vax-*)
+               os=-ultrix4.2
+               ;;
+       m68*-apollo)
+               os=-domain
+               ;;
+       i386-sun)
+               os=-sunos4.0.2
+               ;;
+       m68000-sun)
+               os=-sunos3
+               # This also exists in the configure program, but was not the
+               # default.
+               # os=-sunos4
+               ;;
+       *-tti)  # must be before sparc entry or we get the wrong os.
+               os=-sysv3
+               ;;
+       sparc-* | *-sun)
+               os=-sunos4.1.1
+               ;;
+       *-ibm)
+               os=-aix
+               ;;
+       *-hp)
+               os=-hpux
+               ;;
+       *-hitachi)
+               os=-hiux
+               ;;
+       i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+               os=-sysv
+               ;;
+       *-cbm)
+               os=-amigaos
+               ;;
+       *-dg)
+               os=-dgux
+               ;;
+       *-dolphin)
+               os=-sysv3
+               ;;
+       m68k-ccur)
+               os=-rtu
+               ;;
+       m88k-omron*)
+               os=-luna
+               ;;
+       *-next )
+               os=-nextstep
+               ;;
+       *-sequent)
+               os=-ptx
+               ;;
+       *-crds)
+               os=-unos
+               ;;
+       *-ns)
+               os=-genix
+               ;;
+       i370-*)
+               os=-mvs
+               ;;
+       *-next)
+               os=-nextstep3
+               ;;
+        *-gould)
+               os=-sysv
+               ;;
+        *-highlevel)
+               os=-bsd
+               ;;
+       *-encore)
+               os=-bsd
+               ;;
+        *-sgi)
+               os=-irix
+               ;;
+        *-siemens)
+               os=-sysv4
+               ;;
+       *-masscomp)
+               os=-rtu
+               ;;
+       f301-fujitsu)
+               os=-uxpv
+               ;;
+       *)
+               os=-none
+               ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+       *-unknown)
+               case $os in
+                       -riscix*)
+                               vendor=acorn
+                               ;;
+                       -sunos*)
+                               vendor=sun
+                               ;;
+                       -aix*)
+                               vendor=ibm
+                               ;;
+                       -hpux*)
+                               vendor=hp
+                               ;;
+                       -hiux*)
+                               vendor=hitachi
+                               ;;
+                       -unos*)
+                               vendor=crds
+                               ;;
+                       -dgux*)
+                               vendor=dg
+                               ;;
+                       -luna*)
+                               vendor=omron
+                               ;;
+                       -genix*)
+                               vendor=ns
+                               ;;
+                       -mvs*)
+                               vendor=ibm
+                               ;;
+                       -ptx*)
+                               vendor=sequent
+                               ;;
+                       -vxsim* | -vxworks*)
+                               vendor=wrs
+                               ;;
+                       -aux*)
+                               vendor=apple
+                               ;;
+               esac
+               basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+               ;;
+esac
+
+echo $basic_machine$os
diff --git a/configure.in b/configure.in
new file mode 100644 (file)
index 0000000..bb4f00b
--- /dev/null
@@ -0,0 +1,221 @@
+# Process this file with autoconf to produce a configure script.
+AC_INIT(glist.c)
+
+# Save this value here, since automake will set cflags later
+cflags_set=${CFLAGS+set}
+
+# Making releases:
+#   GLIB_MICRO_VERSION += 1;
+#   GLIB_INTERFACE_AGE += 1;
+#   GLIB_BINARY_AGE += 1;
+# if any functions have been added, set GLIB_INTERFACE_AGE to 0.
+# if backwards compatibility has been broken,
+# set GLIB_BINARY_AGE and GLIB_INTERFACE_AGE to 0.
+#
+GLIB_MAJOR_VERSION=1
+GLIB_MINOR_VERSION=1
+GLIB_MICRO_VERSION=0
+GLIB_INTERFACE_AGE=0
+GLIB_BINARY_AGE=0
+GLIB_VERSION=$GLIB_MAJOR_VERSION.$GLIB_MINOR_VERSION.$GLIB_MICRO_VERSION
+AC_SUBST(GLIB_VERSION)
+
+# libtool versioning
+LT_RELEASE=$GLIB_MAJOR_VERSION.$GLIB_MINOR_VERSION
+LT_CURRENT=`expr $GLIB_MICRO_VERSION - $GLIB_INTERFACE_AGE`
+LT_REVISION=$GLIB_INTERFACE_AGE
+LT_AGE=`expr $GLIB_BINARY_AGE - $GLIB_INTERFACE_AGE`
+AC_SUBST(LT_RELEASE)
+AC_SUBST(LT_CURRENT)
+AC_SUBST(LT_REVISION)
+AC_SUBST(LT_AGE)
+
+VERSION=$GLIB_VERSION
+PACKAGE=glib
+
+AM_INIT_AUTOMAKE($PACKAGE, $VERSION, no-define)
+
+# Specify a configuration file
+AM_CONFIG_HEADER(glibconfig.h)
+
+AC_DEFINE_UNQUOTED(GLIB_MAJOR_VERSION, $GLIB_MAJOR_VERSION)
+AC_DEFINE_UNQUOTED(GLIB_MINOR_VERSION, $GLIB_MINOR_VERSION)
+AC_DEFINE_UNQUOTED(GLIB_MICRO_VERSION, $GLIB_MICRO_VERSION)
+
+dnl Initialize libtool
+AM_PROG_LIBTOOL
+
+dnl Initialize maintainer mode
+AM_MAINTAINER_MODE
+
+AC_CANONICAL_HOST
+
+AC_ARG_ENABLE(debug, [  --enable-debug=[no/minimum/yes] turn on debugging [default=minimum]],,enable_debug=minimum)
+AC_ARG_ENABLE(mem_check, [  --enable-mem-check=[no/yes] turn on malloc/free sanity checking [default=no]],,enable_mem_check=no)
+AC_ARG_ENABLE(mem_profile, [  --enable-mem-profile=[no/yes] turn on malloc profiling atexit [default=no]],,enable_mem_profile=no)
+
+AC_ARG_ENABLE(ansi, [  --enable-ansi           turn on strict ansi [default=no]],
+                   , enable_ansi=no)
+
+echo -n "Enabling memory checking... "
+if test "x$enable_mem_check" = "xyes"; then
+  AC_DEFINE(ENABLE_MEM_CHECK, 1)
+  AC_SUBST(ENABLE_MEM_CHECK)
+  echo "yes"
+else
+  echo "no"
+fi
+
+echo -n "Enabling memory profiling... "
+if test "x$enable_mem_profile" = "xyes"; then
+  AC_DEFINE(ENABLE_MEM_PROFILE, 1)
+  AC_SUBST(ENABLE_MEM_PROFILE)
+  echo "yes"
+else
+  echo "no"
+fi
+
+if test "x$enable_debug" = "xyes"; then
+  test "$cflags_set" = set || CFLAGS="$CFLAGS -g"
+  CFLAGS="$CFLAGS -DG_ENABLE_DEBUG"
+else
+  if test "x$enable_debug" = "xno"; then
+    CFLAGS="$CFLAGS -DG_DISABLE_ASSERT -DG_DISABLE_CHECKS"
+  fi
+fi
+
+AC_DEFINE_UNQUOTED(G_COMPILED_WITH_DEBUGGING, "${enable_debug}")
+
+# Checks for programs.
+AC_PROG_CC
+AM_PROG_CC_STDC
+AC_PROG_INSTALL
+
+if eval "test x$GCC = xyes"; then
+  if eval test -z \"`echo "$CFLAGS" | grep "\-Wall" 2> /dev/null`\" ; then
+    CFLAGS="$CFLAGS -Wall"
+  fi
+
+  if eval "test x$enable_ansi = xyes"; then
+    if eval test -z \"`echo "$CFLAGS" | grep "\-ansi" 2> /dev/null`\" ; then
+      CFLAGS="$CFLAGS -ansi"
+    fi
+
+    if eval test -z \"`echo "$CFLAGS" | grep "\-pedantic" 2> /dev/null`\" ; then
+      CFLAGS="$CFLAGS -pedantic"
+    fi
+  fi
+fi
+
+# Checks for header files.
+AC_HEADER_STDC
+
+# Checks for library functions.
+AC_FUNC_VPRINTF
+
+AC_CHECK_FUNCS(atexit on_exit)
+
+AC_CHECK_SIZEOF(char)
+AC_CHECK_SIZEOF(short)
+AC_CHECK_SIZEOF(long)
+AC_CHECK_SIZEOF(int)
+AC_CHECK_SIZEOF(void *)
+
+# long doubles were not used, and a portability problem 
+# AC_C_LONG_DOUBLE
+AC_C_CONST
+AC_C_INLINE
+
+AC_CHECK_HEADERS(float.h, AC_DEFINE(HAVE_FLOAT_H))
+AC_CHECK_HEADERS(limits.h, AC_DEFINE(HAVE_LIMITS_H))
+AC_CHECK_HEADERS(values.h, AC_DEFINE(HAVE_VALUES_H))
+
+# Check for strerror, strsignal, memmove, vsnprintf, and strcasecmp functions
+AC_CHECK_FUNCS(strerror strsignal memmove vsnprintf strcasecmp)
+
+# Check for sys_errlist
+AC_MSG_CHECKING(sys_errlist)
+AC_TRY_LINK(, [
+extern char *sys_errlist[];
+extern int sys_nerr;
+sys_errlist[sys_nerr-1][0] = 0;
+], glib_ok=yes, glib_ok=no)
+AC_MSG_RESULT($glib_ok)
+if test $glib_ok = no; then
+    AC_DEFINE(NO_SYS_ERRLIST)
+fi
+
+# Check for sys_siglist
+AC_MSG_CHECKING(sys_siglist)
+AC_TRY_LINK(, [
+extern char *sys_siglist[];
+sys_siglist[1][0] = 0;
+], glib_ok=yes, glib_ok=no)
+AC_MSG_RESULT($glib_ok)
+if test $glib_ok = no; then
+    AC_DEFINE(NO_SYS_SIGLIST)
+fi
+
+# Check for sys/select.h
+
+AC_MSG_CHECKING([fd_set and sys/select])
+AC_TRY_COMPILE([#include <sys/types.h>],
+        [fd_set readMask, writeMask;], gtk_ok=yes, gtk_ok=no)
+if test $gtk_ok = no; then
+    AC_HEADER_EGREP(fd_mask, sys/select.h, gtk_ok=yes)
+    if test $gtk_ok = yes; then
+        AC_DEFINE(HAVE_SYS_SELECT_H)
+    fi
+fi
+AC_MSG_RESULT($gtk_ok)
+if test $gtk_ok = no; then
+    AC_DEFINE(NO_FD_SET)
+fi
+
+# This stuff is here, only so that we can define these
+# things in glibconfig.h. If ../config.h was installed
+# (under some other name?) then the definitions would
+# belong there. (They are only used in GDK)
+
+# Check for wchar.h
+
+AC_MSG_CHECKING(for wchar.h)
+AC_TRY_CPP([#include <wchar.h>], gtk_ok=yes, gtk_ok=no)
+if test $gtk_ok = yes; then
+   AC_DEFINE(HAVE_WCHAR_H)
+fi
+AC_MSG_RESULT($gtk_ok)
+
+# Check for wctype.h (for iswalnum)
+
+AC_MSG_CHECKING(for wctype.h)
+AC_TRY_CPP([#include <wctype.h>], gtk_ok=yes, gtk_ok=no)
+if test $gtk_ok = yes; then
+   AC_DEFINE(HAVE_WCTYPE_H)
+fi
+AC_MSG_RESULT($gtk_ok)
+
+# The following is necessary for Linux libc-5.4.38
+
+AC_MSG_CHECKING(if iswalnum() and friends are properly defined)
+AC_TRY_LINK([#include <stdlib.h>],[
+#if (defined(HAVE_WCTYPE_H) || defined(HAVE_WCHAR_H))
+#  ifdef HAVE_WCTYPE_H
+#    include <wctype.h>
+#  else
+#    ifdef HAVE_WCHAR_H
+#      include <wchar.h>
+#    endif
+#  endif
+#else
+#  define iswalnum(c) ((wchar_t)(c) <= 0xFF && isalnum(c))
+#endif
+iswalnum((wchar_t) 0);
+], gtk_ok=yes, gtk_ok=no)
+
+if test $gtk_ok = no; then
+   AC_DEFINE(HAVE_BROKEN_WCTYPE)
+fi
+AC_MSG_RESULT($gtk_ok)
+
+AC_OUTPUT([Makefile glib-config],[chmod +x glib-config])
diff --git a/garray.c b/garray.c
new file mode 100644 (file)
index 0000000..4d814a4
--- /dev/null
+++ b/garray.c
@@ -0,0 +1,143 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <string.h>
+#include "glib.h"
+
+
+#define MIN_ARRAY_SIZE  16
+
+
+typedef struct _GRealArray  GRealArray;
+
+struct _GRealArray
+{
+  guint8 *data;
+  guint   len;
+  guint   alloc;
+  guint   zero_terminated;
+};
+
+
+static gint g_nearest_pow        (gint        num);
+static void g_array_maybe_expand (GRealArray *array,
+                                 gint        len);
+
+
+static GMemChunk *array_mem_chunk = NULL;
+
+
+GArray*
+g_array_new (gint zero_terminated)
+{
+  GRealArray *array;
+
+  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);
+
+  array->data = NULL;
+  array->len = 0;
+  array->alloc = 0;
+  array->zero_terminated = (zero_terminated ? 1 : 0);
+
+  return (GArray*) array;
+}
+
+void
+g_array_free (GArray *array,
+             gint    free_segment)
+{
+  if (free_segment)
+    g_free (array->data);
+
+  g_mem_chunk_free (array_mem_chunk, array);
+}
+
+GArray*
+g_rarray_append (GArray   *array,
+                gpointer  data,
+                gint      size)
+{
+  g_array_maybe_expand ((GRealArray*) array, size);
+
+  memcpy (array->data + array->len, data, size);
+
+  array->len += size;
+
+  return array;
+}
+
+GArray*
+g_rarray_prepend (GArray   *array,
+                 gpointer  data,
+                 gint      size)
+{
+  g_array_maybe_expand ((GRealArray*) array, size);
+
+  g_memmove (array->data + size, array->data, array->len);
+  memcpy (array->data, data, size);
+
+  array->len += size;
+
+  return array;
+}
+
+GArray*
+g_rarray_truncate (GArray *array,
+                  gint    length,
+                  gint    size)
+{
+  if (array->data)
+    memset (array->data + length * size, 0, size);
+  array->len = length * size;
+  return array;
+}
+
+
+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 old_alloc;
+
+  if ((array->len + len) > array->alloc)
+    {
+      old_alloc = array->alloc;
+
+      array->alloc = g_nearest_pow (array->len + array->zero_terminated + len);
+      array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
+      array->data = g_realloc (array->data, array->alloc);
+
+      memset (array->data + old_alloc, 0, array->alloc - old_alloc);
+    }
+}
diff --git a/gbacktrace.c b/gbacktrace.c
new file mode 100644 (file)
index 0000000..1c4ce5c
--- /dev/null
@@ -0,0 +1,260 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <sys/types.h>
+
+#include <time.h>
+#include <unistd.h>
+#include "glib.h"
+
+#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
+
+#define INTERACTIVE 0
+#define STACK_TRACE 1
+
+
+#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 int  do_query (char *prompt);
+static void debug (const gchar *progname, int method);
+static void stack_trace (char **);
+static void stack_trace_sigchld (int);
+
+
+static int stack_trace_done;
+
+void
+g_debug (const gchar *progname)
+{
+  char buf[32];
+
+  fprintf (stdout, "[n]othing, [e]xit, [s]tack trace, [a]ttach to process: ");
+  fflush (stdout);
+
+  fgets (buf, 32, stdin);
+  if (strcmp (buf, "n\n") == 0)
+    return;
+  else if (strcmp (buf, "s\n") == 0)
+    debug (progname, STACK_TRACE);
+  else if (strcmp (buf, "a\n") == 0)
+    debug (progname, INTERACTIVE);
+  else
+    exit (0);
+}
+
+void
+g_attach_process (const gchar *progname,
+                 int          query)
+{
+  if (!query || do_query ("attach to process"))
+    debug (progname, INTERACTIVE);
+}
+
+void
+g_stack_trace (const gchar *progname,
+              int          query)
+{
+  if (!query || do_query ("print stack trace"))
+    debug (progname, STACK_TRACE);
+}
+
+static int
+do_query (char *prompt)
+{
+  char buf[32];
+
+  fprintf (stdout, "%s (y/n) ", prompt);
+  fflush (stdout);
+
+  fgets (buf, 32, stdin);
+  if ((strcmp (buf, "yes\n") == 0) ||
+      (strcmp (buf, "y\n") == 0) ||
+      (strcmp (buf, "YES\n") == 0) ||
+      (strcmp (buf, "Y\n") == 0))
+    return TRUE;
+
+  return FALSE;
+}
+
+static void
+debug (const char *progname,
+       int   method)
+{
+  pid_t pid;
+  char buf[16];
+  char *args[4] = { "gdb", NULL, NULL, NULL };
+  volatile int x;
+
+  sprintf (buf, "%d", (int) getpid ());
+
+  args[1] = (gchar*) progname;
+  args[2] = buf;
+
+  switch (method)
+    {
+    case INTERACTIVE:
+      fprintf (stdout, "pid: %s\n", buf);
+      break;
+    case STACK_TRACE:
+      pid = fork ();
+      if (pid == 0)
+       {
+         stack_trace (args);
+         _exit (0);
+       }
+      else if (pid == (pid_t) -1)
+       {
+         perror ("could not fork");
+         return;
+       }
+      break;
+    }
+
+  x = 1;
+  while (x)
+    ;
+}
+
+static void
+stack_trace (char **args)
+{
+  pid_t pid;
+  int in_fd[2];
+  int out_fd[2];
+  SELECT_MASK fdset;
+  SELECT_MASK readset;
+  struct timeval tv;
+  int sel, index, state;
+  char buffer[256];
+  char c;
+
+  stack_trace_done = 0;
+  signal (SIGCHLD, stack_trace_sigchld);
+
+  if ((pipe (in_fd) == -1) || (pipe (out_fd) == -1))
+    {
+      perror ("could 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 ("could not 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);
+}
+
+static void
+stack_trace_sigchld (int signum)
+{
+  stack_trace_done = 1;
+}
diff --git a/gcache.c b/gcache.c
new file mode 100644 (file)
index 0000000..b2fe779
--- /dev/null
+++ b/gcache.c
@@ -0,0 +1,212 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "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;
+
+
+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);
+
+  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;
+
+  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);
+
+  node->value = value;
+  node->ref_count = 1;
+
+  return node;
+}
+
+static void
+g_cache_node_destroy (GCacheNode *node)
+{
+  g_mem_chunk_free (node_mem_chunk, node);
+}
diff --git a/gcompletion.c b/gcompletion.c
new file mode 100644 (file)
index 0000000..947a6bd
--- /dev/null
@@ -0,0 +1,238 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "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;
+       if ( func )
+               gcomp->func = func;
+       else
+               gcomp->func = NULL;
+       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=NULL;
+       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;
+       }
+
+       if ( !(file=fopen(argv[1], "r")) ) {
+               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
diff --git a/gdataset.c b/gdataset.c
new file mode 100644 (file)
index 0000000..aef270c
--- /dev/null
@@ -0,0 +1,342 @@
+/* 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.
+ */
+#include       "glib.h"
+
+
+
+/* --- defines --- */
+#define        G_DATASET_ID_BLOCK_SIZE                 (1024)
+#define        G_DATASET_MEM_CHUNK_PREALLOC            (512)
+#define        G_DATASET_DATA_MEM_CHUNK_PREALLOC       (1024)
+
+
+/* --- structures --- */
+typedef struct _GDatasetData GDatasetData;
+typedef struct _GDataset GDataset;
+struct _GDatasetData
+{
+  GDatasetData *next;
+  guint id;
+  gpointer data;
+  GDestroyNotify destroy_func;
+};
+
+struct _GDataset
+{
+  gconstpointer location;
+  GDatasetData *data_list;
+};
+
+
+/* --- prototypes --- */
+static inline GDataset*        g_dataset_lookup        (gconstpointer dataset_location);
+static inline void     g_dataset_destroy_i     (GDataset     *dataset);
+static void            g_dataset_initialize    (void);
+static guint*          g_dataset_id_new        (void);
+
+
+/* --- variables --- */
+static GHashTable *g_dataset_location_ht = NULL;
+static GHashTable *g_dataset_key_ht = NULL;
+static GDataset *g_dataset_cached = NULL;
+static GMemChunk *g_dataset_mem_chunk = NULL;
+static GMemChunk *g_dataset_data_mem_chunk = NULL;
+static guint *g_dataset_id_block = NULL;
+static guint g_dataset_id_index = G_DATASET_ID_BLOCK_SIZE + 1;
+
+
+/* --- functions --- */
+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;
+  
+  if (!g_dataset_location_ht)
+    g_dataset_initialize ();
+  
+  dataset = g_hash_table_lookup (g_dataset_location_ht, dataset_location);
+  if (dataset)
+    g_dataset_cached = dataset;
+  
+  return dataset;
+}
+
+static inline void
+g_dataset_destroy_i (GDataset *dataset)
+{
+  register GDatasetData *list;
+  
+  if (dataset == g_dataset_cached)
+    g_dataset_cached = NULL;
+  g_hash_table_remove (g_dataset_location_ht, dataset->location);
+  
+  list = dataset->data_list;
+  g_mem_chunk_free (g_dataset_mem_chunk, dataset);
+  
+  while (list)
+    {
+      register GDatasetData *prev;
+      
+      prev = list;
+      list = prev->next;
+      
+      if (prev->destroy_func)
+       prev->destroy_func (prev->data);
+      
+      g_mem_chunk_free (g_dataset_data_mem_chunk, prev);
+    }
+}
+
+void
+g_dataset_destroy (gconstpointer  dataset_location)
+{
+  register GDataset *dataset;
+  
+  g_return_if_fail (dataset_location != NULL);
+  
+  dataset = g_dataset_lookup (dataset_location);
+  if (dataset)
+    g_dataset_destroy_i (dataset);
+}
+
+void
+g_dataset_id_set_destroy (gconstpointer  dataset_location,
+                         guint          key_id,
+                         GDestroyNotify destroy_func)
+{
+  g_return_if_fail (dataset_location != NULL);
+  
+  if (key_id)
+    {
+      register GDataset *dataset;
+      
+      dataset = g_dataset_lookup (dataset_location);
+      if (dataset)
+       {
+         register GDatasetData *list;
+         
+         list = dataset->data_list;
+         while (list)
+           {
+             if (list->id == key_id)
+               {
+                 list->destroy_func = destroy_func;
+                 return;
+               }
+           }
+       }
+    }
+}
+
+gpointer
+g_dataset_id_get_data (gconstpointer  dataset_location,
+                      guint          key_id)
+{
+  g_return_val_if_fail (dataset_location != NULL, NULL);
+  
+  if (key_id)
+    {
+      register GDataset *dataset;
+      
+      dataset = g_dataset_lookup (dataset_location);
+      if (dataset)
+       {
+         register GDatasetData *list;
+         
+         for (list = dataset->data_list; list; list = list->next)
+           if (list->id == key_id)
+             return list->data;
+       }
+    }
+  
+  return NULL;
+}
+
+void
+g_dataset_id_set_data_full (gconstpointer  dataset_location,
+                           guint          key_id,
+                           gpointer       data,
+                           GDestroyNotify destroy_func)
+{
+  register GDataset *dataset;
+  register GDatasetData *list;
+  
+  g_return_if_fail (dataset_location != NULL);
+  g_return_if_fail (key_id > 0);
+  
+  dataset = g_dataset_lookup (dataset_location);
+  if (!dataset)
+    {
+      dataset = g_chunk_new (GDataset, g_dataset_mem_chunk);
+      dataset->location = dataset_location;
+      dataset->data_list = NULL;
+      g_hash_table_insert (g_dataset_location_ht, 
+                          (gpointer) dataset->location, /* Yuck */
+                          dataset);
+    }
+  
+  list = dataset->data_list;
+  if (!data)
+    {
+      register GDatasetData *prev;
+      
+      prev = NULL;
+      while (list)
+       {
+         if (list->id == key_id)
+           {
+             if (prev)
+               prev->next = list->next;
+             else
+               {
+                 dataset->data_list = list->next;
+                 
+                 if (!dataset->data_list)
+                   g_dataset_destroy_i (dataset);
+               }
+             
+             /* we need to have unlinked before invoking the destroy function
+              */
+             if (list->destroy_func)
+               list->destroy_func (list->data);
+             
+             g_mem_chunk_free (g_dataset_data_mem_chunk, list);
+             break;
+           }
+         
+         prev = list;
+         list = list->next;
+       }
+    }
+  else
+    {
+      register GDatasetData *prev;
+      
+      prev = NULL;
+      while (list)
+       {
+         if (list->id == key_id)
+           {
+             if (prev)
+               prev->next = list->next;
+             else
+               dataset->data_list = list->next;
+             
+             /* we need to have unlinked before invoking the destroy function
+              */
+             if (list->destroy_func)
+               list->destroy_func (list->data);
+             
+             break;
+           }
+         
+         prev = list;
+         list = list->next;
+       }
+      
+      if (!list)
+       list = g_chunk_new (GDatasetData, g_dataset_data_mem_chunk);
+      list->next = dataset->data_list;
+      list->id = key_id;
+      list->data = data;
+      list->destroy_func = destroy_func;
+      dataset->data_list = list;
+    }
+}
+
+guint
+g_dataset_try_key (const gchar    *key)
+{
+  register guint *id;
+  g_return_val_if_fail (key != NULL, 0);
+  
+  if (g_dataset_key_ht)
+    {
+      id = g_hash_table_lookup (g_dataset_key_ht, (gpointer) key);
+      
+      if (id)
+       return *id;
+    }
+  
+  return 0;
+}
+
+guint
+g_dataset_force_id (const gchar    *key)
+{
+  register guint *id;
+  
+  g_return_val_if_fail (key != NULL, 0);
+  
+  if (!g_dataset_key_ht)
+    g_dataset_initialize ();
+  
+  id = g_hash_table_lookup (g_dataset_key_ht, (gpointer) key);
+  if (!id)
+    {
+      id = g_dataset_id_new ();
+      g_hash_table_insert (g_dataset_key_ht, g_strdup (key), id);
+    }
+  
+  return *id;
+}
+
+static void
+g_dataset_initialize (void)
+{
+  if (!g_dataset_location_ht)
+    {
+      g_dataset_location_ht = g_hash_table_new (g_direct_hash, NULL);
+      g_dataset_key_ht = g_hash_table_new (g_str_hash, g_str_equal);
+      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_dataset_data_mem_chunk =
+       g_mem_chunk_new ("GDatasetData MemChunk",
+                        sizeof (GDatasetData),
+                        sizeof (GDatasetData) * G_DATASET_DATA_MEM_CHUNK_PREALLOC,
+                        G_ALLOC_AND_FREE);
+    }
+}
+
+static guint*
+g_dataset_id_new (void)
+{
+  static guint seq_id = 1;
+  register guint *id;
+  
+  if (g_dataset_id_index >= G_DATASET_ID_BLOCK_SIZE)
+    {
+      g_dataset_id_block = g_new (guint, G_DATASET_ID_BLOCK_SIZE);
+      g_dataset_id_index = 0;
+    }
+  
+  id = &g_dataset_id_block[g_dataset_id_index++];
+  *id = seq_id++;
+  
+  return id;
+}
diff --git a/gerror.c b/gerror.c
new file mode 100644 (file)
index 0000000..1c4ce5c
--- /dev/null
+++ b/gerror.c
@@ -0,0 +1,260 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <sys/types.h>
+
+#include <time.h>
+#include <unistd.h>
+#include "glib.h"
+
+#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
+
+#define INTERACTIVE 0
+#define STACK_TRACE 1
+
+
+#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 int  do_query (char *prompt);
+static void debug (const gchar *progname, int method);
+static void stack_trace (char **);
+static void stack_trace_sigchld (int);
+
+
+static int stack_trace_done;
+
+void
+g_debug (const gchar *progname)
+{
+  char buf[32];
+
+  fprintf (stdout, "[n]othing, [e]xit, [s]tack trace, [a]ttach to process: ");
+  fflush (stdout);
+
+  fgets (buf, 32, stdin);
+  if (strcmp (buf, "n\n") == 0)
+    return;
+  else if (strcmp (buf, "s\n") == 0)
+    debug (progname, STACK_TRACE);
+  else if (strcmp (buf, "a\n") == 0)
+    debug (progname, INTERACTIVE);
+  else
+    exit (0);
+}
+
+void
+g_attach_process (const gchar *progname,
+                 int          query)
+{
+  if (!query || do_query ("attach to process"))
+    debug (progname, INTERACTIVE);
+}
+
+void
+g_stack_trace (const gchar *progname,
+              int          query)
+{
+  if (!query || do_query ("print stack trace"))
+    debug (progname, STACK_TRACE);
+}
+
+static int
+do_query (char *prompt)
+{
+  char buf[32];
+
+  fprintf (stdout, "%s (y/n) ", prompt);
+  fflush (stdout);
+
+  fgets (buf, 32, stdin);
+  if ((strcmp (buf, "yes\n") == 0) ||
+      (strcmp (buf, "y\n") == 0) ||
+      (strcmp (buf, "YES\n") == 0) ||
+      (strcmp (buf, "Y\n") == 0))
+    return TRUE;
+
+  return FALSE;
+}
+
+static void
+debug (const char *progname,
+       int   method)
+{
+  pid_t pid;
+  char buf[16];
+  char *args[4] = { "gdb", NULL, NULL, NULL };
+  volatile int x;
+
+  sprintf (buf, "%d", (int) getpid ());
+
+  args[1] = (gchar*) progname;
+  args[2] = buf;
+
+  switch (method)
+    {
+    case INTERACTIVE:
+      fprintf (stdout, "pid: %s\n", buf);
+      break;
+    case STACK_TRACE:
+      pid = fork ();
+      if (pid == 0)
+       {
+         stack_trace (args);
+         _exit (0);
+       }
+      else if (pid == (pid_t) -1)
+       {
+         perror ("could not fork");
+         return;
+       }
+      break;
+    }
+
+  x = 1;
+  while (x)
+    ;
+}
+
+static void
+stack_trace (char **args)
+{
+  pid_t pid;
+  int in_fd[2];
+  int out_fd[2];
+  SELECT_MASK fdset;
+  SELECT_MASK readset;
+  struct timeval tv;
+  int sel, index, state;
+  char buffer[256];
+  char c;
+
+  stack_trace_done = 0;
+  signal (SIGCHLD, stack_trace_sigchld);
+
+  if ((pipe (in_fd) == -1) || (pipe (out_fd) == -1))
+    {
+      perror ("could 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 ("could not 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);
+}
+
+static void
+stack_trace_sigchld (int signum)
+{
+  stack_trace_done = 1;
+}
diff --git a/ghash.c b/ghash.c
new file mode 100644 (file)
index 0000000..ceee098
--- /dev/null
+++ b/ghash.c
@@ -0,0 +1,426 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "glib.h"
+
+
+#define HASH_TABLE_MIN_SIZE 11
+#define HASH_TABLE_MAX_SIZE 13845163
+
+
+typedef struct _GHashNode      GHashNode;
+typedef struct _GRealHashTable GRealHashTable;
+
+struct _GHashNode
+{
+  gpointer key;
+  gpointer value;
+  GHashNode *next;
+};
+
+struct _GRealHashTable
+{
+  gint size;
+  gint nnodes;
+  gint frozen;
+  GHashNode **nodes;
+  GHashFunc hash_func;
+  GCompareFunc key_compare_func;
+};
+
+
+static void       g_hash_table_resize  (GHashTable *hash_table);
+static gint       g_hash_closest_prime (gint        num);
+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);
+
+
+extern gint g_primes[];
+extern gint g_nprimes;
+
+static GMemChunk *node_mem_chunk = NULL;
+static GHashNode *node_free_list = NULL;
+
+
+GHashTable*
+g_hash_table_new (GHashFunc    hash_func,
+                 GCompareFunc key_compare_func)
+{
+  GRealHashTable *hash_table;
+
+  g_return_val_if_fail (hash_func != NULL, NULL);
+
+  hash_table = g_new (GRealHashTable, 1);
+  hash_table->size = 0;
+  hash_table->nnodes = 0;
+  hash_table->frozen = FALSE;
+  hash_table->nodes = NULL;
+  hash_table->hash_func = hash_func;
+  hash_table->key_compare_func = key_compare_func;
+
+  return ((GHashTable*) hash_table);
+}
+
+void
+g_hash_table_destroy (GHashTable *hash_table)
+{
+  GRealHashTable *rhash_table;
+  gint i;
+
+  if (hash_table)
+    {
+      rhash_table = (GRealHashTable*) hash_table;
+
+      for (i = 0; i < rhash_table->size; i++)
+       g_hash_nodes_destroy (rhash_table->nodes[i]);
+
+      if (rhash_table->nodes)
+       g_free (rhash_table->nodes);
+      g_free (rhash_table);
+    }
+}
+
+void
+g_hash_table_insert (GHashTable *hash_table,
+                    gpointer    key,
+                    gpointer    value)
+{
+  GRealHashTable *rhash_table;
+  GHashNode *node;
+  guint hash_val;
+
+  if (hash_table)
+    {
+      rhash_table = (GRealHashTable*) hash_table;
+
+      if (rhash_table->size == 0)
+       g_hash_table_resize (hash_table);
+
+      hash_val = (* rhash_table->hash_func) (key) % rhash_table->size;
+
+      node = rhash_table->nodes[hash_val];
+      while (node)
+       {
+         if ((rhash_table->key_compare_func &&
+              (* rhash_table->key_compare_func) (node->key, key)) ||
+             (node->key == key))
+           {
+             /* 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;
+             return;
+           }
+         node = node->next;
+       }
+
+      node = g_hash_node_new (key, value);
+      node->next = rhash_table->nodes[hash_val];
+      rhash_table->nodes[hash_val] = node;
+
+      rhash_table->nnodes += 1;
+      g_hash_table_resize (hash_table);
+    }
+}
+
+void
+g_hash_table_remove (GHashTable      *hash_table,
+                    gconstpointer    key)
+{
+  GRealHashTable *rhash_table;
+  GHashNode *node;
+  GHashNode *prev;
+  guint hash_val;
+
+  rhash_table = (GRealHashTable*) hash_table;
+  if (hash_table && rhash_table->size)
+    {
+      hash_val = (* rhash_table->hash_func) (key) % rhash_table->size;
+
+      prev = NULL;
+      node = rhash_table->nodes[hash_val];
+
+      while (node)
+       {
+         if ((rhash_table->key_compare_func &&
+              (* rhash_table->key_compare_func) (node->key, key)) ||
+             (node->key == key))
+           {
+             if (prev)
+               prev->next = node->next;
+             if (node == rhash_table->nodes[hash_val])
+               rhash_table->nodes[hash_val] = node->next;
+
+             g_hash_node_destroy (node);
+
+             rhash_table->nnodes -= 1;
+             g_hash_table_resize (hash_table);
+             break;
+           }
+
+         prev = node;
+         node = node->next;
+       }
+    }
+}
+
+gpointer
+g_hash_table_lookup (GHashTable   *hash_table,
+                    gconstpointer key)
+{
+  GRealHashTable *rhash_table;
+  GHashNode *node;
+  guint hash_val;
+
+  rhash_table = (GRealHashTable*) hash_table;
+  if (hash_table && rhash_table->size)
+    {
+      hash_val = (* rhash_table->hash_func) (key) % rhash_table->size;
+
+      node = rhash_table->nodes[hash_val];
+
+      /* 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 (rhash_table->key_compare_func)
+       {
+         while (node)
+           {
+             if ((* rhash_table->key_compare_func) (node->key, key))
+               return node->value;
+             node = node->next;
+           }
+       }
+      else
+       {
+         while (node)
+           {
+             if (node->key == key)
+               return node->value;
+             node = node->next;
+           }
+       }
+    }
+
+  return NULL;
+}
+
+void
+g_hash_table_freeze (GHashTable *hash_table)
+{
+  GRealHashTable *rhash_table;
+
+  if (hash_table)
+    {
+      rhash_table = (GRealHashTable*) hash_table;
+      rhash_table->frozen = TRUE;
+    }
+}
+
+void
+g_hash_table_thaw (GHashTable *hash_table)
+{
+  GRealHashTable *rhash_table;
+
+  if (hash_table)
+    {
+      rhash_table = (GRealHashTable*) hash_table;
+      rhash_table->frozen = FALSE;
+
+      g_hash_table_resize (hash_table);
+    }
+}
+
+void
+g_hash_table_foreach (GHashTable *hash_table,
+                     GHFunc      func,
+                     gpointer    user_data)
+{
+  GRealHashTable *rhash_table;
+  GHashNode *node;
+  gint i;
+
+  if (hash_table)
+    {
+      rhash_table = (GRealHashTable*) hash_table;
+
+      for (i = 0; i < rhash_table->size; i++)
+       {
+         node = rhash_table->nodes[i];
+
+         while (node)
+           {
+             (* func) (node->key, node->value, user_data);
+             node = node->next;
+           }
+       }
+    }
+}
+
+
+static void
+g_hash_table_resize (GHashTable *hash_table)
+{
+  GRealHashTable *rhash_table;
+  GHashNode **new_nodes;
+  GHashNode *node;
+  GHashNode *next;
+  gfloat nodes_per_list;
+  guint hash_val;
+  gint new_size;
+  gint need_resize;
+  gint i;
+
+  if (hash_table)
+    {
+      rhash_table = (GRealHashTable*) hash_table;
+
+      if (rhash_table->size == 0)
+       {
+         rhash_table->size = HASH_TABLE_MIN_SIZE;
+         rhash_table->nodes = g_new (GHashNode*, rhash_table->size);
+
+         for (i = 0; i < rhash_table->size; i++)
+           rhash_table->nodes[i] = NULL;
+       }
+      else if (!rhash_table->frozen)
+       {
+         need_resize = FALSE;
+         nodes_per_list = (gfloat) rhash_table->nnodes / (gfloat) rhash_table->size;
+
+         if (nodes_per_list < 0.3)
+           {
+             if (rhash_table->size > HASH_TABLE_MIN_SIZE)
+               need_resize = TRUE;
+           }
+         else if (nodes_per_list > 3.0)
+           {
+             if (rhash_table->size < HASH_TABLE_MAX_SIZE)
+               need_resize = TRUE;
+           }
+
+         if (need_resize)
+           {
+             new_size = g_hash_closest_prime (rhash_table->nnodes);
+             if (new_size < HASH_TABLE_MIN_SIZE)
+               new_size = HASH_TABLE_MIN_SIZE;
+             else if (new_size > HASH_TABLE_MAX_SIZE)
+               new_size = HASH_TABLE_MAX_SIZE;
+
+             new_nodes = g_new (GHashNode*, new_size);
+
+             for (i = 0; i < new_size; i++)
+               new_nodes[i] = NULL;
+
+             for (i = 0; i < rhash_table->size; i++)
+               {
+                 node = rhash_table->nodes[i];
+
+                 while (node)
+                   {
+                     next = node->next;
+
+                     hash_val = (* rhash_table->hash_func) (node->key) % new_size;
+                     node->next = new_nodes[hash_val];
+                     new_nodes[hash_val] = node;
+
+                     node = next;
+                   }
+               }
+
+             g_free (rhash_table->nodes);
+
+             rhash_table->nodes = new_nodes;
+             rhash_table->size = new_size;
+           }
+       }
+    }
+}
+
+static gint
+g_hash_closest_prime (gint num)
+{
+  gint i;
+
+  for (i = 0; i < g_nprimes; i++)
+    if ((g_primes[i] - num) > 0)
+      return g_primes[i];
+
+  return g_primes[g_nprimes - 1];
+}
+
+static GHashNode*
+g_hash_node_new (gpointer key,
+                gpointer value)
+{
+  GHashNode *hash_node;
+
+  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);
+    }
+
+  hash_node->key = key;
+  hash_node->value = value;
+  hash_node->next = NULL;
+
+  return hash_node;
+}
+
+static void
+g_hash_node_destroy (GHashNode *hash_node)
+{
+  if (hash_node)
+    {
+      hash_node->next = node_free_list;
+      node_free_list = hash_node;
+    }
+}
+
+static void
+g_hash_nodes_destroy (GHashNode *hash_node)
+{
+  GHashNode *node;
+
+  if (hash_node)
+    {
+      node = hash_node;
+      while (node->next)
+       node = node->next;
+      node->next = node_free_list;
+      node_free_list = hash_node;
+    }
+}
diff --git a/glib-config b/glib-config
new file mode 100755 (executable)
index 0000000..3ed07a0
--- /dev/null
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+prefix=/usr/local
+exec_prefix=${prefix}
+exec_prefix_set=no
+
+usage="\
+Usage: glib-config [--prefix[=DIR]] [--exec-prefix[=DIR]] [--version] [--libs] [--cflags]"
+
+if test $# -eq 0; then
+      echo "${usage}" 1>&2
+      exit 1
+fi
+
+while test $# -gt 0; do
+  case "$1" in
+  -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  case $1 in
+    --prefix=*)
+      prefix=$optarg
+      if test $exec_prefix_set = no ; then
+        exec_prefix=$optarg
+      fi
+      ;;
+    --prefix)
+      echo $prefix
+      ;;
+    --exec-prefix=*)
+      exec_prefix=$optarg
+      exec_prefix_set=yes
+      ;;
+    --exec-prefix)
+      echo $exec_prefix
+      ;;
+    --version)
+      echo 1.1.0
+      ;;
+    --cflags)
+      if test ${prefix}/include != /usr/include ; then
+        includes=-I${prefix}/include
+      fi
+      echo -I${exec_prefix}/lib/glib/include $includes
+      ;;
+    --libs)
+      echo -L${exec_prefix}/lib -lglib-1.1
+      ;;
+    *)
+      echo "${usage}" 1>&2
+      exit 1
+      ;;
+  esac
+  shift
+done
+
diff --git a/glib-config.in b/glib-config.in
new file mode 100644 (file)
index 0000000..ad92c6f
--- /dev/null
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+exec_prefix_set=no
+
+usage="\
+Usage: glib-config [--prefix[=DIR]] [--exec-prefix[=DIR]] [--version] [--libs] [--cflags]"
+
+if test $# -eq 0; then
+      echo "${usage}" 1>&2
+      exit 1
+fi
+
+while test $# -gt 0; do
+  case "$1" in
+  -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  case $1 in
+    --prefix=*)
+      prefix=$optarg
+      if test $exec_prefix_set = no ; then
+        exec_prefix=$optarg
+      fi
+      ;;
+    --prefix)
+      echo $prefix
+      ;;
+    --exec-prefix=*)
+      exec_prefix=$optarg
+      exec_prefix_set=yes
+      ;;
+    --exec-prefix)
+      echo $exec_prefix
+      ;;
+    --version)
+      echo @GLIB_VERSION@
+      ;;
+    --cflags)
+      if test @includedir@ != /usr/include ; then
+        includes=-I@includedir@
+      fi
+      echo -I@libdir@/glib/include $includes
+      ;;
+    --libs)
+      echo -L@libdir@ -lglib-@LT_RELEASE@
+      ;;
+    *)
+      echo "${usage}" 1>&2
+      exit 1
+      ;;
+  esac
+  shift
+done
+
diff --git a/glib.m4 b/glib.m4
new file mode 100644 (file)
index 0000000..ee94b59
--- /dev/null
+++ b/glib.m4
@@ -0,0 +1,183 @@
+# Configure paths for GLIB
+# Owen Taylor     97-11-3
+
+dnl AM_PATH_GLIB([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+dnl Test for GTK, and define GLIB_CFLAGS and GLIB_LIBS
+dnl
+AC_DEFUN(AM_PATH_GLIB,
+[dnl 
+dnl Get the cflags and libraries from the glib-config script
+dnl
+AC_ARG_WITH(glib-prefix,[  --with-glib-prefix=PFX   Prefix where GLIB is installed (optional)],
+            glib_config_prefix="$withval", glib_config_prefix="")
+AC_ARG_WITH(glib-exec-prefix,[  --with-glib-exec-prefix=PFX Exec prefix where GLIB is installed (optional)],
+            glib_config_exec_prefix="$withval", glib_config_exec_prefix="")
+AC_ARG_ENABLE(glibtest, [  --disable-glibtest       Do not try to compile and run a test GLIB program],
+                   , enable_glibtest=yes)
+
+  if test x$glib_config_exec_prefix != x ; then
+     glib_config_args="$glib_config_args --exec-prefix=$glib_config_exec_prefix"
+     if test x${GLIB_CONFIG+set} != xset ; then
+        GLIB_CONFIG=$glib_config_exec_prefix/bin/glib-config
+     fi
+  fi
+  if test x$glib_config_prefix != x ; then
+     glib_config_args="$glib_config_args --prefix=$glib_config_prefix"
+     if test x${GLIB_CONFIG+set} != xset ; then
+        GLIB_CONFIG=$glib_config_prefix/bin/glib-config
+     fi
+  fi
+
+  AC_PATH_PROG(GLIB_CONFIG, glib-config, no)
+  min_glib_version=ifelse([$1], ,0.99.7,$1)
+  AC_MSG_CHECKING(for GLIB - version >= $min_glib_version)
+  no_glib=""
+  if test "$GLIB_CONFIG" = "no" ; then
+    no_glib=yes
+  else
+    GLIB_CFLAGS=`$GLIB_CONFIG $glib_config_args --cflags`
+    GLIB_LIBS=`$GLIB_CONFIG $glib_config_args --libs`
+    glib_config_major_version=`$GLIB_CONFIG $glib_config_args --version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+    glib_config_minor_version=`$GLIB_CONFIG $glib_config_args --version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+    glib_config_micro_version=`$GLIB_CONFIG $glib_config_args --version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+    if test "x$enable_glibtest" = "xyes" ; then
+      ac_save_CFLAGS="$CFLAGS"
+      ac_save_LIBS="$LIBS"
+      CFLAGS="$CFLAGS $GLIB_CFLAGS"
+      LIBS="$LIBS $GLIB_LIBS"
+dnl
+dnl Now check if the installed GLIB is sufficiently new. (Also sanity
+dnl checks the results of glib-config to some extent
+dnl
+      rm -f conf.glibtest
+      AC_TRY_RUN([
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int 
+main ()
+{
+  int major, minor, micro;
+  char *tmp_version;
+
+  system ("touch conf.glibtest");
+
+  /* HP/UX 9 (%@#!) writes to sscanf strings */
+  tmp_version = g_strdup("$min_glib_version");
+  if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
+     printf("%s, bad version string\n", "$min_glib_version");
+     exit(1);
+   }
+
+  if ((glib_major_version != $glib_config_major_version) ||
+      (glib_minor_version != $glib_config_minor_version) ||
+      (glib_micro_version != $glib_config_micro_version))
+    {
+      printf("\n*** 'glib-config --version' returned %d.%d.%d, but GLIB (%d.%d.%d)\n", 
+             $glib_config_major_version, $glib_config_minor_version, $glib_config_micro_version,
+             glib_major_version, glib_minor_version, glib_micro_version);
+      printf ("*** was found! If glib-config was correct, then it is best\n");
+      printf ("*** to remove the old version of GLIB. You may also be able to fix the error\n");
+      printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n");
+      printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n");
+      printf("*** required on your system.\n");
+      printf("*** If glib-config was wrong, set the environment variable GLIB_CONFIG\n");
+      printf("*** to point to the correct copy of glib-config, and remove the file config.cache\n");
+      printf("*** before re-running configure\n");
+    } 
+  else if ((glib_major_version != GLIB_MAJOR_VERSION) ||
+          (glib_minor_version != GLIB_MINOR_VERSION) ||
+           (glib_micro_version != GLIB_MICRO_VERSION))
+    {
+      printf("*** GLIB header files (version %d.%d.%d) do not match\n",
+            GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION);
+      printf("*** library (version %d.%d.%d)\n",
+            glib_major_version, glib_minor_version, glib_micro_version);
+    }
+  else
+    {
+      if ((glib_major_version > major) ||
+        ((glib_major_version == major) && (glib_minor_version > minor)) ||
+        ((glib_major_version == major) && (glib_minor_version == minor) && (glib_micro_version >= micro)))
+      {
+        return 0;
+       }
+     else
+      {
+        printf("\n*** An old version of GLIB (%d.%d.%d) was found.\n",
+               glib_major_version, glib_minor_version, glib_micro_version);
+        printf("*** You need a version of GLIB newer than %d.%d.%d. The latest version of\n",
+              major, minor, micro);
+        printf("*** GLIB is always available from ftp://ftp.glib.org.\n");
+        printf("***\n");
+        printf("*** If you have already installed a sufficiently new version, this error\n");
+        printf("*** probably means that the wrong copy of the glib-config shell script is\n");
+        printf("*** being found. The easiest way to fix this is to remove the old version\n");
+        printf("*** of GLIB, but you can also set the GLIB_CONFIG environment to point to the\n");
+        printf("*** correct copy of glib-config. (In this case, you will have to\n");
+        printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
+        printf("*** so that the correct libraries are found at run-time))\n");
+      }
+    }
+  return 1;
+}
+],, no_glib=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
+       CFLAGS="$ac_save_CFLAGS"
+       LIBS="$ac_save_LIBS"
+     fi
+  fi
+  if test "x$no_glib" = x ; then
+     AC_MSG_RESULT(yes)
+     ifelse([$2], , :, [$2])     
+  else
+     AC_MSG_RESULT(no)
+     if test "$GLIB_CONFIG" = "no" ; then
+       echo "*** The glib-config script installed by GLIB could not be found"
+       echo "*** If GLIB was installed in PREFIX, make sure PREFIX/bin is in"
+       echo "*** your path, or set the GLIB_CONFIG environment variable to the"
+       echo "*** full path to glib-config."
+     else
+       if test -f conf.glibtest ; then
+        :
+       else
+          echo "*** Could not run GLIB test program, checking why..."
+          CFLAGS="$CFLAGS $GLIB_CFLAGS"
+          LIBS="$LIBS $GLIB_LIBS"
+          AC_TRY_LINK([
+#include <glib/glib.h>
+#include <stdio.h>
+],      [ return ((glib_major_version) || (glib_minor_version) || (glib_micro_version)); ],
+        [ echo "*** The test program compiled, but did not run. This usually means"
+          echo "*** that the run-time linker is not finding GLIB or finding the wrong"
+          echo "*** version of GLIB. If it is not finding GLIB, you'll need to set your"
+          echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
+          echo "*** to the installed location  Also, make sure you have run ldconfig if that"
+          echo "*** is required on your system"
+         echo "***"
+          echo "*** If you have an old version installed, it is best to remove it, although"
+          echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"
+          echo "***"
+          echo "*** If you have a RedHat 5.0 system, you should remove the GTK package that"
+          echo "*** came with the system with the command"
+          echo "***"
+          echo "***    rpm --erase --nodeps gtk gtk-devel" ],
+        [ echo "*** The test program failed to compile or link. See the file config.log for the"
+          echo "*** exact error that occured. This usually means GLIB was incorrectly installed"
+          echo "*** or that you have moved GLIB since it was installed. In the latter case, you"
+          echo "*** may want to edit the glib-config script: $GLIB_CONFIG" ])
+          CFLAGS="$ac_save_CFLAGS"
+          LIBS="$ac_save_LIBS"
+       fi
+     fi
+     GLIB_CFLAGS=""
+     GLIB_LIBS=""
+     ifelse([$3], , :, [$3])
+  fi
+  AC_SUBST(GLIB_CFLAGS)
+  AC_SUBST(GLIB_LIBS)
+  rm -f conf.glibtest
+])
diff --git a/glib/Makefile.am b/glib/Makefile.am
new file mode 100644 (file)
index 0000000..84f5635
--- /dev/null
@@ -0,0 +1,54 @@
+## Process this file with automake to produce Makefile.in
+
+configincludedir = $(pkglibdir)/include
+
+bin_SCRIPTS=glib-config
+
+EXTRA_DIST =   \
+               glib.m4
+
+lib_LTLIBRARIES = libglib-1.1.la
+
+libglib_1_1_la_SOURCES = \
+               garray.c        \
+               gcache.c        \
+               gcompletion.c   \
+               gdataset.c      \
+               gerror.c        \
+               ghash.c         \
+               glist.c         \
+               gmem.c          \
+               gmessages.c     \
+               gprimes.c       \
+               gslist.c        \
+               gtimer.c        \
+               gtree.c         \
+               gstring.c       \
+               gscanner.c      \
+               gutils.c
+
+include_HEADERS = \
+               glib.h
+
+configinclude_DATA = \
+               glibconfig.h
+
+libglib_1_1_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
+
+INCLUDES = -I$(top_srcdir)
+
+noinst_PROGRAMS = testglib
+testglib_LDADD = libglib-@LT_RELEASE@.la
+
+m4datadir = $(datadir)/aclocal
+m4data_DATA = glib.m4
+
+.PHONY: files release
+
+files:
+       @files=`ls $(DISTFILES) 2> /dev/null `; for p in $$files; do \
+         echo $$p; \
+       done
+
+release:
+       $(MAKE) dist distdir=$(PACKAGE)`date +"%y%m%d"`
diff --git a/glib/garray.c b/glib/garray.c
new file mode 100644 (file)
index 0000000..4d814a4
--- /dev/null
@@ -0,0 +1,143 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <string.h>
+#include "glib.h"
+
+
+#define MIN_ARRAY_SIZE  16
+
+
+typedef struct _GRealArray  GRealArray;
+
+struct _GRealArray
+{
+  guint8 *data;
+  guint   len;
+  guint   alloc;
+  guint   zero_terminated;
+};
+
+
+static gint g_nearest_pow        (gint        num);
+static void g_array_maybe_expand (GRealArray *array,
+                                 gint        len);
+
+
+static GMemChunk *array_mem_chunk = NULL;
+
+
+GArray*
+g_array_new (gint zero_terminated)
+{
+  GRealArray *array;
+
+  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);
+
+  array->data = NULL;
+  array->len = 0;
+  array->alloc = 0;
+  array->zero_terminated = (zero_terminated ? 1 : 0);
+
+  return (GArray*) array;
+}
+
+void
+g_array_free (GArray *array,
+             gint    free_segment)
+{
+  if (free_segment)
+    g_free (array->data);
+
+  g_mem_chunk_free (array_mem_chunk, array);
+}
+
+GArray*
+g_rarray_append (GArray   *array,
+                gpointer  data,
+                gint      size)
+{
+  g_array_maybe_expand ((GRealArray*) array, size);
+
+  memcpy (array->data + array->len, data, size);
+
+  array->len += size;
+
+  return array;
+}
+
+GArray*
+g_rarray_prepend (GArray   *array,
+                 gpointer  data,
+                 gint      size)
+{
+  g_array_maybe_expand ((GRealArray*) array, size);
+
+  g_memmove (array->data + size, array->data, array->len);
+  memcpy (array->data, data, size);
+
+  array->len += size;
+
+  return array;
+}
+
+GArray*
+g_rarray_truncate (GArray *array,
+                  gint    length,
+                  gint    size)
+{
+  if (array->data)
+    memset (array->data + length * size, 0, size);
+  array->len = length * size;
+  return array;
+}
+
+
+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 old_alloc;
+
+  if ((array->len + len) > array->alloc)
+    {
+      old_alloc = array->alloc;
+
+      array->alloc = g_nearest_pow (array->len + array->zero_terminated + len);
+      array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
+      array->data = g_realloc (array->data, array->alloc);
+
+      memset (array->data + old_alloc, 0, array->alloc - old_alloc);
+    }
+}
diff --git a/glib/gbacktrace.c b/glib/gbacktrace.c
new file mode 100644 (file)
index 0000000..1c4ce5c
--- /dev/null
@@ -0,0 +1,260 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <sys/types.h>
+
+#include <time.h>
+#include <unistd.h>
+#include "glib.h"
+
+#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
+
+#define INTERACTIVE 0
+#define STACK_TRACE 1
+
+
+#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 int  do_query (char *prompt);
+static void debug (const gchar *progname, int method);
+static void stack_trace (char **);
+static void stack_trace_sigchld (int);
+
+
+static int stack_trace_done;
+
+void
+g_debug (const gchar *progname)
+{
+  char buf[32];
+
+  fprintf (stdout, "[n]othing, [e]xit, [s]tack trace, [a]ttach to process: ");
+  fflush (stdout);
+
+  fgets (buf, 32, stdin);
+  if (strcmp (buf, "n\n") == 0)
+    return;
+  else if (strcmp (buf, "s\n") == 0)
+    debug (progname, STACK_TRACE);
+  else if (strcmp (buf, "a\n") == 0)
+    debug (progname, INTERACTIVE);
+  else
+    exit (0);
+}
+
+void
+g_attach_process (const gchar *progname,
+                 int          query)
+{
+  if (!query || do_query ("attach to process"))
+    debug (progname, INTERACTIVE);
+}
+
+void
+g_stack_trace (const gchar *progname,
+              int          query)
+{
+  if (!query || do_query ("print stack trace"))
+    debug (progname, STACK_TRACE);
+}
+
+static int
+do_query (char *prompt)
+{
+  char buf[32];
+
+  fprintf (stdout, "%s (y/n) ", prompt);
+  fflush (stdout);
+
+  fgets (buf, 32, stdin);
+  if ((strcmp (buf, "yes\n") == 0) ||
+      (strcmp (buf, "y\n") == 0) ||
+      (strcmp (buf, "YES\n") == 0) ||
+      (strcmp (buf, "Y\n") == 0))
+    return TRUE;
+
+  return FALSE;
+}
+
+static void
+debug (const char *progname,
+       int   method)
+{
+  pid_t pid;
+  char buf[16];
+  char *args[4] = { "gdb", NULL, NULL, NULL };
+  volatile int x;
+
+  sprintf (buf, "%d", (int) getpid ());
+
+  args[1] = (gchar*) progname;
+  args[2] = buf;
+
+  switch (method)
+    {
+    case INTERACTIVE:
+      fprintf (stdout, "pid: %s\n", buf);
+      break;
+    case STACK_TRACE:
+      pid = fork ();
+      if (pid == 0)
+       {
+         stack_trace (args);
+         _exit (0);
+       }
+      else if (pid == (pid_t) -1)
+       {
+         perror ("could not fork");
+         return;
+       }
+      break;
+    }
+
+  x = 1;
+  while (x)
+    ;
+}
+
+static void
+stack_trace (char **args)
+{
+  pid_t pid;
+  int in_fd[2];
+  int out_fd[2];
+  SELECT_MASK fdset;
+  SELECT_MASK readset;
+  struct timeval tv;
+  int sel, index, state;
+  char buffer[256];
+  char c;
+
+  stack_trace_done = 0;
+  signal (SIGCHLD, stack_trace_sigchld);
+
+  if ((pipe (in_fd) == -1) || (pipe (out_fd) == -1))
+    {
+      perror ("could 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 ("could not 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);
+}
+
+static void
+stack_trace_sigchld (int signum)
+{
+  stack_trace_done = 1;
+}
diff --git a/glib/gcache.c b/glib/gcache.c
new file mode 100644 (file)
index 0000000..b2fe779
--- /dev/null
@@ -0,0 +1,212 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "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;
+
+
+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);
+
+  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;
+
+  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);
+
+  node->value = value;
+  node->ref_count = 1;
+
+  return node;
+}
+
+static void
+g_cache_node_destroy (GCacheNode *node)
+{
+  g_mem_chunk_free (node_mem_chunk, node);
+}
diff --git a/glib/gcompletion.c b/glib/gcompletion.c
new file mode 100644 (file)
index 0000000..947a6bd
--- /dev/null
@@ -0,0 +1,238 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "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;
+       if ( func )
+               gcomp->func = func;
+       else
+               gcomp->func = NULL;
+       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=NULL;
+       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;
+       }
+
+       if ( !(file=fopen(argv[1], "r")) ) {
+               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
diff --git a/glib/gdataset.c b/glib/gdataset.c
new file mode 100644 (file)
index 0000000..aef270c
--- /dev/null
@@ -0,0 +1,342 @@
+/* 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.
+ */
+#include       "glib.h"
+
+
+
+/* --- defines --- */
+#define        G_DATASET_ID_BLOCK_SIZE                 (1024)
+#define        G_DATASET_MEM_CHUNK_PREALLOC            (512)
+#define        G_DATASET_DATA_MEM_CHUNK_PREALLOC       (1024)
+
+
+/* --- structures --- */
+typedef struct _GDatasetData GDatasetData;
+typedef struct _GDataset GDataset;
+struct _GDatasetData
+{
+  GDatasetData *next;
+  guint id;
+  gpointer data;
+  GDestroyNotify destroy_func;
+};
+
+struct _GDataset
+{
+  gconstpointer location;
+  GDatasetData *data_list;
+};
+
+
+/* --- prototypes --- */
+static inline GDataset*        g_dataset_lookup        (gconstpointer dataset_location);
+static inline void     g_dataset_destroy_i     (GDataset     *dataset);
+static void            g_dataset_initialize    (void);
+static guint*          g_dataset_id_new        (void);
+
+
+/* --- variables --- */
+static GHashTable *g_dataset_location_ht = NULL;
+static GHashTable *g_dataset_key_ht = NULL;
+static GDataset *g_dataset_cached = NULL;
+static GMemChunk *g_dataset_mem_chunk = NULL;
+static GMemChunk *g_dataset_data_mem_chunk = NULL;
+static guint *g_dataset_id_block = NULL;
+static guint g_dataset_id_index = G_DATASET_ID_BLOCK_SIZE + 1;
+
+
+/* --- functions --- */
+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;
+  
+  if (!g_dataset_location_ht)
+    g_dataset_initialize ();
+  
+  dataset = g_hash_table_lookup (g_dataset_location_ht, dataset_location);
+  if (dataset)
+    g_dataset_cached = dataset;
+  
+  return dataset;
+}
+
+static inline void
+g_dataset_destroy_i (GDataset *dataset)
+{
+  register GDatasetData *list;
+  
+  if (dataset == g_dataset_cached)
+    g_dataset_cached = NULL;
+  g_hash_table_remove (g_dataset_location_ht, dataset->location);
+  
+  list = dataset->data_list;
+  g_mem_chunk_free (g_dataset_mem_chunk, dataset);
+  
+  while (list)
+    {
+      register GDatasetData *prev;
+      
+      prev = list;
+      list = prev->next;
+      
+      if (prev->destroy_func)
+       prev->destroy_func (prev->data);
+      
+      g_mem_chunk_free (g_dataset_data_mem_chunk, prev);
+    }
+}
+
+void
+g_dataset_destroy (gconstpointer  dataset_location)
+{
+  register GDataset *dataset;
+  
+  g_return_if_fail (dataset_location != NULL);
+  
+  dataset = g_dataset_lookup (dataset_location);
+  if (dataset)
+    g_dataset_destroy_i (dataset);
+}
+
+void
+g_dataset_id_set_destroy (gconstpointer  dataset_location,
+                         guint          key_id,
+                         GDestroyNotify destroy_func)
+{
+  g_return_if_fail (dataset_location != NULL);
+  
+  if (key_id)
+    {
+      register GDataset *dataset;
+      
+      dataset = g_dataset_lookup (dataset_location);
+      if (dataset)
+       {
+         register GDatasetData *list;
+         
+         list = dataset->data_list;
+         while (list)
+           {
+             if (list->id == key_id)
+               {
+                 list->destroy_func = destroy_func;
+                 return;
+               }
+           }
+       }
+    }
+}
+
+gpointer
+g_dataset_id_get_data (gconstpointer  dataset_location,
+                      guint          key_id)
+{
+  g_return_val_if_fail (dataset_location != NULL, NULL);
+  
+  if (key_id)
+    {
+      register GDataset *dataset;
+      
+      dataset = g_dataset_lookup (dataset_location);
+      if (dataset)
+       {
+         register GDatasetData *list;
+         
+         for (list = dataset->data_list; list; list = list->next)
+           if (list->id == key_id)
+             return list->data;
+       }
+    }
+  
+  return NULL;
+}
+
+void
+g_dataset_id_set_data_full (gconstpointer  dataset_location,
+                           guint          key_id,
+                           gpointer       data,
+                           GDestroyNotify destroy_func)
+{
+  register GDataset *dataset;
+  register GDatasetData *list;
+  
+  g_return_if_fail (dataset_location != NULL);
+  g_return_if_fail (key_id > 0);
+  
+  dataset = g_dataset_lookup (dataset_location);
+  if (!dataset)
+    {
+      dataset = g_chunk_new (GDataset, g_dataset_mem_chunk);
+      dataset->location = dataset_location;
+      dataset->data_list = NULL;
+      g_hash_table_insert (g_dataset_location_ht, 
+                          (gpointer) dataset->location, /* Yuck */
+                          dataset);
+    }
+  
+  list = dataset->data_list;
+  if (!data)
+    {
+      register GDatasetData *prev;
+      
+      prev = NULL;
+      while (list)
+       {
+         if (list->id == key_id)
+           {
+             if (prev)
+               prev->next = list->next;
+             else
+               {
+                 dataset->data_list = list->next;
+                 
+                 if (!dataset->data_list)
+                   g_dataset_destroy_i (dataset);
+               }
+             
+             /* we need to have unlinked before invoking the destroy function
+              */
+             if (list->destroy_func)
+               list->destroy_func (list->data);
+             
+             g_mem_chunk_free (g_dataset_data_mem_chunk, list);
+             break;
+           }
+         
+         prev = list;
+         list = list->next;
+       }
+    }
+  else
+    {
+      register GDatasetData *prev;
+      
+      prev = NULL;
+      while (list)
+       {
+         if (list->id == key_id)
+           {
+             if (prev)
+               prev->next = list->next;
+             else
+               dataset->data_list = list->next;
+             
+             /* we need to have unlinked before invoking the destroy function
+              */
+             if (list->destroy_func)
+               list->destroy_func (list->data);
+             
+             break;
+           }
+         
+         prev = list;
+         list = list->next;
+       }
+      
+      if (!list)
+       list = g_chunk_new (GDatasetData, g_dataset_data_mem_chunk);
+      list->next = dataset->data_list;
+      list->id = key_id;
+      list->data = data;
+      list->destroy_func = destroy_func;
+      dataset->data_list = list;
+    }
+}
+
+guint
+g_dataset_try_key (const gchar    *key)
+{
+  register guint *id;
+  g_return_val_if_fail (key != NULL, 0);
+  
+  if (g_dataset_key_ht)
+    {
+      id = g_hash_table_lookup (g_dataset_key_ht, (gpointer) key);
+      
+      if (id)
+       return *id;
+    }
+  
+  return 0;
+}
+
+guint
+g_dataset_force_id (const gchar    *key)
+{
+  register guint *id;
+  
+  g_return_val_if_fail (key != NULL, 0);
+  
+  if (!g_dataset_key_ht)
+    g_dataset_initialize ();
+  
+  id = g_hash_table_lookup (g_dataset_key_ht, (gpointer) key);
+  if (!id)
+    {
+      id = g_dataset_id_new ();
+      g_hash_table_insert (g_dataset_key_ht, g_strdup (key), id);
+    }
+  
+  return *id;
+}
+
+static void
+g_dataset_initialize (void)
+{
+  if (!g_dataset_location_ht)
+    {
+      g_dataset_location_ht = g_hash_table_new (g_direct_hash, NULL);
+      g_dataset_key_ht = g_hash_table_new (g_str_hash, g_str_equal);
+      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_dataset_data_mem_chunk =
+       g_mem_chunk_new ("GDatasetData MemChunk",
+                        sizeof (GDatasetData),
+                        sizeof (GDatasetData) * G_DATASET_DATA_MEM_CHUNK_PREALLOC,
+                        G_ALLOC_AND_FREE);
+    }
+}
+
+static guint*
+g_dataset_id_new (void)
+{
+  static guint seq_id = 1;
+  register guint *id;
+  
+  if (g_dataset_id_index >= G_DATASET_ID_BLOCK_SIZE)
+    {
+      g_dataset_id_block = g_new (guint, G_DATASET_ID_BLOCK_SIZE);
+      g_dataset_id_index = 0;
+    }
+  
+  id = &g_dataset_id_block[g_dataset_id_index++];
+  *id = seq_id++;
+  
+  return id;
+}
diff --git a/glib/gerror.c b/glib/gerror.c
new file mode 100644 (file)
index 0000000..1c4ce5c
--- /dev/null
@@ -0,0 +1,260 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <sys/types.h>
+
+#include <time.h>
+#include <unistd.h>
+#include "glib.h"
+
+#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
+
+#define INTERACTIVE 0
+#define STACK_TRACE 1
+
+
+#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 int  do_query (char *prompt);
+static void debug (const gchar *progname, int method);
+static void stack_trace (char **);
+static void stack_trace_sigchld (int);
+
+
+static int stack_trace_done;
+
+void
+g_debug (const gchar *progname)
+{
+  char buf[32];
+
+  fprintf (stdout, "[n]othing, [e]xit, [s]tack trace, [a]ttach to process: ");
+  fflush (stdout);
+
+  fgets (buf, 32, stdin);
+  if (strcmp (buf, "n\n") == 0)
+    return;
+  else if (strcmp (buf, "s\n") == 0)
+    debug (progname, STACK_TRACE);
+  else if (strcmp (buf, "a\n") == 0)
+    debug (progname, INTERACTIVE);
+  else
+    exit (0);
+}
+
+void
+g_attach_process (const gchar *progname,
+                 int          query)
+{
+  if (!query || do_query ("attach to process"))
+    debug (progname, INTERACTIVE);
+}
+
+void
+g_stack_trace (const gchar *progname,
+              int          query)
+{
+  if (!query || do_query ("print stack trace"))
+    debug (progname, STACK_TRACE);
+}
+
+static int
+do_query (char *prompt)
+{
+  char buf[32];
+
+  fprintf (stdout, "%s (y/n) ", prompt);
+  fflush (stdout);
+
+  fgets (buf, 32, stdin);
+  if ((strcmp (buf, "yes\n") == 0) ||
+      (strcmp (buf, "y\n") == 0) ||
+      (strcmp (buf, "YES\n") == 0) ||
+      (strcmp (buf, "Y\n") == 0))
+    return TRUE;
+
+  return FALSE;
+}
+
+static void
+debug (const char *progname,
+       int   method)
+{
+  pid_t pid;
+  char buf[16];
+  char *args[4] = { "gdb", NULL, NULL, NULL };
+  volatile int x;
+
+  sprintf (buf, "%d", (int) getpid ());
+
+  args[1] = (gchar*) progname;
+  args[2] = buf;
+
+  switch (method)
+    {
+    case INTERACTIVE:
+      fprintf (stdout, "pid: %s\n", buf);
+      break;
+    case STACK_TRACE:
+      pid = fork ();
+      if (pid == 0)
+       {
+         stack_trace (args);
+         _exit (0);
+       }
+      else if (pid == (pid_t) -1)
+       {
+         perror ("could not fork");
+         return;
+       }
+      break;
+    }
+
+  x = 1;
+  while (x)
+    ;
+}
+
+static void
+stack_trace (char **args)
+{
+  pid_t pid;
+  int in_fd[2];
+  int out_fd[2];
+  SELECT_MASK fdset;
+  SELECT_MASK readset;
+  struct timeval tv;
+  int sel, index, state;
+  char buffer[256];
+  char c;
+
+  stack_trace_done = 0;
+  signal (SIGCHLD, stack_trace_sigchld);
+
+  if ((pipe (in_fd) == -1) || (pipe (out_fd) == -1))
+    {
+      perror ("could 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 ("could not 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);
+}
+
+static void
+stack_trace_sigchld (int signum)
+{
+  stack_trace_done = 1;
+}
diff --git a/glib/ghash.c b/glib/ghash.c
new file mode 100644 (file)
index 0000000..ceee098
--- /dev/null
@@ -0,0 +1,426 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "glib.h"
+
+
+#define HASH_TABLE_MIN_SIZE 11
+#define HASH_TABLE_MAX_SIZE 13845163
+
+
+typedef struct _GHashNode      GHashNode;
+typedef struct _GRealHashTable GRealHashTable;
+
+struct _GHashNode
+{
+  gpointer key;
+  gpointer value;
+  GHashNode *next;
+};
+
+struct _GRealHashTable
+{
+  gint size;
+  gint nnodes;
+  gint frozen;
+  GHashNode **nodes;
+  GHashFunc hash_func;
+  GCompareFunc key_compare_func;
+};
+
+
+static void       g_hash_table_resize  (GHashTable *hash_table);
+static gint       g_hash_closest_prime (gint        num);
+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);
+
+
+extern gint g_primes[];
+extern gint g_nprimes;
+
+static GMemChunk *node_mem_chunk = NULL;
+static GHashNode *node_free_list = NULL;
+
+
+GHashTable*
+g_hash_table_new (GHashFunc    hash_func,
+                 GCompareFunc key_compare_func)
+{
+  GRealHashTable *hash_table;
+
+  g_return_val_if_fail (hash_func != NULL, NULL);
+
+  hash_table = g_new (GRealHashTable, 1);
+  hash_table->size = 0;
+  hash_table->nnodes = 0;
+  hash_table->frozen = FALSE;
+  hash_table->nodes = NULL;
+  hash_table->hash_func = hash_func;
+  hash_table->key_compare_func = key_compare_func;
+
+  return ((GHashTable*) hash_table);
+}
+
+void
+g_hash_table_destroy (GHashTable *hash_table)
+{
+  GRealHashTable *rhash_table;
+  gint i;
+
+  if (hash_table)
+    {
+      rhash_table = (GRealHashTable*) hash_table;
+
+      for (i = 0; i < rhash_table->size; i++)
+       g_hash_nodes_destroy (rhash_table->nodes[i]);
+
+      if (rhash_table->nodes)
+       g_free (rhash_table->nodes);
+      g_free (rhash_table);
+    }
+}
+
+void
+g_hash_table_insert (GHashTable *hash_table,
+                    gpointer    key,
+                    gpointer    value)
+{
+  GRealHashTable *rhash_table;
+  GHashNode *node;
+  guint hash_val;
+
+  if (hash_table)
+    {
+      rhash_table = (GRealHashTable*) hash_table;
+
+      if (rhash_table->size == 0)
+       g_hash_table_resize (hash_table);
+
+      hash_val = (* rhash_table->hash_func) (key) % rhash_table->size;
+
+      node = rhash_table->nodes[hash_val];
+      while (node)
+       {
+         if ((rhash_table->key_compare_func &&
+              (* rhash_table->key_compare_func) (node->key, key)) ||
+             (node->key == key))
+           {
+             /* 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;
+             return;
+           }
+         node = node->next;
+       }
+
+      node = g_hash_node_new (key, value);
+      node->next = rhash_table->nodes[hash_val];
+      rhash_table->nodes[hash_val] = node;
+
+      rhash_table->nnodes += 1;
+      g_hash_table_resize (hash_table);
+    }
+}
+
+void
+g_hash_table_remove (GHashTable      *hash_table,
+                    gconstpointer    key)
+{
+  GRealHashTable *rhash_table;
+  GHashNode *node;
+  GHashNode *prev;
+  guint hash_val;
+
+  rhash_table = (GRealHashTable*) hash_table;
+  if (hash_table && rhash_table->size)
+    {
+      hash_val = (* rhash_table->hash_func) (key) % rhash_table->size;
+
+      prev = NULL;
+      node = rhash_table->nodes[hash_val];
+
+      while (node)
+       {
+         if ((rhash_table->key_compare_func &&
+              (* rhash_table->key_compare_func) (node->key, key)) ||
+             (node->key == key))
+           {
+             if (prev)
+               prev->next = node->next;
+             if (node == rhash_table->nodes[hash_val])
+               rhash_table->nodes[hash_val] = node->next;
+
+             g_hash_node_destroy (node);
+
+             rhash_table->nnodes -= 1;
+             g_hash_table_resize (hash_table);
+             break;
+           }
+
+         prev = node;
+         node = node->next;
+       }
+    }
+}
+
+gpointer
+g_hash_table_lookup (GHashTable   *hash_table,
+                    gconstpointer key)
+{
+  GRealHashTable *rhash_table;
+  GHashNode *node;
+  guint hash_val;
+
+  rhash_table = (GRealHashTable*) hash_table;
+  if (hash_table && rhash_table->size)
+    {
+      hash_val = (* rhash_table->hash_func) (key) % rhash_table->size;
+
+      node = rhash_table->nodes[hash_val];
+
+      /* 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 (rhash_table->key_compare_func)
+       {
+         while (node)
+           {
+             if ((* rhash_table->key_compare_func) (node->key, key))
+               return node->value;
+             node = node->next;
+           }
+       }
+      else
+       {
+         while (node)
+           {
+             if (node->key == key)
+               return node->value;
+             node = node->next;
+           }
+       }
+    }
+
+  return NULL;
+}
+
+void
+g_hash_table_freeze (GHashTable *hash_table)
+{
+  GRealHashTable *rhash_table;
+
+  if (hash_table)
+    {
+      rhash_table = (GRealHashTable*) hash_table;
+      rhash_table->frozen = TRUE;
+    }
+}
+
+void
+g_hash_table_thaw (GHashTable *hash_table)
+{
+  GRealHashTable *rhash_table;
+
+  if (hash_table)
+    {
+      rhash_table = (GRealHashTable*) hash_table;
+      rhash_table->frozen = FALSE;
+
+      g_hash_table_resize (hash_table);
+    }
+}
+
+void
+g_hash_table_foreach (GHashTable *hash_table,
+                     GHFunc      func,
+                     gpointer    user_data)
+{
+  GRealHashTable *rhash_table;
+  GHashNode *node;
+  gint i;
+
+  if (hash_table)
+    {
+      rhash_table = (GRealHashTable*) hash_table;
+
+      for (i = 0; i < rhash_table->size; i++)
+       {
+         node = rhash_table->nodes[i];
+
+         while (node)
+           {
+             (* func) (node->key, node->value, user_data);
+             node = node->next;
+           }
+       }
+    }
+}
+
+
+static void
+g_hash_table_resize (GHashTable *hash_table)
+{
+  GRealHashTable *rhash_table;
+  GHashNode **new_nodes;
+  GHashNode *node;
+  GHashNode *next;
+  gfloat nodes_per_list;
+  guint hash_val;
+  gint new_size;
+  gint need_resize;
+  gint i;
+
+  if (hash_table)
+    {
+      rhash_table = (GRealHashTable*) hash_table;
+
+      if (rhash_table->size == 0)
+       {
+         rhash_table->size = HASH_TABLE_MIN_SIZE;
+         rhash_table->nodes = g_new (GHashNode*, rhash_table->size);
+
+         for (i = 0; i < rhash_table->size; i++)
+           rhash_table->nodes[i] = NULL;
+       }
+      else if (!rhash_table->frozen)
+       {
+         need_resize = FALSE;
+         nodes_per_list = (gfloat) rhash_table->nnodes / (gfloat) rhash_table->size;
+
+         if (nodes_per_list < 0.3)
+           {
+             if (rhash_table->size > HASH_TABLE_MIN_SIZE)
+               need_resize = TRUE;
+           }
+         else if (nodes_per_list > 3.0)
+           {
+             if (rhash_table->size < HASH_TABLE_MAX_SIZE)
+               need_resize = TRUE;
+           }
+
+         if (need_resize)
+           {
+             new_size = g_hash_closest_prime (rhash_table->nnodes);
+             if (new_size < HASH_TABLE_MIN_SIZE)
+               new_size = HASH_TABLE_MIN_SIZE;
+             else if (new_size > HASH_TABLE_MAX_SIZE)
+               new_size = HASH_TABLE_MAX_SIZE;
+
+             new_nodes = g_new (GHashNode*, new_size);
+
+             for (i = 0; i < new_size; i++)
+               new_nodes[i] = NULL;
+
+             for (i = 0; i < rhash_table->size; i++)
+               {
+                 node = rhash_table->nodes[i];
+
+                 while (node)
+                   {
+                     next = node->next;
+
+                     hash_val = (* rhash_table->hash_func) (node->key) % new_size;
+                     node->next = new_nodes[hash_val];
+                     new_nodes[hash_val] = node;
+
+                     node = next;
+                   }
+               }
+
+             g_free (rhash_table->nodes);
+
+             rhash_table->nodes = new_nodes;
+             rhash_table->size = new_size;
+           }
+       }
+    }
+}
+
+static gint
+g_hash_closest_prime (gint num)
+{
+  gint i;
+
+  for (i = 0; i < g_nprimes; i++)
+    if ((g_primes[i] - num) > 0)
+      return g_primes[i];
+
+  return g_primes[g_nprimes - 1];
+}
+
+static GHashNode*
+g_hash_node_new (gpointer key,
+                gpointer value)
+{
+  GHashNode *hash_node;
+
+  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);
+    }
+
+  hash_node->key = key;
+  hash_node->value = value;
+  hash_node->next = NULL;
+
+  return hash_node;
+}
+
+static void
+g_hash_node_destroy (GHashNode *hash_node)
+{
+  if (hash_node)
+    {
+      hash_node->next = node_free_list;
+      node_free_list = hash_node;
+    }
+}
+
+static void
+g_hash_nodes_destroy (GHashNode *hash_node)
+{
+  GHashNode *node;
+
+  if (hash_node)
+    {
+      node = hash_node;
+      while (node->next)
+       node = node->next;
+      node->next = node_free_list;
+      node_free_list = hash_node;
+    }
+}
diff --git a/glib/glist.c b/glib/glist.c
new file mode 100644 (file)
index 0000000..dc21158
--- /dev/null
@@ -0,0 +1,481 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "glib.h"
+
+
+typedef struct _GRealListAllocator GRealListAllocator;
+
+struct _GRealListAllocator
+{
+  GMemChunk *list_mem_chunk;
+  GList            *free_list;
+};
+
+
+static GRealListAllocator *default_allocator = NULL;
+static GRealListAllocator *current_allocator = NULL;
+
+
+GListAllocator*
+g_list_allocator_new (void)
+{
+  GRealListAllocator* allocator = g_new (GRealListAllocator, 1);
+  
+  allocator->list_mem_chunk = NULL;
+  allocator->free_list = NULL;
+  
+  return (GListAllocator*) allocator;
+}
+
+void
+g_list_allocator_free (GListAllocator* fallocator)
+{
+  GRealListAllocator* allocator = (GRealListAllocator *) fallocator;
+  
+  if (allocator && allocator->list_mem_chunk)
+    g_mem_chunk_destroy (allocator->list_mem_chunk);
+  if (allocator)
+    g_free (allocator);
+}
+
+GListAllocator*
+g_list_set_allocator (GListAllocator* fallocator)
+{
+  GRealListAllocator* allocator = (GRealListAllocator *) fallocator;
+  GRealListAllocator* old_allocator = current_allocator;
+  
+  if (allocator)
+    current_allocator = allocator;
+  else
+    {
+      if (!default_allocator)
+       default_allocator = (GRealListAllocator*) g_list_allocator_new ();
+      current_allocator = default_allocator;
+    }
+  
+  if (!current_allocator->list_mem_chunk)
+    current_allocator->list_mem_chunk = g_mem_chunk_new ("list mem chunk",
+                                                        sizeof (GList),
+                                                        1024,
+                                                        G_ALLOC_ONLY);
+  
+  return (GListAllocator*) (old_allocator == default_allocator ? NULL : old_allocator);
+}
+
+
+GList*
+g_list_alloc (void)
+{
+  GList *new_list;
+  
+  g_list_set_allocator (NULL);
+  if (current_allocator->free_list)
+    {
+      new_list = current_allocator->free_list;
+      current_allocator->free_list = current_allocator->free_list->next;
+    }
+  else
+    {
+      new_list = g_chunk_new (GList, current_allocator->list_mem_chunk);
+    }
+  
+  new_list->data = NULL;
+  new_list->next = NULL;
+  new_list->prev = NULL;
+  
+  return new_list;
+}
+
+void
+g_list_free (GList *list)
+{
+  GList *last;
+  
+  if (list)
+    {
+      last = g_list_last (list);
+      last->next = current_allocator->free_list;
+      current_allocator->free_list = list;
+    }
+}
+
+void
+g_list_free_1 (GList *list)
+{
+  if (list)
+    {
+      list->next = current_allocator->free_list;
+      current_allocator->free_list = list;
+    }
+}
+
+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_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;
+}
diff --git a/glib/gmem.c b/glib/gmem.c
new file mode 100644 (file)
index 0000000..a3fa6f5
--- /dev/null
@@ -0,0 +1,807 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <stdlib.h>
+#include <string.h>
+#include "glib.h"
+
+/* #define ENABLE_MEM_PROFILE */
+/* #define ENABLE_MEM_CHECK */
+
+
+#define MAX_MEM_AREA  65536L
+#define MEM_AREA_SIZE 4L
+
+#if SIZEOF_VOID_P > SIZEOF_LONG
+#define MEM_ALIGN     SIZEOF_VOID_P
+#else
+#define MEM_ALIGN     SIZEOF_LONG
+#endif
+
+
+typedef struct _GFreeAtom      GFreeAtom;
+typedef struct _GMemArea       GMemArea;
+typedef struct _GRealMemChunk  GRealMemChunk;
+
+struct _GFreeAtom
+{
+  GFreeAtom *next;
+};
+
+struct _GMemArea
+{
+  GMemArea *next;            /* the next mem area */
+  GMemArea *prev;            /* the previous mem area */
+  gulong index;              /* the current index into the "mem" array */
+  gulong free;               /* the number of free bytes in this mem area */
+  gulong allocated;          /* the number of atoms allocated from this area */
+  gulong mark;               /* is this mem area marked for deletion */
+  gchar mem[MEM_AREA_SIZE];  /* the mem array from which atoms get allocated
+                             * the actual size of this array is determined by
+                             *  the mem chunk "area_size". ANSI says that it
+                             *  must be declared to be the maximum size it
+                             *  can possibly be (even though the actual size
+                             *  may be less).
+                             */
+};
+
+struct _GRealMemChunk
+{
+  gchar *name;               /* name of this MemChunk...used for debugging output */
+  gint type;                 /* the type of MemChunk: ALLOC_ONLY or ALLOC_AND_FREE */
+  gint num_mem_areas;        /* the number of memory areas */
+  gint num_marked_areas;     /* the number of areas marked for deletion */
+  guint atom_size;           /* the size of an atom */
+  gulong area_size;          /* the size of a memory area */
+  GMemArea *mem_area;        /* the current memory area */
+  GMemArea *mem_areas;       /* a list of all the mem areas owned by this chunk */
+  GMemArea *free_mem_area;   /* the free area...which is about to be destroyed */
+  GFreeAtom *free_atoms;     /* the free atoms list */
+  GTree *mem_tree;           /* tree of mem areas sorted by memory address */
+  GRealMemChunk *next;       /* pointer to the next chunk */
+  GRealMemChunk *prev;       /* pointer to the previous chunk */
+};
+
+
+static gulong g_mem_chunk_compute_size (gulong    size);
+static gint   g_mem_chunk_area_compare (GMemArea *a,
+                                       GMemArea *b);
+static gint   g_mem_chunk_area_search  (GMemArea *a,
+                                       gchar    *addr);
+
+
+static GRealMemChunk *mem_chunks = NULL;
+
+#ifdef ENABLE_MEM_PROFILE
+static gulong allocations[4096] = { 0 };
+static gulong allocated_mem = 0;
+static gulong freed_mem = 0;
+#endif /* ENABLE_MEM_PROFILE */
+
+
+#ifndef USE_DMALLOC
+
+gpointer
+g_malloc (gulong size)
+{
+  gpointer p;
+
+
+#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
+  gulong *t;
+#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
+
+
+  if (size == 0)
+    return NULL;
+
+
+#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
+  size += SIZEOF_LONG;
+#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
+
+#ifdef ENABLE_MEM_CHECK
+  size += SIZEOF_LONG;
+#endif /* ENABLE_MEM_CHECK */
+
+
+  p = (gpointer) malloc (size);
+  if (!p)
+    g_error ("could not allocate %ld bytes", size);
+
+
+#ifdef ENABLE_MEM_CHECK
+  size -= SIZEOF_LONG;
+
+  t = p;
+  p = ((guchar*) p + SIZEOF_LONG);
+  *t = 0;
+#endif /* ENABLE_MEM_CHECK */
+
+#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
+  size -= SIZEOF_LONG;
+
+  t = p;
+  p = ((guchar*) p + SIZEOF_LONG);
+  *t = size;
+
+#ifdef ENABLE_MEM_PROFILE
+  if (size <= 4095)
+    allocations[size-1] += 1;
+  else
+    allocations[4095] += 1;
+  allocated_mem += size;
+#endif /* ENABLE_MEM_PROFILE */
+#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
+
+
+  return p;
+}
+
+gpointer
+g_malloc0 (gulong size)
+{
+  gpointer p;
+
+
+#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
+  gulong *t;
+#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
+
+
+  if (size == 0)
+    return NULL;
+
+
+#ifdef ENABLE_MEM_PROFILE
+  size += SIZEOF_LONG;
+#endif /* ENABLE_MEM_PROFILE */
+
+#ifdef ENABLE_MEM_CHECK
+  size += SIZEOF_LONG;
+#endif /* ENABLE_MEM_CHECK */
+
+
+  p = (gpointer) calloc (size, 1);
+  if (!p)
+    g_error ("could not allocate %ld bytes", size);
+
+
+#ifdef ENABLE_MEM_CHECK
+  size -= SIZEOF_LONG;
+
+  t = p;
+  p = ((guchar*) p + SIZEOF_LONG);
+  *t = 0;
+#endif /* ENABLE_MEM_CHECK */
+
+#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
+  size -= SIZEOF_LONG;
+
+  t = p;
+  p = ((guchar*) p + SIZEOF_LONG);
+  *t = size;
+
+#ifdef ENABLE_MEM_PROFILE
+  if (size <= 4095)
+    allocations[size-1] += 1;
+  else
+    allocations[4095] += 1;
+  allocated_mem += size;
+#endif /* ENABLE_MEM_PROFILE */
+#endif /* ENABLE_MEM_PROFILE */
+
+
+  return p;
+}
+
+gpointer
+g_realloc (gpointer mem,
+          gulong   size)
+{
+  gpointer p;
+
+#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
+  gulong *t;
+#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
+
+
+  if (size == 0)
+    return NULL;
+
+
+#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
+  size += SIZEOF_LONG;
+#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
+
+#ifdef ENABLE_MEM_CHECK
+  size += SIZEOF_LONG;
+#endif /* ENABLE_MEM_CHECK */
+
+
+  if (!mem)
+    p = (gpointer) malloc (size);
+  else
+    {
+#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
+      t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
+#ifdef ENABLE_MEM_PROFILE
+      freed_mem += *t;
+#endif /* ENABLE_MEM_PROFILE */
+      mem = t;
+#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
+
+#ifdef ENABLE_MEM_CHECK
+      t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
+      if (*t >= 1)
+       g_warning ("trying to realloc freed memory\n");
+      mem = t;
+#endif /* ENABLE_MEM_CHECK */
+
+      p = (gpointer) realloc (mem, size);
+    }
+
+  if (!p)
+    g_error ("could not reallocate %ld bytes", size);
+
+
+#ifdef ENABLE_MEM_CHECK
+  size -= SIZEOF_LONG;
+
+  t = p;
+  p = ((guchar*) p + SIZEOF_LONG);
+  *t = 0;
+#endif /* ENABLE_MEM_CHECK */
+
+#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
+  size -= SIZEOF_LONG;
+
+  t = p;
+  p = ((guchar*) p + SIZEOF_LONG);
+  *t = size;
+
+#ifdef ENABLE_MEM_PROFILE
+  if (size <= 4095)
+    allocations[size-1] += 1;
+  else
+    allocations[4095] += 1;
+  allocated_mem += size;
+#endif /* ENABLE_MEM_PROFILE */
+#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
+
+
+  return p;
+}
+
+void
+g_free (gpointer mem)
+{
+  if (mem)
+    {
+#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
+      gulong *t;
+      gulong size;
+#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
+
+#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
+      t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
+      size = *t;
+#ifdef ENABLE_MEM_PROFILE
+      freed_mem += size;
+#endif /* ENABLE_MEM_PROFILE */
+      mem = t;
+#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
+
+#ifdef ENABLE_MEM_CHECK
+      t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
+      if (*t >= 1)
+       g_warning ("freeing previously freed memory\n");
+      *t += 1;
+      mem = t;
+
+      memset ((guchar*) mem + 8, 0, size);
+#else /* ENABLE_MEM_CHECK */
+      free (mem);
+#endif /* ENABLE_MEM_CHECK */
+    }
+}
+
+#endif /* ! USE_DMALLOC */
+
+
+void
+g_mem_profile (void)
+{
+#ifdef ENABLE_MEM_PROFILE
+  gint i;
+
+  for (i = 0; i < 4095; i++)
+    if (allocations[i] > 0)
+      g_print ("%lu allocations of %d bytes\n", allocations[i], i + 1);
+
+  if (allocations[4095] > 0)
+    g_print ("%lu allocations of greater than 4095 bytes\n", allocations[4095]);
+  g_print ("%lu bytes allocated\n", allocated_mem);
+  g_print ("%lu bytes freed\n", freed_mem);
+  g_print ("%lu bytes in use\n", allocated_mem - freed_mem);
+#endif /* ENABLE_MEM_PROFILE */
+}
+
+void
+g_mem_check (gpointer mem)
+{
+#ifdef ENABLE_MEM_CHECK
+  gulong *t;
+
+  t = (gulong*) ((guchar*) mem - SIZEOF_LONG - SIZEOF_LONG);
+
+  if (*t >= 1)
+    g_warning ("mem: 0x%08x has been freed: %lu\n", (gulong) mem, *t);
+#endif /* ENABLE_MEM_CHECK */
+}
+
+GMemChunk*
+g_mem_chunk_new (gchar  *name,
+                gint    atom_size,
+                gulong  area_size,
+                gint    type)
+{
+  GRealMemChunk *mem_chunk;
+  gulong rarea_size;
+
+  mem_chunk = g_new (struct _GRealMemChunk, 1);
+  mem_chunk->name = name;
+  mem_chunk->type = type;
+  mem_chunk->num_mem_areas = 0;
+  mem_chunk->num_marked_areas = 0;
+  mem_chunk->mem_area = NULL;
+  mem_chunk->free_mem_area = NULL;
+  mem_chunk->free_atoms = NULL;
+  mem_chunk->mem_tree = NULL;
+  mem_chunk->mem_areas = NULL;
+  mem_chunk->atom_size = atom_size;
+
+  if (mem_chunk->type == G_ALLOC_AND_FREE)
+    mem_chunk->mem_tree = g_tree_new ((GCompareFunc) g_mem_chunk_area_compare);
+
+  if (mem_chunk->atom_size % MEM_ALIGN)
+    mem_chunk->atom_size += MEM_ALIGN - (mem_chunk->atom_size % MEM_ALIGN);
+
+  mem_chunk->area_size = area_size;
+  if (mem_chunk->area_size > MAX_MEM_AREA)
+    mem_chunk->area_size = MAX_MEM_AREA;
+  while (mem_chunk->area_size < mem_chunk->atom_size)
+    mem_chunk->area_size *= 2;
+
+  rarea_size = mem_chunk->area_size + sizeof (GMemArea) - MEM_AREA_SIZE;
+  rarea_size = g_mem_chunk_compute_size (rarea_size);
+  mem_chunk->area_size = rarea_size - (sizeof (GMemArea) - MEM_AREA_SIZE);
+
+  /*
+  mem_chunk->area_size -= (sizeof (GMemArea) - MEM_AREA_SIZE);
+  if (mem_chunk->area_size < mem_chunk->atom_size)
+    {
+      mem_chunk->area_size = (mem_chunk->area_size + sizeof (GMemArea) - MEM_AREA_SIZE) * 2;
+      mem_chunk->area_size -= (sizeof (GMemArea) - MEM_AREA_SIZE);
+    }
+
+  if (mem_chunk->area_size % mem_chunk->atom_size)
+    mem_chunk->area_size += mem_chunk->atom_size - (mem_chunk->area_size % mem_chunk->atom_size);
+    */
+
+  mem_chunk->next = mem_chunks;
+  mem_chunk->prev = NULL;
+  if (mem_chunks)
+    mem_chunks->prev = mem_chunk;
+  mem_chunks = mem_chunk;
+
+  return ((GMemChunk*) mem_chunk);
+}
+
+void
+g_mem_chunk_destroy (GMemChunk *mem_chunk)
+{
+  GRealMemChunk *rmem_chunk;
+  GMemArea *mem_areas;
+  GMemArea *temp_area;
+
+  g_assert (mem_chunk != NULL);
+
+  rmem_chunk = (GRealMemChunk*) mem_chunk;
+
+  mem_areas = rmem_chunk->mem_areas;
+  while (mem_areas)
+    {
+      temp_area = mem_areas;
+      mem_areas = mem_areas->next;
+      g_free (temp_area);
+    }
+
+  if (rmem_chunk->next)
+    rmem_chunk->next->prev = rmem_chunk->prev;
+  if (rmem_chunk->prev)
+    rmem_chunk->prev->next = rmem_chunk->next;
+
+  if (rmem_chunk == mem_chunks)
+    mem_chunks = mem_chunks->next;
+
+  if (rmem_chunk->type == G_ALLOC_AND_FREE)
+    g_tree_destroy (rmem_chunk->mem_tree);
+
+  g_free (rmem_chunk);
+}
+
+gpointer
+g_mem_chunk_alloc (GMemChunk *mem_chunk)
+{
+  GRealMemChunk *rmem_chunk;
+  GMemArea *temp_area;
+  gpointer mem;
+
+  g_assert (mem_chunk != NULL);
+
+  rmem_chunk = (GRealMemChunk*) mem_chunk;
+
+  while (rmem_chunk->free_atoms)
+    {
+      /* Get the first piece of memory on the "free_atoms" list.
+       * We can go ahead and destroy the list node we used to keep
+       *  track of it with and to update the "free_atoms" list to
+       *  point to its next element.
+       */
+      mem = rmem_chunk->free_atoms;
+      rmem_chunk->free_atoms = rmem_chunk->free_atoms->next;
+
+      /* Determine which area this piece of memory is allocated from */
+      temp_area = g_tree_search (rmem_chunk->mem_tree,
+                                (GSearchFunc) g_mem_chunk_area_search,
+                                mem);
+
+      /* If the area has been marked, then it is being destroyed.
+       *  (ie marked to be destroyed).
+       * We check to see if all of the segments on the free list that
+       *  reference this area have been removed. This occurs when
+       *  the ammount of free memory is less than the allocatable size.
+       * If the chunk should be freed, then we place it in the "free_mem_area".
+       * This is so we make sure not to free the mem area here and then
+       *  allocate it again a few lines down.
+       * If we don't allocate a chunk a few lines down then the "free_mem_area"
+       *  will be freed.
+       * If there is already a "free_mem_area" then we'll just free this mem area.
+       */
+      if (temp_area->mark)
+        {
+          /* Update the "free" memory available in that area */
+          temp_area->free += rmem_chunk->atom_size;
+
+          if (temp_area->free == rmem_chunk->area_size)
+            {
+              if (temp_area == rmem_chunk->mem_area)
+                rmem_chunk->mem_area = NULL;
+
+              if (rmem_chunk->free_mem_area)
+                {
+                  rmem_chunk->num_mem_areas -= 1;
+
+                  if (temp_area->next)
+                    temp_area->next->prev = temp_area->prev;
+                  if (temp_area->prev)
+                    temp_area->prev->next = temp_area->next;
+                  if (temp_area == rmem_chunk->mem_areas)
+                    rmem_chunk->mem_areas = rmem_chunk->mem_areas->next;
+
+                 if (rmem_chunk->type == G_ALLOC_AND_FREE)
+                   g_tree_remove (rmem_chunk->mem_tree, temp_area);
+                  g_free (temp_area);
+                }
+              else
+                rmem_chunk->free_mem_area = temp_area;
+             
+             rmem_chunk->num_marked_areas -= 1;
+           }
+       }
+      else
+        {
+          /* Update the number of allocated atoms count.
+          */
+          temp_area->allocated += 1;
+
+          /* The area wasn't marked...return the memory
+          */
+         goto outa_here;
+        }
+    }
+
+  /* If there isn't a current mem area or the current mem area is out of space
+   *  then allocate a new mem area. We'll first check and see if we can use
+   *  the "free_mem_area". Otherwise we'll just malloc the mem area.
+   */
+  if ((!rmem_chunk->mem_area) ||
+      ((rmem_chunk->mem_area->index + rmem_chunk->atom_size) > rmem_chunk->area_size))
+    {
+      if (rmem_chunk->free_mem_area)
+        {
+          rmem_chunk->mem_area = rmem_chunk->free_mem_area;
+         rmem_chunk->free_mem_area = NULL;
+        }
+      else
+        {
+         rmem_chunk->mem_area = (GMemArea*) g_malloc (sizeof (GMemArea) -
+                                                      MEM_AREA_SIZE +
+                                                      rmem_chunk->area_size);
+
+         rmem_chunk->num_mem_areas += 1;
+         rmem_chunk->mem_area->next = rmem_chunk->mem_areas;
+         rmem_chunk->mem_area->prev = NULL;
+
+         if (rmem_chunk->mem_areas)
+           rmem_chunk->mem_areas->prev = rmem_chunk->mem_area;
+         rmem_chunk->mem_areas = rmem_chunk->mem_area;
+
+         if (rmem_chunk->type == G_ALLOC_AND_FREE)
+           g_tree_insert (rmem_chunk->mem_tree, rmem_chunk->mem_area, rmem_chunk->mem_area);
+        }
+
+      rmem_chunk->mem_area->index = 0;
+      rmem_chunk->mem_area->free = rmem_chunk->area_size;
+      rmem_chunk->mem_area->allocated = 0;
+      rmem_chunk->mem_area->mark = 0;
+    }
+
+  /* Get the memory and modify the state variables appropriately.
+   */
+  mem = (gpointer) &rmem_chunk->mem_area->mem[rmem_chunk->mem_area->index];
+  rmem_chunk->mem_area->index += rmem_chunk->atom_size;
+  rmem_chunk->mem_area->free -= rmem_chunk->atom_size;
+  rmem_chunk->mem_area->allocated += 1;
+
+outa_here:
+  return mem;
+}
+
+void
+g_mem_chunk_free (GMemChunk *mem_chunk,
+                 gpointer   mem)
+{
+  GRealMemChunk *rmem_chunk;
+  GMemArea *temp_area;
+  GFreeAtom *free_atom;
+
+  g_assert (mem_chunk != NULL);
+  g_assert (mem != NULL);
+
+  rmem_chunk = (GRealMemChunk*) mem_chunk;
+
+  /* Don't do anything if this is an ALLOC_ONLY chunk
+   */
+  if (rmem_chunk->type == G_ALLOC_AND_FREE)
+    {
+      /* Place the memory on the "free_atoms" list
+       */
+      free_atom = (GFreeAtom*) mem;
+      free_atom->next = rmem_chunk->free_atoms;
+      rmem_chunk->free_atoms = free_atom;
+
+      temp_area = g_tree_search (rmem_chunk->mem_tree,
+                                (GSearchFunc) g_mem_chunk_area_search,
+                                mem);
+
+      temp_area->allocated -= 1;
+
+      if (temp_area->allocated == 0)
+       {
+         temp_area->mark = 1;
+         rmem_chunk->num_marked_areas += 1;
+       }
+    }
+}
+
+/* This doesn't free the free_area if there is one */
+void
+g_mem_chunk_clean (GMemChunk *mem_chunk)
+{
+  GRealMemChunk *rmem_chunk;
+  GMemArea *mem_area;
+  GFreeAtom *prev_free_atom;
+  GFreeAtom *temp_free_atom;
+  gpointer mem;
+
+  g_assert (mem_chunk != NULL);
+
+  rmem_chunk = (GRealMemChunk*) mem_chunk;
+
+  if (rmem_chunk->type == G_ALLOC_AND_FREE)
+    {
+      prev_free_atom = NULL;
+      temp_free_atom = rmem_chunk->free_atoms;
+
+      while (temp_free_atom)
+       {
+         mem = (gpointer) temp_free_atom;
+
+         mem_area = g_tree_search (rmem_chunk->mem_tree,
+                                   (GSearchFunc) g_mem_chunk_area_search,
+                                   mem);
+
+          /* If this mem area is marked for destruction then delete the
+          *  area and list node and decrement the free mem.
+           */
+         if (mem_area->mark)
+           {
+             if (prev_free_atom)
+               prev_free_atom->next = temp_free_atom->next;
+             else
+               rmem_chunk->free_atoms = temp_free_atom->next;
+             temp_free_atom = temp_free_atom->next;
+
+             mem_area->free += rmem_chunk->atom_size;
+             if (mem_area->free == rmem_chunk->area_size)
+               {
+                 rmem_chunk->num_mem_areas -= 1;
+                 rmem_chunk->num_marked_areas -= 1;
+
+                 if (mem_area->next)
+                   mem_area->next->prev = mem_area->prev;
+                 if (mem_area->prev)
+                   mem_area->prev->next = mem_area->next;
+                 if (mem_area == rmem_chunk->mem_areas)
+                   rmem_chunk->mem_areas = rmem_chunk->mem_areas->next;
+                 if (mem_area == rmem_chunk->mem_area)
+                   rmem_chunk->mem_area = NULL;
+
+                 if (rmem_chunk->type == G_ALLOC_AND_FREE)
+                   g_tree_remove (rmem_chunk->mem_tree, mem_area);
+                 g_free (mem_area);
+               }
+           }
+         else
+           {
+             prev_free_atom = temp_free_atom;
+             temp_free_atom = temp_free_atom->next;
+           }
+       }
+    }
+}
+
+void
+g_mem_chunk_reset (GMemChunk *mem_chunk)
+{
+  GRealMemChunk *rmem_chunk;
+  GMemArea *mem_areas;
+  GMemArea *temp_area;
+
+  g_assert (mem_chunk != NULL);
+
+  rmem_chunk = (GRealMemChunk*) mem_chunk;
+
+  mem_areas = rmem_chunk->mem_areas;
+  rmem_chunk->num_mem_areas = 0;
+  rmem_chunk->mem_areas = NULL;
+  rmem_chunk->mem_area = NULL;
+
+  while (mem_areas)
+    {
+      temp_area = mem_areas;
+      mem_areas = mem_areas->next;
+      g_free (temp_area);
+    }
+
+  rmem_chunk->free_atoms = NULL;
+
+  if (rmem_chunk->mem_tree)
+    g_tree_destroy (rmem_chunk->mem_tree);
+  rmem_chunk->mem_tree = g_tree_new ((GCompareFunc) g_mem_chunk_area_compare);
+}
+
+void
+g_mem_chunk_print (GMemChunk *mem_chunk)
+{
+  GRealMemChunk *rmem_chunk;
+  GMemArea *mem_areas;
+  gulong mem;
+
+  g_assert (mem_chunk != NULL);
+
+  rmem_chunk = (GRealMemChunk*) mem_chunk;
+  mem_areas = rmem_chunk->mem_areas;
+  mem = 0;
+
+  while (mem_areas)
+    {
+      mem += rmem_chunk->area_size - mem_areas->free;
+      mem_areas = mem_areas->next;
+    }
+
+  g_print ("%s: %ld bytes using %d mem areas\n", rmem_chunk->name, mem, rmem_chunk->num_mem_areas);
+}
+
+void
+g_mem_chunk_info (void)
+{
+  GRealMemChunk *mem_chunk;
+  gint count;
+
+  count = 0;
+  mem_chunk = mem_chunks;
+  while (mem_chunk)
+    {
+      count += 1;
+      mem_chunk = mem_chunk->next;
+    }
+
+  g_print ("%d mem chunks\n", count);
+
+  mem_chunk = mem_chunks;
+  while (mem_chunk)
+    {
+      g_mem_chunk_print ((GMemChunk*) mem_chunk);
+      mem_chunk = mem_chunk->next;
+    }
+}
+
+void
+g_blow_chunks (void)
+{
+  GRealMemChunk *mem_chunk;
+
+  mem_chunk = mem_chunks;
+  while (mem_chunk)
+    {
+      g_mem_chunk_clean ((GMemChunk*) mem_chunk);
+      mem_chunk = mem_chunk->next;
+    }
+}
+
+
+static gulong
+g_mem_chunk_compute_size (gulong size)
+{
+  gulong power_of_2;
+  gulong lower, upper;
+
+  power_of_2 = 16;
+  while (power_of_2 < size)
+    power_of_2 <<= 1;
+
+  lower = power_of_2 >> 1;
+  upper = power_of_2;
+
+  if ((size - lower) < (upper - size))
+    return lower;
+  return upper;
+}
+
+static gint
+g_mem_chunk_area_compare (GMemArea *a,
+                         GMemArea *b)
+{
+  return (a->mem - b->mem);
+}
+
+static gint
+g_mem_chunk_area_search (GMemArea *a,
+                        gchar    *addr)
+{
+  if (a->mem <= addr)
+    {
+      if (addr < &a->mem[a->index])
+       return 0;
+      return 1;
+    }
+  return -1;
+}
diff --git a/glib/gmessages.c b/glib/gmessages.c
new file mode 100644 (file)
index 0000000..2e58fc3
--- /dev/null
@@ -0,0 +1,180 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include "glib.h"
+
+static GErrorFunc glib_error_func = NULL;
+static GWarningFunc glib_warning_func = NULL;
+static GPrintFunc glib_message_func = NULL;
+static GPrintFunc glib_print_func = NULL;
+
+extern char* g_vsprintf (const gchar *fmt, va_list *args, va_list *args2);
+
+void
+g_error (const gchar *format, ...)
+{
+  va_list args, args2;
+  char *buf;
+  static gboolean errored = 0;
+
+  if (errored++)
+    {
+      write (2, "g_error: recursed!\n", 19);
+      return;
+    }
+  
+  va_start (args, format);
+  va_start (args2, format);
+  buf = g_vsprintf (format, &args, &args2);
+  va_end (args);
+  va_end (args2);
+
+  if (glib_error_func)
+    {
+      (* glib_error_func) (buf);
+    }
+  else
+    {
+      /* Use write() here because we might be out of memory */
+      write (2, "\n** ERROR **: ", 14);
+      write (2, buf, strlen(buf));
+      write (2, "\n", 1);
+    }
+
+  abort ();
+}
+
+void
+g_warning (const gchar *format, ...)
+{
+  va_list args, args2;
+  char *buf;
+
+  va_start (args, format);
+  va_start (args2, format);
+  buf = g_vsprintf (format, &args, &args2);
+  va_end (args);
+  va_end (args2);
+
+  if (glib_warning_func)
+    {
+      (* glib_warning_func) (buf);
+    }
+  else
+    {
+      fputs ("\n** WARNING **: ", stderr);
+      fputs (buf, stderr);
+      fputc ('\n', stderr);
+    }
+}
+
+void
+g_message (const gchar *format, ...)
+{
+  va_list args, args2;
+  char *buf;
+
+  va_start (args, format);
+  va_start (args2, format);
+  buf = g_vsprintf (format, &args, &args2);
+  va_end (args);
+  va_end (args2);
+
+  if (glib_message_func)
+    {
+      (* glib_message_func) (buf);
+    }
+  else
+    {
+      fputs ("message: ", stdout);
+      fputs (buf, stdout);
+      fputc ('\n', stdout);
+    }
+}
+
+void
+g_print (const gchar *format, ...)
+{
+  va_list args, args2;
+  char *buf;
+
+  va_start (args, format);
+  va_start (args2, format);
+  buf = g_vsprintf (format, &args, &args2);
+  va_end (args);
+  va_end (args2);
+
+  if (glib_print_func)
+    {
+      (* glib_print_func) (buf);
+    }
+  else
+    {
+      fputs (buf, stdout);
+    }
+}
+
+GErrorFunc
+g_set_error_handler (GErrorFunc func)
+{
+  GErrorFunc old_error_func;
+
+  old_error_func = glib_error_func;
+  glib_error_func = func;
+
+  return old_error_func;
+}
+
+GWarningFunc
+g_set_warning_handler (GWarningFunc func)
+{
+  GWarningFunc old_warning_func;
+
+  old_warning_func = glib_warning_func;
+  glib_warning_func = func;
+
+  return old_warning_func;
+}
+
+GPrintFunc
+g_set_message_handler (GPrintFunc func)
+{
+  GPrintFunc old_message_func;
+
+  old_message_func = glib_message_func;
+  glib_message_func = func;
+
+  return old_message_func;
+}
+
+GPrintFunc
+g_set_print_handler (GPrintFunc func)
+{
+  GPrintFunc old_print_func;
+
+  old_print_func = glib_print_func;
+  glib_print_func = func;
+  
+  return old_print_func;
+}
+
diff --git a/glib/gprimes.c b/glib/gprimes.c
new file mode 100644 (file)
index 0000000..6a38b39
--- /dev/null
@@ -0,0 +1,62 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "glib.h"
+
+
+gint g_primes[] =
+{
+  11,
+  15,
+  23,
+  35,
+  49,
+  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,
+};
+
+gint g_nprimes = sizeof (g_primes) / sizeof (g_primes[0]);
diff --git a/glib/gscanner.c b/glib/gscanner.c
new file mode 100644 (file)
index 0000000..ccb6960
--- /dev/null
@@ -0,0 +1,1551 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * GScanner: Flexible lexical scanner for general purpose.
+ * Copyright (C) 1997, 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.
+ */
+#define                __gscanner_c__
+
+#include       <stdlib.h>
+#include       <stdarg.h>
+#include       <string.h>
+#include       <stdio.h>
+#include       <unistd.h>
+#include       <errno.h>
+#include       <sys/types.h>   /* needed for sys/stat.h */
+#include       <sys/stat.h>
+#include       "glib.h"
+
+
+
+/* --- defines --- */
+#define        to_lower(c)                             ( \
+       (guchar) (                                                      \
+         ( (((guchar)(c))>='A' && ((guchar)(c))<='Z') * ('a'-'A') ) |  \
+         ( (((guchar)(c))>=192 && ((guchar)(c))<=214) * (224-192) ) |  \
+         ( (((guchar)(c))>=216 && ((guchar)(c))<=222) * (248-216) ) |  \
+         ((guchar)(c))                                                 \
+       )                                                               \
+)
+
+
+/* --- typedefs --- */
+typedef        struct  _GScannerHashVal        GScannerHashVal;
+
+struct _GScannerHashVal
+{
+  gchar                *key;
+  gpointer     value;
+};
+
+
+
+/* --- variables --- */
+static GScannerConfig  g_scanner_config_template =
+{
+  (
+   " \t\n"
+   )                   /* cset_skip_characters */,
+  (
+   G_CSET_a_2_z
+   "_"
+   G_CSET_A_2_Z
+   )                   /* cset_identifier_first */,
+  (
+   G_CSET_a_2_z
+   "_0123456789"
+   G_CSET_A_2_Z
+   G_CSET_LATINS
+   G_CSET_LATINC
+   )                   /* cset_identifier_nth */,
+  ( "#\n" )            /* cpair_comment_single */,
+  
+  FALSE                        /* case_sensitive */,
+  
+  TRUE                 /* skip_comment_multi */,
+  TRUE                 /* skip_comment_single */,
+  TRUE                 /* scan_comment_multi */,
+  TRUE                 /* scan_identifier */,
+  FALSE                        /* scan_identifier_1char */,
+  FALSE                        /* scan_identifier_NULL */,
+  TRUE                 /* scan_symbols */,
+  FALSE                        /* scan_binary */,
+  TRUE                 /* scan_octal */,
+  TRUE                 /* scan_float */,
+  TRUE                 /* scan_hex */,
+  FALSE                        /* scan_hex_dollar */,
+  TRUE                 /* scan_string_sq */,
+  TRUE                 /* scan_string_dq */,
+  TRUE                 /* numbers_2_int */,
+  FALSE                        /* int_2_float */,
+  FALSE                        /* identifier_2_string */,
+  TRUE                 /* char_2_token */,
+  FALSE                        /* symbol_2_token */,
+};
+
+
+/* --- prototypes --- */
+extern char* g_vsprintf (gchar *fmt, va_list *args, va_list *args2);
+static GScannerHashVal* g_scanner_lookup_internal (GScanner    *scanner,
+                                                   const gchar *symbol);
+static void    g_scanner_get_token_ll  (GScanner       *scanner,
+                                        GTokenType     *token_p,
+                                        GValue         *value_p,
+                                        guint          *line_p,
+                                        guint          *position_p);
+static void    g_scanner_get_token_i   (GScanner       *scanner,
+                                        GTokenType     *token_p,
+                                        GValue         *value_p,
+                                        guint          *line_p,
+                                        guint          *position_p);
+static void    g_scanner_free_value    (GTokenType     *token_p,
+                                        GValue         *value_p);
+
+static inline
+gint           g_scanner_char_2_num    (guchar         c,
+                                        guchar         base);
+static guchar  g_scanner_peek_next_char(GScanner       *scanner);
+static guchar  g_scanner_get_char      (GScanner       *scanner,
+                                        guint          *line_p,
+                                        guint          *position_p);
+static  void   g_scanner_msg_handler   (GScanner       *scanner,
+                                        gchar          *message,
+                                        gint            is_error);
+
+
+/* --- functions --- */
+static gint
+g_scanner_char_2_num (guchar   c,
+                     guchar    base)
+{
+  if (c >= '0' && c <= '9')
+    c -= '0';
+  else if (c >= 'A' && c <= 'Z')
+    c -= 'A' - 10;
+  else if (c >= 'a' && c <= 'z')
+    c -= 'a' - 10;
+  else
+    return -1;
+  
+  if (c < base)
+    return c;
+  
+  return -1;
+}
+
+GScanner*
+g_scanner_new (GScannerConfig  *config_templ)
+{
+  register GScanner    *scanner;
+  
+  if (!config_templ)
+    config_templ = &g_scanner_config_template;
+  
+  scanner = g_new0 (GScanner, 1);
+  
+  scanner->user_data = NULL;
+  scanner->input_name = NULL;
+  scanner->parse_errors        = 0;
+  scanner->max_parse_errors = 0;
+  
+  scanner->config = g_new0 (GScannerConfig, 1);
+  
+  scanner->config->case_sensitive      = config_templ->case_sensitive;
+  scanner->config->cset_skip_characters        = config_templ->cset_skip_characters;
+  scanner->config->cset_identifier_first= config_templ->cset_identifier_first;
+  scanner->config->cset_identifier_nth = config_templ->cset_identifier_nth;
+  scanner->config->cpair_comment_single        = config_templ->cpair_comment_single;
+  scanner->config->skip_comment_multi  = config_templ->skip_comment_multi;
+  scanner->config->skip_comment_single = config_templ->skip_comment_single;
+  scanner->config->scan_comment_multi  = config_templ->scan_comment_multi;
+  scanner->config->scan_identifier     = config_templ->scan_identifier;
+  scanner->config->scan_identifier_1char= config_templ->scan_identifier_1char;
+  scanner->config->scan_identifier_NULL        = config_templ->scan_identifier_NULL;
+  scanner->config->scan_symbols                = config_templ->scan_symbols;
+  scanner->config->scan_binary         = config_templ->scan_binary;
+  scanner->config->scan_octal          = config_templ->scan_octal;
+  scanner->config->scan_float          = config_templ->scan_float;
+  scanner->config->scan_hex            = config_templ->scan_hex;
+  scanner->config->scan_hex_dollar     = config_templ->scan_hex_dollar;
+  scanner->config->scan_string_sq      = config_templ->scan_string_sq;
+  scanner->config->scan_string_dq      = config_templ->scan_string_dq;
+  scanner->config->numbers_2_int       = config_templ->numbers_2_int;
+  scanner->config->int_2_float         = config_templ->int_2_float;
+  scanner->config->identifier_2_string = config_templ->identifier_2_string;
+  scanner->config->char_2_token                = config_templ->char_2_token;
+  scanner->config->symbol_2_token      = config_templ->symbol_2_token;
+  
+  scanner->token = G_TOKEN_NONE;
+  scanner->value.v_int = 0;
+  scanner->line = 1;
+  scanner->position = 0;
+  
+  scanner->next_token = G_TOKEN_NONE;
+  scanner->next_value.v_int = 0;
+  scanner->next_line = 1;
+  scanner->next_position = 0;
+  
+  scanner->symbol_table = g_hash_table_new (g_str_hash, g_str_equal);
+  scanner->text = NULL;
+  scanner->text_len = 0;
+  scanner->input_fd = -1;
+  scanner->peeked_char = -1;
+
+  scanner->msg_handler = g_scanner_msg_handler;
+  
+  return scanner;
+}
+
+static void
+g_scanner_destroy_symbol_table_entry (gpointer key,
+                                     gpointer value,
+                                     gpointer user_data)
+{
+  g_free (key);
+  g_free (value);
+}
+
+void
+g_scanner_destroy (GScanner    *scanner)
+{
+  g_return_if_fail (scanner != NULL);
+  
+  g_hash_table_foreach (scanner->symbol_table, 
+                        g_scanner_destroy_symbol_table_entry, NULL);
+  g_hash_table_destroy (scanner->symbol_table);
+  g_scanner_free_value (&scanner->token, &scanner->value);
+  g_scanner_free_value (&scanner->next_token, &scanner->next_value);
+  g_free (scanner->config);
+  g_free (scanner);
+}
+
+static void
+g_scanner_msg_handler (GScanner                *scanner,
+                      gchar            *message,
+                      gint              is_error)
+{
+  g_return_if_fail (scanner != NULL);
+
+  fprintf (stdout, "%s:%d: ", scanner->input_name, scanner->line);
+  if (is_error)
+    fprintf (stdout, "error: ");
+  fprintf (stdout, "%s\n", message);
+}
+
+void
+g_scanner_error (GScanner       *scanner,
+                const gchar    *format,
+                ...)
+{
+  g_return_if_fail (scanner != NULL);
+  g_return_if_fail (format != NULL);
+
+  scanner->parse_errors++;
+
+  if (scanner->msg_handler)
+    {
+      va_list args, args2;
+      gchar *string;
+      
+      va_start (args, format);
+      va_start (args2, format);
+      string = g_vsprintf ((gchar*) format, &args, &args2);
+      va_end (args);
+      va_end (args2);
+
+      string = g_strdup (string);
+
+      scanner->msg_handler (scanner, string, TRUE);
+         
+      g_free (string);
+    }
+}
+
+void
+g_scanner_warn (GScanner       *scanner,
+               const gchar    *format,
+               ...)
+{
+  g_return_if_fail (scanner != NULL);
+  g_return_if_fail (format != NULL);
+  
+  if (scanner->msg_handler)
+    {
+      va_list args, args2;
+      gchar *string;
+      
+      va_start (args, format);
+      va_start (args2, format);
+      string = g_vsprintf ((gchar*) format, &args, &args2);
+      va_end (args);
+      va_end (args2);
+      
+      string = g_strdup (string);
+      
+      scanner->msg_handler (scanner, string, FALSE);
+      
+      g_free (string);
+    }
+}
+
+void
+g_scanner_input_file (GScanner *scanner,
+                     gint      input_fd)
+{
+  g_return_if_fail (input_fd >= 0);
+  
+  scanner->token = G_TOKEN_NONE;
+  scanner->value.v_int = 0;
+  scanner->line = 1;
+  scanner->position = 0;
+  scanner->next_token = G_TOKEN_NONE;
+  
+  scanner->text = NULL;
+  scanner->text_len = 0;
+  scanner->input_fd = input_fd;
+  scanner->peeked_char = -1;
+}
+
+void
+g_scanner_input_text (GScanner      *scanner,
+                     const  gchar   *text,
+                     guint           text_len)
+{
+  g_return_if_fail (text != NULL);
+  
+  scanner->token = G_TOKEN_NONE;
+  scanner->value.v_int = 0;
+  scanner->line = 1;
+  scanner->position = 0;
+  scanner->next_token = G_TOKEN_NONE;
+  
+  scanner->text = text;
+  scanner->text_len = text_len;
+  scanner->input_fd = -1;
+  scanner->peeked_char = -1;
+}
+
+void
+g_scanner_add_symbol (GScanner         *scanner,
+                     const gchar       *symbol,
+                     gpointer          value)
+{
+  register GScannerHashVal     *hash_val;
+  
+  g_return_if_fail (scanner != NULL);
+  g_return_if_fail (symbol != NULL);
+  
+  hash_val = g_scanner_lookup_internal (scanner, symbol);
+  
+  if (!hash_val)
+    {
+      hash_val = g_new (GScannerHashVal, 1);
+      hash_val->key = g_strdup (symbol);
+      hash_val->value = value;
+      if (!scanner->config->case_sensitive)
+       {
+         register guint        i, l;
+         
+         l = strlen (hash_val->key);
+         for (i = 0; i < l; i++)
+           hash_val->key[i] = to_lower (hash_val->key[i]);
+       }
+      g_hash_table_insert (scanner->symbol_table, hash_val->key, hash_val);
+    }
+  else
+    hash_val->value = value;
+}
+
+gpointer
+g_scanner_lookup_symbol (GScanner      *scanner,
+                        const gchar    *symbol)
+{
+  register GScannerHashVal     *hash_val;
+  
+  g_return_val_if_fail (scanner != NULL, NULL);
+  
+  if (!symbol)
+    return NULL;
+  
+  hash_val = g_scanner_lookup_internal (scanner, symbol);
+  
+  if (hash_val)
+    return hash_val->value;
+  else
+    return NULL;
+}
+
+static void
+g_scanner_foreach_internal (gpointer  key,
+                           gpointer  value,
+                           gpointer  user_data)
+{
+  register GScannerHashVal *hash_val;
+  register GHFunc func;
+  register gpointer func_data;
+  register gpointer *d;
+
+  d = user_data;
+  func = (GHFunc)d[0];
+  func_data = d[1];
+  hash_val = value;
+
+  func (key, hash_val->value, func_data);
+}
+
+void
+g_scanner_foreach_symbol (GScanner       *scanner,
+                         GHFunc          func,
+                         gpointer        func_data)
+{
+  gpointer d[2];
+
+  g_return_if_fail (scanner != NULL);
+
+  d[0] = (gpointer)func;
+  d[1] = func_data;
+
+  g_hash_table_foreach (scanner->symbol_table, g_scanner_foreach_internal, d);
+}
+
+void
+g_scanner_remove_symbol (GScanner      *scanner,
+                        const gchar    *symbol)
+{
+  register GScannerHashVal     *hash_val;
+  
+  g_return_if_fail (scanner != NULL);
+
+  hash_val = g_scanner_lookup_internal (scanner, symbol);
+  
+  if (hash_val)
+    {
+      g_hash_table_remove (scanner->symbol_table, hash_val->key);
+      g_free (hash_val->key);
+      g_free (hash_val);
+    }
+}
+
+void
+g_scanner_freeze_symbol_table (GScanner *scanner)
+{
+  g_return_if_fail (scanner != NULL);
+
+  g_hash_table_freeze (scanner->symbol_table);
+}
+
+void
+g_scanner_thaw_symbol_table (GScanner *scanner)
+{
+  g_return_if_fail (scanner != NULL);
+
+  g_hash_table_thaw (scanner->symbol_table);
+}
+
+GTokenType
+g_scanner_peek_next_token (GScanner    *scanner)
+{
+  g_return_val_if_fail (scanner != NULL, G_TOKEN_EOF);
+  
+  if (scanner->next_token == G_TOKEN_NONE)
+    {
+      scanner->next_line = scanner->line;
+      scanner->next_position = scanner->position;
+      g_scanner_get_token_i (scanner,
+                            &scanner->next_token,
+                            &scanner->next_value,
+                            &scanner->next_line,
+                            &scanner->next_position);
+    }
+  
+  return scanner->next_token;
+}
+
+GTokenType
+g_scanner_get_next_token (GScanner     *scanner)
+{
+  g_return_val_if_fail (scanner != NULL, G_TOKEN_EOF);
+  
+  if (scanner->next_token != G_TOKEN_NONE)
+    {
+      g_scanner_free_value (&scanner->token, &scanner->value);
+      
+      scanner->token = scanner->next_token;
+      scanner->value = scanner->next_value;
+      scanner->line = scanner->next_line;
+      scanner->position = scanner->next_position;
+      scanner->next_token = G_TOKEN_NONE;
+    }
+  else
+    g_scanner_get_token_i (scanner,
+                          &scanner->token,
+                          &scanner->value,
+                          &scanner->line,
+                          &scanner->position);
+  
+  return scanner->token;
+}
+
+GTokenType
+g_scanner_cur_token (GScanner *scanner)
+{
+  g_return_val_if_fail (scanner != NULL, G_TOKEN_EOF);
+  
+  return scanner->token;
+}
+
+GValue
+g_scanner_cur_value (GScanner *scanner)
+{
+  register GValue v;
+  
+  v.v_int = 0;
+  g_return_val_if_fail (scanner != NULL, v);
+  
+  return scanner->value;
+}
+
+guint
+g_scanner_cur_line (GScanner *scanner)
+{
+  g_return_val_if_fail (scanner != NULL, 0);
+  
+  return scanner->line;
+}
+
+guint
+g_scanner_cur_position (GScanner *scanner)
+{
+  g_return_val_if_fail (scanner != NULL, 0);
+  
+  return scanner->position;
+}
+
+gboolean
+g_scanner_eof (GScanner        *scanner)
+{
+  g_return_val_if_fail (scanner != NULL, TRUE);
+  
+  return scanner->token == G_TOKEN_EOF;
+}
+
+static GScannerHashVal*
+g_scanner_lookup_internal (GScanner    *scanner,
+                          const gchar  *symbol)
+{
+  register GScannerHashVal     *hash_val;
+  
+  if (!scanner->config->case_sensitive)
+    {
+      register gchar *buffer;
+      register guint i, l;
+      
+      l = strlen (symbol);
+      buffer = g_new (gchar, l + 1);
+      for (i = 0; i < l; i++)
+       buffer[i] = to_lower (symbol[i]);
+      buffer[i] = 0;
+      hash_val = g_hash_table_lookup (scanner->symbol_table, buffer);
+      g_free (buffer);
+    }
+  else
+    hash_val = g_hash_table_lookup (scanner->symbol_table, (gchar*) symbol);
+  
+  return hash_val;
+}
+
+static guchar
+g_scanner_peek_next_char (GScanner *scanner)
+{
+  guchar fchar;
+  
+  if (scanner->text_len)
+    {
+      fchar = scanner->text[0];
+    }
+  else if (scanner->input_fd >= 0)
+    {
+      if (scanner->peeked_char < 0)
+       {
+         register gint count;
+         
+         do
+           {
+             count = read (scanner->input_fd, &fchar, 1);
+           }
+         while (count == -1 &&
+                (errno == EINTR ||
+                 errno == EAGAIN));
+         
+         if (count != 1)
+           fchar = 0;
+         
+         scanner->peeked_char = fchar;
+       }
+      else
+       fchar = scanner->peeked_char;
+    }
+  else
+    fchar = 0;
+  
+  return fchar;
+}
+
+static guchar
+g_scanner_get_char (GScanner   *scanner,
+                   guint       *line_p,
+                   guint       *position_p)
+{
+  guchar fchar;
+  
+  if (scanner->text_len)
+    {
+      fchar = *(scanner->text++);
+      scanner->text_len--;
+    }
+  else if (scanner->input_fd >= 0)
+    {
+      if (scanner->peeked_char < 0)
+       {
+         register gint count;
+         
+         do
+           {
+             count = read (scanner->input_fd, &fchar, 1);
+           }
+         while (count == -1 &&
+                (errno == EINTR ||
+                 errno == EAGAIN));
+         if (count != 1 || fchar == 0)
+           {
+             fchar = 0;
+             scanner->peeked_char = 0;
+           }
+       }
+      else
+       {
+         fchar = scanner->peeked_char;
+         if (fchar)
+           scanner->peeked_char = -1;
+       }
+    }
+  else
+    fchar = 0;
+  
+  if (fchar == '\n')
+    {
+      (*position_p) = 0;
+      (*line_p)++;
+    }
+  else if (fchar)
+    {
+      (*position_p)++;
+    }
+  
+  return fchar;
+}
+
+void
+g_scanner_unexp_token (GScanner                *scanner,
+                      GTokenType        expected_token,
+                      const gchar      *identifier_spec,
+                      const gchar      *symbol_spec,
+                      const gchar      *symbol_name,
+                      const gchar      *message,
+                      gint              is_error)
+{
+  register gchar       *token_string;
+  register guint       token_string_len;
+  register gchar       *expected_string;
+  register guint       expected_string_len;
+  register gchar       *message_prefix;
+  register gboolean    print_unexp;
+  void (*msg_handler)   (GScanner*, const gchar*, ...);
+  
+  g_return_if_fail (scanner != NULL);
+
+  if (is_error)
+    msg_handler = g_scanner_error;
+  else
+    msg_handler = g_scanner_warn;
+
+  if (!identifier_spec)
+    identifier_spec = "identifier";
+  if (!symbol_spec)
+    symbol_spec = "symbol";
+  
+  token_string_len = 56;
+  token_string = g_new (gchar, token_string_len + 1);
+  expected_string_len = 64;
+  expected_string = g_new (gchar, expected_string_len + 1);
+  print_unexp = TRUE;
+  
+  switch (scanner->token)
+    {
+      
+    case  G_TOKEN_EOF:
+      g_snprintf (token_string, token_string_len, "end of file");
+      break;
+      
+    default:  /* 1 ... 255 */
+      if (scanner->token >= 1 && scanner->token <= 255)
+       {
+         if ((scanner->token >= ' ' && scanner->token <= '~') ||
+             strchr (scanner->config->cset_identifier_first, scanner->token) ||
+             strchr (scanner->config->cset_identifier_nth, scanner->token))
+           g_snprintf (token_string, expected_string_len, "character `%c'", scanner->token);
+         else
+           g_snprintf (token_string, expected_string_len, "character `\\%o'", scanner->token);
+       }
+      else
+       g_snprintf (token_string, token_string_len, "(unknown) token <%d>", scanner->token);
+      break;
+      
+    case  G_TOKEN_ERROR:
+      print_unexp = FALSE;
+      expected_token = G_TOKEN_NONE;
+      switch (scanner->value.v_error)
+       {
+       case  G_ERR_UNEXP_EOF:
+         g_snprintf (token_string, token_string_len, "scanner: unexpected end of file");
+         break;
+         
+       case  G_ERR_UNEXP_EOF_IN_STRING:
+         g_snprintf (token_string, token_string_len, "scanner: unterminated string constant");
+         break;
+         
+       case  G_ERR_UNEXP_EOF_IN_COMMENT:
+         g_snprintf (token_string, token_string_len, "scanner: unterminated comment");
+         break;
+         
+       case  G_ERR_NON_DIGIT_IN_CONST:
+         g_snprintf (token_string, token_string_len, "scanner: non digit in constant");
+         break;
+         
+       case  G_ERR_FLOAT_RADIX:
+         g_snprintf (token_string, token_string_len, "scanner: invalid radix for floating constant");
+         break;
+         
+       case  G_ERR_FLOAT_MALFORMED:
+         g_snprintf (token_string, token_string_len, "scanner: malformed floating constant");
+         break;
+         
+       case  G_ERR_DIGIT_RADIX:
+         g_snprintf (token_string, token_string_len, "scanner: digit is beyond radix");
+         break;
+         
+       case  G_ERR_UNKNOWN:
+       default:
+         g_snprintf (token_string, token_string_len, "scanner: unknown error");
+         break;
+       }
+      break;
+      
+    case  G_TOKEN_CHAR:
+      g_snprintf (token_string, token_string_len, "character `%c'", scanner->value.v_char);
+      break;
+      
+    case  G_TOKEN_SYMBOL:
+      if (expected_token == G_TOKEN_SYMBOL)
+       print_unexp = FALSE;
+      if (symbol_name)
+       g_snprintf (token_string,
+                 token_string_len,
+                 "%s%s `%s'",
+                 print_unexp ? "" : "invalid ",
+                 symbol_spec,
+                 symbol_name);
+      else
+       g_snprintf (token_string,
+                 token_string_len,
+                 "%s%s",
+                 print_unexp ? "" : "invalid ",
+                 symbol_spec);
+      break;
+      
+    case  G_TOKEN_IDENTIFIER:
+      if (expected_token == G_TOKEN_IDENTIFIER)
+       print_unexp = FALSE;
+      g_snprintf (token_string,
+               token_string_len,
+               "%s%s `%s'",
+               print_unexp ? "" : "invalid ",
+               identifier_spec,
+               scanner->value.v_string);
+      break;
+      
+    case  G_TOKEN_BINARY:
+    case  G_TOKEN_OCTAL:
+    case  G_TOKEN_INT:
+    case  G_TOKEN_HEX:
+      g_snprintf (token_string, token_string_len, "number `%ld'", scanner->value.v_int);
+      break;
+      
+    case  G_TOKEN_FLOAT:
+      g_snprintf (token_string, token_string_len, "number `%.3f'", scanner->value.v_float);
+      break;
+      
+    case  G_TOKEN_STRING:
+      g_snprintf (token_string,
+               token_string_len,
+               "%sstring constant \"%s\"",
+               scanner->value.v_string[0] == 0 ? "empty " : "",
+               scanner->value.v_string);
+      token_string[token_string_len - 2] = '"';
+      token_string[token_string_len - 1] = 0;
+      break;
+      
+    case  G_TOKEN_COMMENT_SINGLE:
+    case  G_TOKEN_COMMENT_MULTI:
+      g_snprintf (token_string, token_string_len, "comment");
+      break;
+      
+    case  G_TOKEN_NONE:
+      g_assert_not_reached ();
+      break;
+    }
+  
+  
+  switch (expected_token)
+    {
+    default: /* 1 ... 255 */
+      if (expected_token >= 1 && expected_token <= 255)
+       {
+         if ((expected_token >= ' ' && expected_token <= '~') ||
+             strchr (scanner->config->cset_identifier_first, expected_token) ||
+             strchr (scanner->config->cset_identifier_nth, expected_token))
+           g_snprintf (expected_string, expected_string_len, "character `%c'", expected_token);
+         else
+           g_snprintf (expected_string, expected_string_len, "character `\\%o'", expected_token);
+       }
+      else
+       g_snprintf (expected_string, expected_string_len, "(unknown) token <%d>", expected_token);
+      break;
+      
+    case  G_TOKEN_INT:
+      g_snprintf (expected_string, expected_string_len, "number (integer)");
+      break;
+      
+    case  G_TOKEN_FLOAT:
+      g_snprintf (expected_string, expected_string_len, "number (float)");
+      break;
+      
+    case  G_TOKEN_STRING:
+      g_snprintf (expected_string, expected_string_len, "string constant");
+      break;
+      
+    case  G_TOKEN_SYMBOL:
+      g_snprintf (expected_string,
+               expected_string_len,
+               "%s%s",
+               scanner->token == G_TOKEN_SYMBOL ? "valid " : "",
+               symbol_spec);
+      break;
+      
+    case  G_TOKEN_IDENTIFIER:
+      g_snprintf (expected_string,
+               expected_string_len,
+               "%s%s",
+               scanner->token == G_TOKEN_IDENTIFIER ? "valid " : "",
+               identifier_spec);
+      break;
+      
+    case  G_TOKEN_NONE:
+      break;
+    }
+  
+  if (message && message[0] != 0)
+    message_prefix = " - ";
+  else
+    {
+      message_prefix = "";
+      message = "";
+    }
+  
+  if (expected_token != G_TOKEN_NONE)
+    {
+      if (print_unexp)
+       msg_handler (scanner,
+                    "unexpected %s, expected %s%s%s",
+                    token_string,
+                    expected_string,
+                    message_prefix,
+                    message);
+      else
+       msg_handler (scanner,
+                    "%s, expected %s%s%s",
+                    token_string,
+                    expected_string,
+                    message_prefix,
+                    message);
+    }
+  else
+    {
+      if (print_unexp)
+       msg_handler (scanner,
+                    "unexpected %s%s%s",
+                    token_string,
+                    message_prefix,
+                    message);
+      else
+       msg_handler (scanner,
+                    "%s%s%s",
+                    token_string,
+                    message_prefix,
+                    message);
+    }
+  
+  g_free (token_string);
+  g_free (expected_string);
+}
+
+gint
+g_scanner_stat_mode (const gchar *filename)
+{
+  struct stat  *stat_buf;
+  gint          st_mode;
+
+  stat_buf = g_new0 (struct stat, 1);
+
+  lstat (filename, stat_buf);
+
+  st_mode = stat_buf->st_mode;
+
+  g_free (stat_buf);
+
+  return st_mode;
+}
+
+static void
+g_scanner_free_value (GTokenType     *token_p,
+                     GValue         *value_p)
+{
+  switch (*token_p)
+    {
+    case  G_TOKEN_STRING:
+    case  G_TOKEN_IDENTIFIER:
+    case  G_TOKEN_IDENTIFIER_NULL:
+    case  G_TOKEN_COMMENT_SINGLE:
+    case  G_TOKEN_COMMENT_MULTI:
+      g_free (value_p->v_string);
+      break;
+      
+    default:
+      break;
+    }
+  
+  *token_p = G_TOKEN_NONE;
+}
+
+static void
+g_scanner_get_token_i (GScanner        *scanner,
+                      GTokenType       *token_p,
+                      GValue           *value_p,
+                      guint            *line_p,
+                      guint            *position_p)
+{
+  do
+    {
+      g_scanner_free_value (token_p, value_p);
+      g_scanner_get_token_ll (scanner, token_p, value_p, line_p, position_p);
+    }
+  while (((*token_p > 0 && *token_p < 256) &&
+         strchr (scanner->config->cset_skip_characters, *token_p)) ||
+        (*token_p == G_TOKEN_CHAR &&
+         strchr (scanner->config->cset_skip_characters, value_p->v_char)) ||
+        (*token_p == G_TOKEN_COMMENT_MULTI &&
+         scanner->config->skip_comment_multi) ||
+        (*token_p == G_TOKEN_COMMENT_SINGLE &&
+         scanner->config->skip_comment_single));
+  
+  switch (*token_p)
+    {
+    case       G_TOKEN_IDENTIFIER:
+      if (scanner->config->identifier_2_string)
+       *token_p = G_TOKEN_STRING;
+      break;
+      
+    case       G_TOKEN_SYMBOL:
+      if (scanner->config->symbol_2_token)
+       *token_p = (GTokenType) value_p->v_symbol;
+      break;
+      
+    case       G_TOKEN_BINARY:
+    case       G_TOKEN_OCTAL:
+    case       G_TOKEN_HEX:
+      if (scanner->config->numbers_2_int)
+       *token_p = G_TOKEN_INT;
+      break;
+      
+    default:
+      break;
+    }
+  
+  if (*token_p == G_TOKEN_INT &&
+      scanner->config->int_2_float)
+    {
+      *token_p = G_TOKEN_FLOAT;
+      value_p->v_float = value_p->v_int;
+    }
+  
+  errno = 0;
+}
+
+static void
+g_scanner_get_token_ll (GScanner       *scanner,
+                        GTokenType     *token_p,
+                        GValue         *value_p,
+                        guint          *line_p,
+                        guint          *position_p)
+{
+  register GScannerConfig      *config;
+  register gboolean            in_comment_multi;
+  register gboolean            in_comment_single;
+  register gboolean            in_string_sq;
+  register gboolean            in_string_dq;
+  static   guchar              ch;
+  register GTokenType          token;
+  register GValue              value;
+  register GString             *gstring;
+  
+  config = scanner->config;
+  (*value_p).v_int = 0;
+  
+  if (scanner->token == G_TOKEN_EOF ||
+      (!scanner->text_len &&
+       (scanner->input_fd < 0 ||
+       scanner->peeked_char == 0)))
+    {
+      *token_p = G_TOKEN_EOF;
+      return;
+    }
+  
+  in_comment_multi = FALSE;
+  in_comment_single = FALSE;
+  in_string_sq = FALSE;
+  in_string_dq = FALSE;
+  gstring = NULL;
+  
+  do
+    {
+      register gboolean                dotted_float = FALSE;
+      
+      ch = g_scanner_get_char (scanner, line_p, position_p);
+      
+      value.v_int = 0;
+      token = G_TOKEN_NONE;
+      
+      /* this is *evil*, but needed ;(
+       * we first check for identifier first character, because         it
+       * might interfere with other key chars like slashes or numbers
+       */
+      if (config->scan_identifier &&
+         ch && strchr (config->cset_identifier_first, ch))
+       goto identifier_precedence;
+      
+      switch (ch)
+       {
+         register gboolean     in_number;
+         static         gchar          *endptr;
+         
+       case  0:
+         token = G_TOKEN_EOF;
+         (*position_p)++;
+         ch = 0;
+         break;
+         
+       case  '/':
+         if (!config->scan_comment_multi ||
+             g_scanner_peek_next_char (scanner) != '*')
+           goto default_case;
+         g_scanner_get_char (scanner, line_p, position_p);
+         token = G_TOKEN_COMMENT_MULTI;
+         in_comment_multi = TRUE;
+         gstring = g_string_new ("");
+         while ((ch = g_scanner_get_char (scanner, line_p, position_p)) != 0)
+           {
+             if (ch == '*' && g_scanner_peek_next_char (scanner) == '/')
+               {
+                 g_scanner_get_char (scanner, line_p, position_p);
+                 in_comment_multi = FALSE;
+                 break;
+               }
+             else
+               gstring = g_string_append_c (gstring, ch);
+           }
+         ch = 0;
+         break;
+         
+       case  '\'':
+         if (!config->scan_string_sq)
+           goto default_case;
+         token = G_TOKEN_STRING;
+         in_string_sq = TRUE;
+         gstring = g_string_new ("");
+         while ((ch = g_scanner_get_char (scanner, line_p, position_p)) != 0)
+           {
+             if (ch == '\'')
+               {
+                 in_string_sq = FALSE;
+                 break;
+               }
+             else
+               gstring = g_string_append_c (gstring, ch);
+           }
+         ch = 0;
+         break;
+         
+       case  '"':
+         if (!config->scan_string_dq)
+           goto default_case;
+         token = G_TOKEN_STRING;
+         in_string_dq = TRUE;
+         gstring = g_string_new ("");
+         while ((ch = g_scanner_get_char (scanner, line_p, position_p)) != 0)
+           {
+             if (ch == '"')
+               {
+                 in_string_dq = FALSE;
+                 break;
+               }
+             else
+               {
+                 if (ch == '\\')
+                   {
+                     ch = g_scanner_get_char (scanner, line_p, position_p);
+                     switch (ch)
+                       {
+                         register guint        i;
+                         register guint        fchar;
+                         
+                       case  0:
+                         break;
+                         
+                       case  '\\':
+                         gstring = g_string_append_c (gstring, '\\');
+                         break;
+                         
+                       case  'n':
+                         gstring = g_string_append_c (gstring, '\n');
+                         break;
+                         
+                       case  't':
+                         gstring = g_string_append_c (gstring, '\t');
+                         break;
+                         
+                       case  'r':
+                         gstring = g_string_append_c (gstring, '\r');
+                         break;
+                         
+                       case  'b':
+                         gstring = g_string_append_c (gstring, '\b');
+                         break;
+                         
+                       case  'f':
+                         gstring = g_string_append_c (gstring, '\f');
+                         break;
+                         
+                       case  '0':
+                       case  '1':
+                       case  '2':
+                       case  '3':
+                       case  '4':
+                       case  '5':
+                       case  '6':
+                       case  '7':
+                         i = ch - '0';
+                         fchar = g_scanner_peek_next_char (scanner);
+                         if (fchar >= '0' && fchar <= '7')
+                           {
+                             ch = g_scanner_get_char (scanner, line_p, position_p);
+                             i= i * 8 + ch - '0';
+                             fchar = g_scanner_peek_next_char (scanner);
+                             if (fchar >= '0' && fchar <= '7')
+                               {
+                                 ch = g_scanner_get_char (scanner, line_p, position_p);
+                                 i = i * 8 + ch - '0';
+                               }
+                           }
+                         gstring = g_string_append_c (gstring, i);
+                         break;
+                         
+                       default:
+                         gstring = g_string_append_c (gstring, ch);
+                         break;
+                       }
+                   }
+                 else
+                   gstring = g_string_append_c (gstring, ch);
+               }
+           }
+         ch = 0;
+         break;
+         
+       case  '.':
+         if (!config->scan_float)
+           goto default_case;
+         token = G_TOKEN_FLOAT;
+         dotted_float = TRUE;
+         ch = g_scanner_get_char (scanner, line_p, position_p);
+         goto number_parsing;
+         
+       case  '$':
+         if (!config->scan_hex_dollar)
+           goto default_case;
+         token = G_TOKEN_HEX;
+         ch = g_scanner_get_char (scanner, line_p, position_p);
+         goto number_parsing;
+         
+       case  '0':
+         if (config->scan_octal)
+           token = G_TOKEN_OCTAL;
+         else
+           token = G_TOKEN_INT;
+         ch = g_scanner_peek_next_char (scanner);
+         if (config->scan_hex && (ch == 'x' || ch == 'X'))
+           {
+             token = G_TOKEN_HEX;
+             g_scanner_get_char (scanner, line_p, position_p);
+             ch = g_scanner_get_char (scanner, line_p, position_p);
+             if (ch == 0)
+               {
+                 token = G_TOKEN_ERROR;
+                 value.v_error = G_ERR_UNEXP_EOF;
+                 (*position_p)++;
+                 break;
+               }
+             if (g_scanner_char_2_num (ch, 16) < 0)
+               {
+                 token = G_TOKEN_ERROR;
+                 value.v_error = G_ERR_DIGIT_RADIX;
+                 ch = 0;
+                 break;
+               }
+           }
+         else if (config->scan_binary && (ch == 'b' || ch == 'B'))
+           {
+             token = G_TOKEN_BINARY;
+             g_scanner_get_char (scanner, line_p, position_p);
+             ch = g_scanner_get_char (scanner, line_p, position_p);
+             if (ch == 0)
+               {
+                 token = G_TOKEN_ERROR;
+                 value.v_error = G_ERR_UNEXP_EOF;
+                 (*position_p)++;
+                 break;
+               }
+             if (g_scanner_char_2_num (ch, 10) < 0)
+               {
+                 token = G_TOKEN_ERROR;
+                 value.v_error = G_ERR_NON_DIGIT_IN_CONST;
+                 ch = 0;
+                 break;
+               }
+           }
+         else
+           ch = '0';
+         /* fall through */
+       case  '1':
+       case  '2':
+       case  '3':
+       case  '4':
+       case  '5':
+       case  '6':
+       case  '7':
+       case  '8':
+       case  '9':
+       number_parsing:
+       if (token == G_TOKEN_NONE)
+         token = G_TOKEN_INT;
+       
+       gstring = g_string_new (dotted_float ? "0." : "");
+       gstring = g_string_append_c (gstring, ch);
+       in_number = TRUE;
+       while (in_number)
+         {
+           register gboolean is_E;
+           
+           is_E = (ch == 'e' || ch == 'E') && token == G_TOKEN_FLOAT;
+           ch = g_scanner_peek_next_char (scanner);
+           
+           if (g_scanner_char_2_num (ch, 36) >= 0 ||
+               (config->scan_float && ch == '.') ||
+               (is_E && ch == '+') ||
+               (is_E && ch == '-') )
+             ch = g_scanner_get_char (scanner, line_p, position_p);
+           else
+             in_number = FALSE;
+           
+           if (in_number)
+             switch (ch)
+               {
+               case  '.':
+                 if (token != G_TOKEN_INT &&
+                     token != G_TOKEN_OCTAL)
+                   {
+                     token = G_TOKEN_ERROR;
+                     if (token == G_TOKEN_FLOAT)
+                       value.v_error = G_ERR_FLOAT_MALFORMED;
+                     else
+                       value.v_error = G_ERR_FLOAT_RADIX;
+                     in_number = FALSE;
+                   }
+                 else
+                   {
+                     token = G_TOKEN_FLOAT;
+                     gstring = g_string_append_c (gstring, ch);
+                   }
+                 break;
+                 
+               case    '0':
+               case  '1':
+               case  '2':
+               case  '3':
+               case  '4':
+               case  '5':
+               case  '6':
+               case  '7':
+               case  '8':
+               case  '9':
+                 gstring = g_string_append_c (gstring, ch);
+                 break;
+                 
+               case    '-':
+               case    '+':
+                 if (token != G_TOKEN_FLOAT)
+                   {
+                     token = G_TOKEN_ERROR;
+                     value.v_error = G_ERR_NON_DIGIT_IN_CONST;
+                     in_number = FALSE;
+                   }
+                 else
+                   gstring = g_string_append_c (gstring, ch);
+                 break;
+                 
+               case    'e':
+               case    'E':
+                 if ((token != G_TOKEN_HEX && !config->scan_float) ||
+                     (token != G_TOKEN_HEX &&
+                      token != G_TOKEN_OCTAL &&
+                      token != G_TOKEN_FLOAT &&
+                      token != G_TOKEN_INT))
+                   {
+                     token = G_TOKEN_ERROR;
+                     value.v_error = G_ERR_NON_DIGIT_IN_CONST;
+                     in_number = FALSE;
+                   }
+                 else
+                   {
+                     if (token != G_TOKEN_HEX)
+                       token = G_TOKEN_FLOAT;
+                     gstring = g_string_append_c (gstring, ch);
+                   }
+                 break;
+                 
+               default:
+                 if (token != G_TOKEN_HEX)
+                   {
+                     token = G_TOKEN_ERROR;
+                     value.v_error = G_ERR_NON_DIGIT_IN_CONST;
+                     in_number = FALSE;
+                   }
+                 else
+                   gstring = g_string_append_c (gstring, ch);
+                 break;
+               }
+         }
+       endptr = NULL;
+       switch (token)
+         {
+         case  G_TOKEN_BINARY:
+           value.v_binary = strtol (gstring->str, &endptr, 2);
+           break;
+           
+         case  G_TOKEN_OCTAL:
+           value.v_octal = strtol (gstring->str, &endptr, 8);
+           break;
+           
+         case  G_TOKEN_INT:
+           value.v_int = strtol (gstring->str, &endptr, 10);
+           break;
+           
+         case  G_TOKEN_FLOAT:
+           value.v_float = g_strtod (gstring->str, &endptr);
+           break;
+           
+         case  G_TOKEN_HEX:
+           value.v_hex = strtol (gstring->str, &endptr, 16);
+           break;
+           
+         default:
+           break;
+         }
+       if (endptr && *endptr)
+         {
+           token = G_TOKEN_ERROR;
+           if (*endptr == 'e' || *endptr == 'E')
+             value.v_error = G_ERR_NON_DIGIT_IN_CONST;
+           else
+             value.v_error = G_ERR_DIGIT_RADIX;
+         }
+       g_string_free (gstring, TRUE);
+       gstring = NULL;
+       ch = 0;
+       break;
+       
+       default:
+       default_case:
+       if (config->cpair_comment_single &&
+           ch == config->cpair_comment_single[0])
+         {
+           token = G_TOKEN_COMMENT_SINGLE;
+           in_comment_single = TRUE;
+           gstring = g_string_new ("");
+           while ((ch = g_scanner_get_char (scanner,
+                                            line_p,
+                                            position_p)) != 0)
+             {
+               if (ch == config->cpair_comment_single[1])
+                 {
+                   in_comment_single = FALSE;
+                   ch = 0;
+                   break;
+                 }
+               
+               gstring = g_string_append_c (gstring, ch);
+               ch = 0;
+             }
+         }
+       else if (config->scan_identifier && ch &&
+                strchr (config->cset_identifier_first, ch))
+         {
+         identifier_precedence:
+           
+           if (config->cset_identifier_nth && ch &&
+               strchr (config->cset_identifier_nth,
+                       g_scanner_peek_next_char (scanner)))
+             {
+               token = G_TOKEN_IDENTIFIER;
+               gstring = g_string_new ("");
+               gstring = g_string_append_c (gstring, ch);
+               do
+                 {
+                   ch = g_scanner_get_char (scanner, line_p, position_p);
+                   gstring = g_string_append_c (gstring, ch);
+                   ch = g_scanner_peek_next_char (scanner);
+                 }
+               while (ch && strchr (config->cset_identifier_nth, ch));
+               ch = 0;
+             }
+           else if (config->scan_identifier_1char)
+             {
+               token = G_TOKEN_IDENTIFIER;
+               value.v_identifier = g_new0 (gchar, 2);
+               value.v_identifier[0] = ch;
+               ch = 0;
+             }
+         }
+       if (ch)
+         {
+           if (config->char_2_token)
+             token = ch;
+           else
+             {
+               token = G_TOKEN_CHAR;
+               value.v_char = ch;
+             }
+           ch = 0;
+         }
+       break;
+       }
+      g_assert (ch == 0 && token != G_TOKEN_NONE);
+    }
+  while (ch != 0);
+  
+  if (in_comment_multi ||
+      in_comment_single ||
+      in_string_sq ||
+      in_string_dq)
+    {
+      token = G_TOKEN_ERROR;
+      if (gstring)
+       {
+         g_string_free (gstring, TRUE);
+         gstring = NULL;
+       }
+      (*position_p)++;
+      if (in_comment_multi || in_comment_single)
+       value.v_error = G_ERR_UNEXP_EOF_IN_COMMENT;
+      else if (in_string_sq || in_string_dq)
+       value.v_error = G_ERR_UNEXP_EOF_IN_STRING;
+    }
+  
+  if (gstring)
+    {
+      value.v_string = gstring->str;
+      g_string_free (gstring, FALSE);
+      gstring = NULL;
+    }
+  
+  if (token == G_TOKEN_IDENTIFIER &&
+      config->scan_symbols)
+    {
+      register GScannerHashVal *hash_val;
+      
+      hash_val = g_scanner_lookup_internal (scanner, value.v_identifier);
+      
+      if (hash_val)
+       {
+         g_free (value.v_identifier);
+         token = G_TOKEN_SYMBOL;
+         value.v_symbol = hash_val->value;
+       }
+    }
+
+  if (token == G_TOKEN_IDENTIFIER &&
+      config->scan_identifier_NULL &&
+      strlen (value.v_identifier) == 4)
+    {
+      gchar *null_upper = "NULL";
+      gchar *null_lower = "null";
+      
+      if (scanner->config->case_sensitive)
+       {
+         if (value.v_identifier[0] == null_upper[0] &&
+             value.v_identifier[1] == null_upper[1] &&
+             value.v_identifier[2] == null_upper[2] &&
+             value.v_identifier[3] == null_upper[3])
+           token = G_TOKEN_IDENTIFIER_NULL;
+       }
+      else
+       {
+         if ((value.v_identifier[0] == null_upper[0] ||
+              value.v_identifier[0] == null_lower[0]) &&
+             (value.v_identifier[1] == null_upper[1] ||
+              value.v_identifier[1] == null_lower[1]) &&
+             (value.v_identifier[2] == null_upper[2] ||
+              value.v_identifier[2] == null_lower[2]) &&
+             (value.v_identifier[3] == null_upper[3] ||
+              value.v_identifier[3] == null_lower[3]))
+           token = G_TOKEN_IDENTIFIER_NULL;
+       }
+    }
+  
+  *token_p = token;
+  *value_p = value;
+}
diff --git a/glib/gslist.c b/glib/gslist.c
new file mode 100644 (file)
index 0000000..3a201b4
--- /dev/null
@@ -0,0 +1,456 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "glib.h"
+
+
+typedef struct _GRealListAllocator GRealListAllocator;
+
+struct _GRealListAllocator
+{
+  GMemChunk *list_mem_chunk;
+  GSList    *free_list;
+};
+
+
+static GRealListAllocator *default_allocator = NULL;
+static GRealListAllocator *current_allocator = NULL;
+
+GListAllocator*
+g_slist_set_allocator (GListAllocator* fallocator)
+{
+  GRealListAllocator* allocator = (GRealListAllocator *) fallocator;
+  GRealListAllocator* old_allocator = current_allocator;
+
+  if (allocator)
+    current_allocator = allocator;
+  else
+    {
+      if (!default_allocator)
+       default_allocator = (GRealListAllocator*) g_list_allocator_new ();
+      current_allocator = default_allocator;
+    }
+
+  if (!current_allocator->list_mem_chunk)
+    current_allocator->list_mem_chunk = g_mem_chunk_new ("slist mem chunk",
+                                                        sizeof (GSList),
+                                                        1024,
+                                                        G_ALLOC_ONLY);
+
+  return (GListAllocator*) (old_allocator == default_allocator ? NULL : old_allocator);
+}
+
+
+GSList*
+g_slist_alloc (void)
+{
+  GSList *new_list;
+
+  g_slist_set_allocator (NULL);
+  if (current_allocator->free_list)
+    {
+      new_list = current_allocator->free_list;
+      current_allocator->free_list = current_allocator->free_list->next;
+    }
+  else
+    {
+      new_list = g_chunk_new (GSList, current_allocator->list_mem_chunk);
+    }
+
+  new_list->data = NULL;
+  new_list->next = NULL;
+
+  return new_list;
+}
+
+void
+g_slist_free (GSList *list)
+{
+  GSList *last;
+
+  if (list)
+    {
+      last = g_slist_last (list);
+      last->next = current_allocator->free_list;
+      current_allocator->free_list = list;
+    }
+}
+
+void
+g_slist_free_1 (GSList *list)
+{
+  if (list)
+    {
+      list->next = current_allocator->free_list;
+      current_allocator->free_list = list;
+    }
+}
+
+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_reverse (GSList *list)
+{
+  GSList *tmp;
+  GSList *prev;
+  GSList *last;
+
+  last = NULL;
+  prev = NULL;
+
+  while (list)
+    {
+      last = list;
+
+      tmp = list->next;
+      list->next = prev;
+
+      prev = list;
+      list = tmp;
+    }
+
+  return last;
+}
+
+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;
+    }
+}
diff --git a/glib/gstring.c b/glib/gstring.c
new file mode 100644 (file)
index 0000000..8350552
--- /dev/null
@@ -0,0 +1,647 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <glib.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.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;
+};
+
+
+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;
+}
+
+/* a char* hash function from ASU */
+guint
+g_str_hash (gconstpointer v)
+{
+  const char *s = (char*)v;
+  const char *p;
+  guint h=0, g;
+
+  for(p = s; *p != '\0'; p += 1) {
+    h = ( h << 4 ) + *p;
+    if ( ( g = h & 0xf0000000 ) ) {
+      h = h ^ (g >> 24);
+      h = h ^ g;
+    }
+  }
+
+  return h /* % M */;
+}
+
+
+/* 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)
+    {
+      GListAllocator *tmp_allocator = g_slist_set_allocator (NULL);
+
+      for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next)
+       g_free (tmp_list->data);
+
+      g_slist_free (chunk->storage_list);
+
+      g_slist_set_allocator (tmp_allocator);
+    }
+
+  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)
+    {
+      GListAllocator *tmp_allocator = g_slist_set_allocator (NULL);
+      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;
+
+      g_slist_set_allocator (tmp_allocator);
+    }
+
+  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;
+
+  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);
+
+  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_mem_chunk_free (string_mem_chunk, string);
+}
+
+GString*
+g_string_assign (GString *lval,
+                const gchar *rval)
+{
+  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);
+
+  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;
+  gchar *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;
+  gchar *s;
+
+  g_return_val_if_fail (string != NULL, NULL);
+
+  s = string->str;
+
+  while (*s)
+    {
+      *s = toupper (*s);
+      s++;
+    }
+
+  return fstring;
+}
+
+static int
+get_length_upper_bound (const gchar* fmt, va_list *args)
+{
+  int len = 0;
+  int short_int;
+  int long_int;
+  int done;
+  char *tmp;
+
+  while (*fmt)
+    {
+      char c = *fmt++;
+
+      short_int = FALSE;
+      long_int = FALSE;
+
+      if (c == '%')
+       {
+         done = FALSE;
+         while (*fmt && !done)
+           {
+             switch (*fmt++)
+               {
+               case '*':
+                 len += va_arg(*args, int);
+                 break;
+               case '1':
+               case '2':
+               case '3':
+               case '4':
+               case '5':
+               case '6':
+               case '7':
+               case '8':
+               case '9':
+                 fmt -= 1;
+                 len += strtol (fmt, (char **)&fmt, 10);
+                 break;
+               case 'h':
+                 short_int = TRUE;
+                 break;
+               case 'l':
+                 long_int = TRUE;
+                 break;
+
+                 /* I ignore 'q' and 'L', they're not portable anyway. */
+
+               case 's':
+                 tmp = va_arg(*args, char *);
+                 if(tmp)
+                   len += strlen (tmp);
+                 else
+                   len += strlen ("(null)");
+                 done = TRUE;
+                 break;
+               case 'd':
+               case 'i':
+               case 'o':
+               case 'u':
+               case 'x':
+               case 'X':
+                 if (long_int)
+                   (void)va_arg (*args, long);
+                 else if (short_int)
+                   (void)va_arg (*args, int);
+                 else
+                   (void)va_arg (*args, int);
+                 len += 32;
+                 done = TRUE;
+                 break;
+               case 'D':
+               case 'O':
+               case 'U':
+                 (void)va_arg (*args, long);
+                 len += 32;
+                 done = TRUE;
+                 break;
+               case 'e':
+               case 'E':
+               case 'f':
+               case 'g':
+                 (void)va_arg (*args, double);
+                 len += 32;
+                 done = TRUE;
+                 break;
+               case 'c':
+                 (void)va_arg (*args, int);
+                 len += 1;
+                 done = TRUE;
+                 break;
+               case 'p':
+               case 'n':
+                 (void)va_arg (*args, void*);
+                 len += 32;
+                 done = TRUE;
+                 break;
+               case '%':
+                 len += 1;
+                 done = TRUE;
+                 break;
+               default:
+                 break;
+               }
+           }
+       }
+      else
+       len += 1;
+    }
+
+  return len;
+}
+
+char*
+g_vsprintf (const gchar *fmt,
+           va_list *args,
+           va_list *args2)
+{
+  static gchar *buf = NULL;
+  static gint   alloc = 0;
+
+  gint len = get_length_upper_bound (fmt, args);
+
+  if (len >= alloc)
+    {
+      if (buf)
+       g_free (buf);
+
+      alloc = nearest_pow (MAX(len + 1, 1024));
+
+      buf = g_new (char, alloc);
+    }
+
+  vsprintf (buf, fmt, *args2);
+
+  return buf;
+}
+
+static void
+g_string_sprintfa_int (GString *string,
+                      const gchar *fmt,
+                      va_list *args,
+                      va_list *args2)
+{
+  g_string_append (string, g_vsprintf (fmt, args, args2));
+}
+
+void
+g_string_sprintf (GString *string,
+                 const gchar *fmt,
+                 ...)
+{
+  va_list args, args2;
+
+  va_start(args, fmt);
+  va_start(args2, fmt);
+
+  g_string_truncate (string, 0);
+
+  g_string_sprintfa_int (string, fmt, &args, &args2);
+
+  va_end(args);
+  va_end(args2);
+}
+
+void
+g_string_sprintfa (GString *string,
+                  const gchar *fmt,
+                  ...)
+{
+  va_list args, args2;
+
+  va_start(args, fmt);
+  va_start(args2, fmt);
+
+  g_string_sprintfa_int (string, fmt, &args, &args2);
+
+  va_end(args);
+  va_end(args2);
+}
diff --git a/glib/gtimer.c b/glib/gtimer.c
new file mode 100644 (file)
index 0000000..47946b3
--- /dev/null
@@ -0,0 +1,120 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <sys/time.h>
+#include <unistd.h>
+#include "glib.h"
+
+
+typedef struct _GRealTimer GRealTimer;
+
+struct _GRealTimer
+{
+  struct timeval start;
+  struct timeval end;
+  gint active;
+};
+
+
+GTimer*
+g_timer_new (void)
+{
+  GRealTimer *timer;
+
+  timer = g_new (GRealTimer, 1);
+  timer->active = TRUE;
+
+  gettimeofday (&timer->start, NULL);
+
+  return ((GTimer*) timer);
+}
+
+void
+g_timer_destroy (GTimer *timer)
+{
+  g_assert (timer != NULL);
+
+  g_free (timer);
+}
+
+void
+g_timer_start (GTimer *timer)
+{
+  GRealTimer *rtimer;
+
+  g_assert (timer != NULL);
+
+  rtimer = (GRealTimer*) timer;
+  gettimeofday (&rtimer->start, NULL);
+  rtimer->active = 1;
+}
+
+void
+g_timer_stop (GTimer *timer)
+{
+  GRealTimer *rtimer;
+
+  g_assert (timer != NULL);
+
+  rtimer = (GRealTimer*) timer;
+  gettimeofday (&rtimer->end, NULL);
+  rtimer->active = 0;
+}
+
+void
+g_timer_reset (GTimer *timer)
+{
+  GRealTimer *rtimer;
+
+  g_assert (timer != NULL);
+
+  rtimer = (GRealTimer*) timer;
+  gettimeofday (&rtimer->start, NULL);
+}
+
+gdouble
+g_timer_elapsed (GTimer *timer,
+                gulong *microseconds)
+{
+  GRealTimer *rtimer;
+  struct timeval elapsed;
+  gdouble total;
+
+  g_assert (timer != NULL);
+
+  rtimer = (GRealTimer*) timer;
+
+  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 (microseconds)
+    *microseconds = elapsed.tv_usec;
+
+  return total;
+}
diff --git a/glib/gtree.c b/glib/gtree.c
new file mode 100644 (file)
index 0000000..981ff39
--- /dev/null
@@ -0,0 +1,719 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "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);
+
+
+static GMemChunk *node_mem_chunk = NULL;
+static GSList *node_free_list = NULL;
+
+
+GTree*
+g_tree_new (GCompareFunc key_compare_func)
+{
+  GRealTree *rtree;
+
+  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;
+
+  g_return_if_fail (rtree->root != NULL);
+
+  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;
+    }
+}
+
+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);
+  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);
+  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);
+  return 0;
+}
+
+
+static GTreeNode*
+g_tree_node_new (gpointer key,
+                gpointer value)
+{
+  GTreeNode *node;
+  GSList *tmp_list;
+
+  if (node_free_list)
+    {
+      tmp_list = node_free_list;
+      node_free_list = node_free_list->next;
+
+      node = tmp_list->data;
+
+      {
+       GListAllocator *tmp_allocator = g_list_set_allocator (NULL);
+       g_slist_free_1 (tmp_list);
+       g_list_set_allocator (tmp_allocator);
+      }
+    }
+  else
+    {
+      if (!node_mem_chunk)
+       node_mem_chunk = g_mem_chunk_new ("tree node mem chunk", sizeof (GTreeNode), 1024, G_ALLOC_ONLY);
+
+      node = g_chunk_new (GTreeNode, node_mem_chunk);
+    }
+
+  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)
+    {
+      node_free_list = g_slist_prepend (node_free_list, node);
+      g_tree_node_destroy (node->right);
+      g_tree_node_destroy (node->left);
+    }
+}
+
+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 *garbage;
+  GTreeNode *new_root;
+  gint old_balance;
+  gint cmp;
+
+  if (!node)
+    return NULL;
+
+  cmp = (* compare) (key, node->key);
+  if (cmp == 0)
+    {
+      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);
+       }
+
+      node_free_list = g_slist_prepend (node_free_list, garbage);
+    }
+  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;
+  GTreeNode *right;
+  gint a_bal;
+  gint b_bal;
+
+  left = node->left;
+  right = node->right;
+
+  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_print ("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);
+    }
+}
diff --git a/glib/gutils.c b/glib/gutils.c
new file mode 100644 (file)
index 0000000..8528163
--- /dev/null
@@ -0,0 +1,858 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+#include <ctype.h>             /* For tolower() */
+#include "glib.h"
+
+const guint glib_major_version = GLIB_MAJOR_VERSION;
+const guint glib_minor_version = GLIB_MINOR_VERSION;
+const guint glib_micro_version = GLIB_MICRO_VERSION;
+
+extern char* g_vsprintf (const gchar *fmt, va_list *args, va_list *args2);
+
+gchar*
+g_strdup (const gchar *str)
+{
+  gchar *new_str;
+  
+  new_str = NULL;
+  if (str)
+    {
+      new_str = g_new (char, strlen (str) + 1);
+      strcpy (new_str, str);
+    }
+  
+  return new_str;
+}
+
+gchar*
+g_strconcat (const gchar *string1, ...)
+{
+  guint          l;
+  va_list args;
+  gchar          *s;
+  gchar          *concat;
+  
+  g_return_val_if_fail (string1 != NULL, NULL);
+  
+  l = 1 + strlen (string1);
+  va_start (args, string1);
+  s = va_arg (args, gchar*);
+  while (s)
+    {
+      l += strlen (s);
+      s = va_arg (args, gchar*);
+    }
+  va_end (args);
+  
+  concat = g_new (gchar, l);
+  concat[0] = 0;
+  
+  strcat (concat, string1);
+  va_start (args, string1);
+  s = va_arg (args, gchar*);
+  while (s)
+    {
+      strcat (concat, s);
+      s = va_arg (args, gchar*);
+    }
+  va_end (args);
+  
+  return concat;
+}
+
+gdouble
+g_strtod (const gchar *nptr,
+         gchar **endptr)
+{
+  gchar *fail_pos_1;
+  gchar *fail_pos_2;
+  gdouble val_1;
+  gdouble val_2 = 0;
+
+  g_return_val_if_fail (nptr != NULL, 0);
+
+  fail_pos_1 = NULL;
+  fail_pos_2 = NULL;
+
+  val_1 = strtod (nptr, &fail_pos_1);
+
+  if (fail_pos_1 && fail_pos_1[0] != 0)
+    {
+      gchar *old_locale;
+
+      old_locale = setlocale (LC_NUMERIC, "C");
+      val_2 = strtod (nptr, &fail_pos_2);
+      setlocale (LC_NUMERIC, old_locale);
+    }
+
+  if (!fail_pos_1 || fail_pos_1[0] == 0 || fail_pos_1 >= fail_pos_2)
+    {
+      if (endptr)
+       *endptr = fail_pos_1;
+      return val_1;
+    }
+  else
+    {
+      if (endptr)
+       *endptr = fail_pos_2;
+      return val_2;
+    }
+}
+
+gchar*
+g_strerror (gint errnum)
+{
+  static char msg[64];
+  
+#ifdef HAVE_STRERROR
+  return strerror (errnum);
+#elif NO_SYS_ERRLIST
+  switch (errnum)
+    {
+#ifdef E2BIG
+    case E2BIG: return "argument list too long";
+#endif
+#ifdef EACCES
+    case EACCES: return "permission denied";
+#endif
+#ifdef EADDRINUSE
+    case EADDRINUSE: return "address already in use";
+#endif
+#ifdef EADDRNOTAVAIL
+    case EADDRNOTAVAIL: return "can't assign requested address";
+#endif
+#ifdef EADV
+    case EADV: return "advertise error";
+#endif
+#ifdef EAFNOSUPPORT
+    case EAFNOSUPPORT: return "address family not supported by protocol family";
+#endif
+#ifdef EAGAIN
+    case EAGAIN: return "try again";
+#endif
+#ifdef EALIGN
+    case EALIGN: return "EALIGN";
+#endif
+#ifdef EALREADY
+    case EALREADY: return "operation already in progress";
+#endif
+#ifdef EBADE
+    case EBADE: return "bad exchange descriptor";
+#endif
+#ifdef EBADF
+    case EBADF: return "bad file number";
+#endif
+#ifdef EBADFD
+    case EBADFD: return "file descriptor in bad state";
+#endif
+#ifdef EBADMSG
+    case EBADMSG: return "not a data message";
+#endif
+#ifdef EBADR
+    case EBADR: return "bad request descriptor";
+#endif
+#ifdef EBADRPC
+    case EBADRPC: return "RPC structure is bad";
+#endif
+#ifdef EBADRQC
+    case EBADRQC: return "bad request code";
+#endif
+#ifdef EBADSLT
+    case EBADSLT: return "invalid slot";
+#endif
+#ifdef EBFONT
+    case EBFONT: return "bad font file format";
+#endif
+#ifdef EBUSY
+    case EBUSY: return "mount device busy";
+#endif
+#ifdef ECHILD
+    case ECHILD: return "no children";
+#endif
+#ifdef ECHRNG
+    case ECHRNG: return "channel number out of range";
+#endif
+#ifdef ECOMM
+    case ECOMM: return "communication error on send";
+#endif
+#ifdef ECONNABORTED
+    case ECONNABORTED: return "software caused connection abort";
+#endif
+#ifdef ECONNREFUSED
+    case ECONNREFUSED: return "connection refused";
+#endif
+#ifdef ECONNRESET
+    case ECONNRESET: return "connection reset by peer";
+#endif
+#if defined(EDEADLK) && (!defined(EWOULDBLOCK) || (EDEADLK != EWOULDBLOCK))
+    case EDEADLK: return "resource deadlock avoided";
+#endif
+#ifdef EDEADLOCK
+    case EDEADLOCK: return "resource deadlock avoided";
+#endif
+#ifdef EDESTADDRREQ
+    case EDESTADDRREQ: return "destination address required";
+#endif
+#ifdef EDIRTY
+    case EDIRTY: return "mounting a dirty fs w/o force";
+#endif
+#ifdef EDOM
+    case EDOM: return "math argument out of range";
+#endif
+#ifdef EDOTDOT
+    case EDOTDOT: return "cross mount point";
+#endif
+#ifdef EDQUOT
+    case EDQUOT: return "disk quota exceeded";
+#endif
+#ifdef EDUPPKG
+    case EDUPPKG: return "duplicate package name";
+#endif
+#ifdef EEXIST
+    case EEXIST: return "file already exists";
+#endif
+#ifdef EFAULT
+    case EFAULT: return "bad address in system call argument";
+#endif
+#ifdef EFBIG
+    case EFBIG: return "file too large";
+#endif
+#ifdef EHOSTDOWN
+    case EHOSTDOWN: return "host is down";
+#endif
+#ifdef EHOSTUNREACH
+    case EHOSTUNREACH: return "host is unreachable";
+#endif
+#ifdef EIDRM
+    case EIDRM: return "identifier removed";
+#endif
+#ifdef EINIT
+    case EINIT: return "initialization error";
+#endif
+#ifdef EINPROGRESS
+    case EINPROGRESS: return "operation now in progress";
+#endif
+#ifdef EINTR
+    case EINTR: return "interrupted system call";
+#endif
+#ifdef EINVAL
+    case EINVAL: return "invalid argument";
+#endif
+#ifdef EIO
+    case EIO: return "I/O error";
+#endif
+#ifdef EISCONN
+    case EISCONN: return "socket is already connected";
+#endif
+#ifdef EISDIR
+    case EISDIR: return "illegal operation on a directory";
+#endif
+#ifdef EISNAME
+    case EISNAM: return "is a name file";
+#endif
+#ifdef ELBIN
+    case ELBIN: return "ELBIN";
+#endif
+#ifdef EL2HLT
+    case EL2HLT: return "level 2 halted";
+#endif
+#ifdef EL2NSYNC
+    case EL2NSYNC: return "level 2 not synchronized";
+#endif
+#ifdef EL3HLT
+    case EL3HLT: return "level 3 halted";
+#endif
+#ifdef EL3RST
+    case EL3RST: return "level 3 reset";
+#endif
+#ifdef ELIBACC
+    case ELIBACC: return "can not access a needed shared library";
+#endif
+#ifdef ELIBBAD
+    case ELIBBAD: return "accessing a corrupted shared library";
+#endif
+#ifdef ELIBEXEC
+    case ELIBEXEC: return "can not exec a shared library directly";
+#endif
+#ifdef ELIBMAX
+    case ELIBMAX: return "attempting to link in more shared libraries than system limit";
+#endif
+#ifdef ELIBSCN
+    case ELIBSCN: return ".lib section in a.out corrupted";
+#endif
+#ifdef ELNRNG
+    case ELNRNG: return "link number out of range";
+#endif
+#ifdef ELOOP
+    case ELOOP: return "too many levels of symbolic links";
+#endif
+#ifdef EMFILE
+    case EMFILE: return "too many open files";
+#endif
+#ifdef EMLINK
+    case EMLINK: return "too many links";
+#endif
+#ifdef EMSGSIZE
+    case EMSGSIZE: return "message too long";
+#endif
+#ifdef EMULTIHOP
+    case EMULTIHOP: return "multihop attempted";
+#endif
+#ifdef ENAMETOOLONG
+    case ENAMETOOLONG: return "file name too long";
+#endif
+#ifdef ENAVAIL
+    case ENAVAIL: return "not available";
+#endif
+#ifdef ENET
+    case ENET: return "ENET";
+#endif
+#ifdef ENETDOWN
+    case ENETDOWN: return "network is down";
+#endif
+#ifdef ENETRESET
+    case ENETRESET: return "network dropped connection on reset";
+#endif
+#ifdef ENETUNREACH
+    case ENETUNREACH: return "network is unreachable";
+#endif
+#ifdef ENFILE
+    case ENFILE: return "file table overflow";
+#endif
+#ifdef ENOANO
+    case ENOANO: return "anode table overflow";
+#endif
+#if defined(ENOBUFS) && (!defined(ENOSR) || (ENOBUFS != ENOSR))
+    case ENOBUFS: return "no buffer space available";
+#endif
+#ifdef ENOCSI
+    case ENOCSI: return "no CSI structure available";
+#endif
+#ifdef ENODATA
+    case ENODATA: return "no data available";
+#endif
+#ifdef ENODEV
+    case ENODEV: return "no such device";
+#endif
+#ifdef ENOENT
+    case ENOENT: return "no such file or directory";
+#endif
+#ifdef ENOEXEC
+    case ENOEXEC: return "exec format error";
+#endif
+#ifdef ENOLCK
+    case ENOLCK: return "no locks available";
+#endif
+#ifdef ENOLINK
+    case ENOLINK: return "link has be severed";
+#endif
+#ifdef ENOMEM
+    case ENOMEM: return "not enough memory";
+#endif
+#ifdef ENOMSG
+    case ENOMSG: return "no message of desired type";
+#endif
+#ifdef ENONET
+    case ENONET: return "machine is not on the network";
+#endif
+#ifdef ENOPKG
+    case ENOPKG: return "package not installed";
+#endif
+#ifdef ENOPROTOOPT
+    case ENOPROTOOPT: return "bad proocol option";
+#endif
+#ifdef ENOSPC
+    case ENOSPC: return "no space left on device";
+#endif
+#ifdef ENOSR
+    case ENOSR: return "out of stream resources";
+#endif
+#ifdef ENOSTR
+    case ENOSTR: return "not a stream device";
+#endif
+#ifdef ENOSYM
+    case ENOSYM: return "unresolved symbol name";
+#endif
+#ifdef ENOSYS
+    case ENOSYS: return "function not implemented";
+#endif
+#ifdef ENOTBLK
+    case ENOTBLK: return "block device required";
+#endif
+#ifdef ENOTCONN
+    case ENOTCONN: return "socket is not connected";
+#endif
+#ifdef ENOTDIR
+    case ENOTDIR: return "not a directory";
+#endif
+#ifdef ENOTEMPTY
+    case ENOTEMPTY: return "directory not empty";
+#endif
+#ifdef ENOTNAM
+    case ENOTNAM: return "not a name file";
+#endif
+#ifdef ENOTSOCK
+    case ENOTSOCK: return "socket operation on non-socket";
+#endif
+#ifdef ENOTTY
+    case ENOTTY: return "inappropriate device for ioctl";
+#endif
+#ifdef ENOTUNIQ
+    case ENOTUNIQ: return "name not unique on network";
+#endif
+#ifdef ENXIO
+    case ENXIO: return "no such device or address";
+#endif
+#ifdef EOPNOTSUPP
+    case EOPNOTSUPP: return "operation not supported on socket";
+#endif
+#ifdef EPERM
+    case EPERM: return "not owner";
+#endif
+#ifdef EPFNOSUPPORT
+    case EPFNOSUPPORT: return "protocol family not supported";
+#endif
+#ifdef EPIPE
+    case EPIPE: return "broken pipe";
+#endif
+#ifdef EPROCLIM
+    case EPROCLIM: return "too many processes";
+#endif
+#ifdef EPROCUNAVAIL
+    case EPROCUNAVAIL: return "bad procedure for program";
+#endif
+#ifdef EPROGMISMATCH
+    case EPROGMISMATCH: return "program version wrong";
+#endif
+#ifdef EPROGUNAVAIL
+    case EPROGUNAVAIL: return "RPC program not available";
+#endif
+#ifdef EPROTO
+    case EPROTO: return "protocol error";
+#endif
+#ifdef EPROTONOSUPPORT
+    case EPROTONOSUPPORT: return "protocol not suppored";
+#endif
+#ifdef EPROTOTYPE
+    case EPROTOTYPE: return "protocol wrong type for socket";
+#endif
+#ifdef ERANGE
+    case ERANGE: return "math result unrepresentable";
+#endif
+#if defined(EREFUSED) && (!defined(ECONNREFUSED) || (EREFUSED != ECONNREFUSED))
+    case EREFUSED: return "EREFUSED";
+#endif
+#ifdef EREMCHG
+    case EREMCHG: return "remote address changed";
+#endif
+#ifdef EREMDEV
+    case EREMDEV: return "remote device";
+#endif
+#ifdef EREMOTE
+    case EREMOTE: return "pathname hit remote file system";
+#endif
+#ifdef EREMOTEIO
+    case EREMOTEIO: return "remote i/o error";
+#endif
+#ifdef EREMOTERELEASE
+    case EREMOTERELEASE: return "EREMOTERELEASE";
+#endif
+#ifdef EROFS
+    case EROFS: return "read-only file system";
+#endif
+#ifdef ERPCMISMATCH
+    case ERPCMISMATCH: return "RPC version is wrong";
+#endif
+#ifdef ERREMOTE
+    case ERREMOTE: return "object is remote";
+#endif
+#ifdef ESHUTDOWN
+    case ESHUTDOWN: return "can't send afer socket shutdown";
+#endif
+#ifdef ESOCKTNOSUPPORT
+    case ESOCKTNOSUPPORT: return "socket type not supported";
+#endif
+#ifdef ESPIPE
+    case ESPIPE: return "invalid seek";
+#endif
+#ifdef ESRCH
+    case ESRCH: return "no such process";
+#endif
+#ifdef ESRMNT
+    case ESRMNT: return "srmount error";
+#endif
+#ifdef ESTALE
+    case ESTALE: return "stale remote file handle";
+#endif
+#ifdef ESUCCESS
+    case ESUCCESS: return "Error 0";
+#endif
+#ifdef ETIME
+    case ETIME: return "timer expired";
+#endif
+#ifdef ETIMEDOUT
+    case ETIMEDOUT: return "connection timed out";
+#endif
+#ifdef ETOOMANYREFS
+    case ETOOMANYREFS: return "too many references: can't splice";
+#endif
+#ifdef ETXTBSY
+    case ETXTBSY: return "text file or pseudo-device busy";
+#endif
+#ifdef EUCLEAN
+    case EUCLEAN: return "structure needs cleaning";
+#endif
+#ifdef EUNATCH
+    case EUNATCH: return "protocol driver not attached";
+#endif
+#ifdef EUSERS
+    case EUSERS: return "too many users";
+#endif
+#ifdef EVERSION
+    case EVERSION: return "version mismatch";
+#endif
+#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
+    case EWOULDBLOCK: return "operation would block";
+#endif
+#ifdef EXDEV
+    case EXDEV: return "cross-domain link";
+#endif
+#ifdef EXFULL
+    case EXFULL: return "message tables full";
+#endif
+    }
+#else /* NO_SYS_ERRLIST */
+  extern int sys_nerr;
+  extern char *sys_errlist[];
+
+  if ((errnum > 0) && (errnum <= sys_nerr))
+    return sys_errlist [errnum];
+#endif /* NO_SYS_ERRLIST */
+
+  sprintf (msg, "unknown error (%d)", errnum);
+  return msg;
+}
+
+gchar*
+g_strsignal (gint signum)
+{
+  static char msg[64];
+
+#ifdef HAVE_STRSIGNAL
+  extern char *strsignal (int sig);
+  return strsignal (signum);
+#elif NO_SYS_SIGLIST
+  switch (signum)
+    {
+#ifdef SIGHUP
+    case SIGHUP: return "Hangup";
+#endif
+#ifdef SIGINT
+    case SIGINT: return "Interrupt";
+#endif
+#ifdef SIGQUIT
+    case SIGQUIT: return "Quit";
+#endif
+#ifdef SIGILL
+    case SIGILL: return "Illegal instruction";
+#endif
+#ifdef SIGTRAP
+    case SIGTRAP: return "Trace/breakpoint trap";
+#endif
+#ifdef SIGABRT
+    case SIGABRT: return "IOT trap/Abort";
+#endif
+#ifdef SIGBUS
+    case SIGBUS: return "Bus error";
+#endif
+#ifdef SIGFPE
+    case SIGFPE: return "Floating point exception";
+#endif
+#ifdef SIGKILL
+    case SIGKILL: return "Killed";
+#endif
+#ifdef SIGUSR1
+    case SIGUSR1: return "User defined signal 1";
+#endif
+#ifdef SIGSEGV
+    case SIGSEGV: return "Segmentation fault";
+#endif
+#ifdef SIGUSR2
+    case SIGUSR2: return "User defined signal 2";
+#endif
+#ifdef SIGPIPE
+    case SIGPIPE: return "Broken pipe";
+#endif
+#ifdef SIGALRM
+    case SIGALRM: return "Alarm clock";
+#endif
+#ifdef SIGTERM
+    case SIGTERM: return "Terminated";
+#endif
+#ifdef SIGSTKFLT
+    case SIGSTKFLT: return "Stack fault";
+#endif
+#ifdef SIGCHLD
+    case SIGCHLD: return "Child exited";
+#endif
+#ifdef SIGCONT
+    case SIGCONT: return "Continued";
+#endif
+#ifdef SIGSTOP
+    case SIGSTOP: return "Stopped (signal)";
+#endif
+#ifdef SIGTSTP
+    case SIGTSTP: return "Stopped";
+#endif
+#ifdef SIGTTIN
+    case SIGTTIN: return "Stopped (tty input)";
+#endif
+#ifdef SIGTTOU
+    case SIGTTOU: return "Stopped (tty output)";
+#endif
+#ifdef SIGURG
+    case SIGURG: return "Urgent condition";
+#endif
+#ifdef SIGXCPU
+    case SIGXCPU: return "CPU time limit exceeded";
+#endif
+#ifdef SIGXFSZ
+    case SIGXFSZ: return "File size limit exceeded";
+#endif
+#ifdef SIGVTALRM
+    case SIGVTALRM: return "Virtual time alarm";
+#endif
+#ifdef SIGPROF
+    case SIGPROF: return "Profile signal";
+#endif
+#ifdef SIGWINCH
+    case SIGWINCH: return "Window size changed";
+#endif
+#ifdef SIGIO
+    case SIGIO: return "Possible I/O";
+#endif
+#ifdef SIGPWR
+    case SIGPWR: return "Power failure";
+#endif
+#ifdef SIGUNUSED
+    case SIGUNUSED: return "Unused signal";
+#endif
+    }
+#else /* NO_SYS_SIGLIST */
+  extern char *sys_siglist[];
+  return sys_siglist [signum];
+#endif /* NO_SYS_SIGLIST */
+
+  sprintf (msg, "unknown signal (%d)", signum);
+  return msg;
+}
+
+gint
+g_snprintf (gchar       *str,
+           gulong       n,
+           gchar const *fmt,
+           ...)
+{
+#ifdef HAVE_VSNPRINTF
+  va_list args;
+  gint retval;
+  
+  va_start (args, fmt);
+  retval = vsnprintf (str, n, fmt, args);
+  va_end (args);
+
+  return retval;
+
+#else
+  gchar *printed;
+  va_list args, args2;
+
+  va_start (args, fmt);
+  va_start (args2, fmt);
+  
+  printed = g_vsprintf (fmt, &args, &args2);
+  strncpy (str, printed, n);
+  str[n-1] = '\0';
+  
+  va_end (args2);
+  va_end (args);
+
+  return strlen (str);
+
+#endif
+}
+
+void
+g_strdown (gchar  *string)
+{
+  register gchar *s;
+
+  g_return_if_fail (string != NULL);
+
+  s = string;
+
+  while (*s)
+    {
+      *s = tolower (*s);
+      s++;
+    }
+}
+
+void
+g_strup (gchar  *string)
+{
+  register gchar *s;
+
+  g_return_if_fail (string != NULL);
+
+  s = string;
+
+  while (*s)
+    {
+      *s = toupper (*s);
+      s++;
+    }
+}
+
+void
+g_strreverse (gchar       *string)
+{
+  g_return_if_fail (string != NULL);
+
+  if (*string)
+    {
+      register gchar *h, *t;
+
+      h = string;
+      t = string + strlen (string) - 1;
+      
+      while (h < t)
+       {
+         register gchar c;
+         
+         c = *h;
+         *h = *t;
+         h++;
+         *t = c;
+         t--;
+       }
+    }
+}
+
+gint
+g_strcasecmp (const gchar *s1,
+             const gchar *s2)
+{
+#ifdef HAVE_STRCASECMP
+  return strcasecmp (s1, s2);
+#else
+  gint c1, c2;
+
+  while (*s1 && *s2)
+    {
+      /* According to A. Cox, some platforms have islower's that
+       * don't work right on non-uppercase
+       */
+      c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1;
+      c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2;
+      if (c1 != c2)
+        return (c1 - c2);
+      s1++; s2++;
+    }
+
+  return (((gint)(guchar) *s1) - ((gint)(guchar) *s2));
+#endif
+}
+
+void
+g_strdelimit (gchar       *string,
+             const gchar *delimiters,
+             gchar        new_delim)
+{
+  register gchar *c;
+
+  g_return_if_fail (string != NULL);
+
+  if (!delimiters)
+    delimiters = G_STR_DELIMITERS;
+
+  for (c = string; *c; c++)
+    {
+      if (strchr (delimiters, *c))
+       *c = new_delim;
+    }
+}
+
+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;
+}
+
+guint
+g_direct_hash(gconstpointer key)
+{
+  return GPOINTER_TO_UINT (key);
+}
+
diff --git a/glibconfig.h.in b/glibconfig.h.in
new file mode 100644 (file)
index 0000000..09cb42c
--- /dev/null
@@ -0,0 +1,87 @@
+/* glibconfig.h.in.  Generated automatically from configure.in by autoheader.  */
+
+/* Define to empty if the keyword does not work.  */
+#undef const
+
+/* Define if you don't have vprintf but do have _doprnt.  */
+#undef HAVE_DOPRNT
+
+/* Define if you have the vprintf function.  */
+#undef HAVE_VPRINTF
+
+/* Define as __inline if that's what the C compiler calls it.  */
+#undef inline
+
+/* Define if you have the ANSI C header files.  */
+#undef STDC_HEADERS
+
+#undef ENABLE_MEM_CHECK
+#undef ENABLE_MEM_PROFILE
+
+#undef G_COMPILED_WITH_DEBUGGING
+#undef HAVE_BROKEN_WCTYPE
+#undef HAVE_DOPRNT
+#undef HAVE_FLOAT_H
+#undef HAVE_LIMITS_H
+#undef HAVE_LONG_DOUBLE
+#undef HAVE_SYS_SELECT_H
+#undef HAVE_STRERROR
+#undef HAVE_STRSIGNAL
+#undef HAVE_VSNPRINTF
+#undef HAVE_VALUES_H
+#undef HAVE_VPRINTF
+#undef HAVE_WCHAR_H
+#undef HAVE_WCTYPE_H
+
+#undef NO_FD_SET
+#undef NO_SYS_ERRLIST
+#undef NO_SYS_SIGLIST
+
+#undef GLIB_MAJOR_VERSION
+#undef GLIB_MINOR_VERSION
+#undef GLIB_MICRO_VERSION
+
+/* The number of bytes in a char.  */
+#undef SIZEOF_CHAR
+
+/* The number of bytes in a int.  */
+#undef SIZEOF_INT
+
+/* The number of bytes in a long.  */
+#undef SIZEOF_LONG
+
+/* The number of bytes in a short.  */
+#undef SIZEOF_SHORT
+
+/* The number of bytes in a void *.  */
+#undef SIZEOF_VOID_P
+
+/* Define if you have the atexit function.  */
+#undef HAVE_ATEXIT
+
+/* Define if you have the memmove function.  */
+#undef HAVE_MEMMOVE
+
+/* Define if you have the on_exit function.  */
+#undef HAVE_ON_EXIT
+
+/* Define if you have the strcasecmp function.  */
+#undef HAVE_STRCASECMP
+
+/* Define if you have the strerror function.  */
+#undef HAVE_STRERROR
+
+/* Define if you have the strsignal function.  */
+#undef HAVE_STRSIGNAL
+
+/* Define if you have the vsnprintf function.  */
+#undef HAVE_VSNPRINTF
+
+/* Define if you have the <float.h> header file.  */
+#undef HAVE_FLOAT_H
+
+/* Define if you have the <limits.h> header file.  */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <values.h> header file.  */
+#undef HAVE_VALUES_H
diff --git a/glist.c b/glist.c
new file mode 100644 (file)
index 0000000..dc21158
--- /dev/null
+++ b/glist.c
@@ -0,0 +1,481 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "glib.h"
+
+
+typedef struct _GRealListAllocator GRealListAllocator;
+
+struct _GRealListAllocator
+{
+  GMemChunk *list_mem_chunk;
+  GList            *free_list;
+};
+
+
+static GRealListAllocator *default_allocator = NULL;
+static GRealListAllocator *current_allocator = NULL;
+
+
+GListAllocator*
+g_list_allocator_new (void)
+{
+  GRealListAllocator* allocator = g_new (GRealListAllocator, 1);
+  
+  allocator->list_mem_chunk = NULL;
+  allocator->free_list = NULL;
+  
+  return (GListAllocator*) allocator;
+}
+
+void
+g_list_allocator_free (GListAllocator* fallocator)
+{
+  GRealListAllocator* allocator = (GRealListAllocator *) fallocator;
+  
+  if (allocator && allocator->list_mem_chunk)
+    g_mem_chunk_destroy (allocator->list_mem_chunk);
+  if (allocator)
+    g_free (allocator);
+}
+
+GListAllocator*
+g_list_set_allocator (GListAllocator* fallocator)
+{
+  GRealListAllocator* allocator = (GRealListAllocator *) fallocator;
+  GRealListAllocator* old_allocator = current_allocator;
+  
+  if (allocator)
+    current_allocator = allocator;
+  else
+    {
+      if (!default_allocator)
+       default_allocator = (GRealListAllocator*) g_list_allocator_new ();
+      current_allocator = default_allocator;
+    }
+  
+  if (!current_allocator->list_mem_chunk)
+    current_allocator->list_mem_chunk = g_mem_chunk_new ("list mem chunk",
+                                                        sizeof (GList),
+                                                        1024,
+                                                        G_ALLOC_ONLY);
+  
+  return (GListAllocator*) (old_allocator == default_allocator ? NULL : old_allocator);
+}
+
+
+GList*
+g_list_alloc (void)
+{
+  GList *new_list;
+  
+  g_list_set_allocator (NULL);
+  if (current_allocator->free_list)
+    {
+      new_list = current_allocator->free_list;
+      current_allocator->free_list = current_allocator->free_list->next;
+    }
+  else
+    {
+      new_list = g_chunk_new (GList, current_allocator->list_mem_chunk);
+    }
+  
+  new_list->data = NULL;
+  new_list->next = NULL;
+  new_list->prev = NULL;
+  
+  return new_list;
+}
+
+void
+g_list_free (GList *list)
+{
+  GList *last;
+  
+  if (list)
+    {
+      last = g_list_last (list);
+      last->next = current_allocator->free_list;
+      current_allocator->free_list = list;
+    }
+}
+
+void
+g_list_free_1 (GList *list)
+{
+  if (list)
+    {
+      list->next = current_allocator->free_list;
+      current_allocator->free_list = list;
+    }
+}
+
+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_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;
+}
diff --git a/gmem.c b/gmem.c
new file mode 100644 (file)
index 0000000..a3fa6f5
--- /dev/null
+++ b/gmem.c
@@ -0,0 +1,807 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <stdlib.h>
+#include <string.h>
+#include "glib.h"
+
+/* #define ENABLE_MEM_PROFILE */
+/* #define ENABLE_MEM_CHECK */
+
+
+#define MAX_MEM_AREA  65536L
+#define MEM_AREA_SIZE 4L
+
+#if SIZEOF_VOID_P > SIZEOF_LONG
+#define MEM_ALIGN     SIZEOF_VOID_P
+#else
+#define MEM_ALIGN     SIZEOF_LONG
+#endif
+
+
+typedef struct _GFreeAtom      GFreeAtom;
+typedef struct _GMemArea       GMemArea;
+typedef struct _GRealMemChunk  GRealMemChunk;
+
+struct _GFreeAtom
+{
+  GFreeAtom *next;
+};
+
+struct _GMemArea
+{
+  GMemArea *next;            /* the next mem area */
+  GMemArea *prev;            /* the previous mem area */
+  gulong index;              /* the current index into the "mem" array */
+  gulong free;               /* the number of free bytes in this mem area */
+  gulong allocated;          /* the number of atoms allocated from this area */
+  gulong mark;               /* is this mem area marked for deletion */
+  gchar mem[MEM_AREA_SIZE];  /* the mem array from which atoms get allocated
+                             * the actual size of this array is determined by
+                             *  the mem chunk "area_size". ANSI says that it
+                             *  must be declared to be the maximum size it
+                             *  can possibly be (even though the actual size
+                             *  may be less).
+                             */
+};
+
+struct _GRealMemChunk
+{
+  gchar *name;               /* name of this MemChunk...used for debugging output */
+  gint type;                 /* the type of MemChunk: ALLOC_ONLY or ALLOC_AND_FREE */
+  gint num_mem_areas;        /* the number of memory areas */
+  gint num_marked_areas;     /* the number of areas marked for deletion */
+  guint atom_size;           /* the size of an atom */
+  gulong area_size;          /* the size of a memory area */
+  GMemArea *mem_area;        /* the current memory area */
+  GMemArea *mem_areas;       /* a list of all the mem areas owned by this chunk */
+  GMemArea *free_mem_area;   /* the free area...which is about to be destroyed */
+  GFreeAtom *free_atoms;     /* the free atoms list */
+  GTree *mem_tree;           /* tree of mem areas sorted by memory address */
+  GRealMemChunk *next;       /* pointer to the next chunk */
+  GRealMemChunk *prev;       /* pointer to the previous chunk */
+};
+
+
+static gulong g_mem_chunk_compute_size (gulong    size);
+static gint   g_mem_chunk_area_compare (GMemArea *a,
+                                       GMemArea *b);
+static gint   g_mem_chunk_area_search  (GMemArea *a,
+                                       gchar    *addr);
+
+
+static GRealMemChunk *mem_chunks = NULL;
+
+#ifdef ENABLE_MEM_PROFILE
+static gulong allocations[4096] = { 0 };
+static gulong allocated_mem = 0;
+static gulong freed_mem = 0;
+#endif /* ENABLE_MEM_PROFILE */
+
+
+#ifndef USE_DMALLOC
+
+gpointer
+g_malloc (gulong size)
+{
+  gpointer p;
+
+
+#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
+  gulong *t;
+#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
+
+
+  if (size == 0)
+    return NULL;
+
+
+#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
+  size += SIZEOF_LONG;
+#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
+
+#ifdef ENABLE_MEM_CHECK
+  size += SIZEOF_LONG;
+#endif /* ENABLE_MEM_CHECK */
+
+
+  p = (gpointer) malloc (size);
+  if (!p)
+    g_error ("could not allocate %ld bytes", size);
+
+
+#ifdef ENABLE_MEM_CHECK
+  size -= SIZEOF_LONG;
+
+  t = p;
+  p = ((guchar*) p + SIZEOF_LONG);
+  *t = 0;
+#endif /* ENABLE_MEM_CHECK */
+
+#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
+  size -= SIZEOF_LONG;
+
+  t = p;
+  p = ((guchar*) p + SIZEOF_LONG);
+  *t = size;
+
+#ifdef ENABLE_MEM_PROFILE
+  if (size <= 4095)
+    allocations[size-1] += 1;
+  else
+    allocations[4095] += 1;
+  allocated_mem += size;
+#endif /* ENABLE_MEM_PROFILE */
+#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
+
+
+  return p;
+}
+
+gpointer
+g_malloc0 (gulong size)
+{
+  gpointer p;
+
+
+#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
+  gulong *t;
+#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
+
+
+  if (size == 0)
+    return NULL;
+
+
+#ifdef ENABLE_MEM_PROFILE
+  size += SIZEOF_LONG;
+#endif /* ENABLE_MEM_PROFILE */
+
+#ifdef ENABLE_MEM_CHECK
+  size += SIZEOF_LONG;
+#endif /* ENABLE_MEM_CHECK */
+
+
+  p = (gpointer) calloc (size, 1);
+  if (!p)
+    g_error ("could not allocate %ld bytes", size);
+
+
+#ifdef ENABLE_MEM_CHECK
+  size -= SIZEOF_LONG;
+
+  t = p;
+  p = ((guchar*) p + SIZEOF_LONG);
+  *t = 0;
+#endif /* ENABLE_MEM_CHECK */
+
+#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
+  size -= SIZEOF_LONG;
+
+  t = p;
+  p = ((guchar*) p + SIZEOF_LONG);
+  *t = size;
+
+#ifdef ENABLE_MEM_PROFILE
+  if (size <= 4095)
+    allocations[size-1] += 1;
+  else
+    allocations[4095] += 1;
+  allocated_mem += size;
+#endif /* ENABLE_MEM_PROFILE */
+#endif /* ENABLE_MEM_PROFILE */
+
+
+  return p;
+}
+
+gpointer
+g_realloc (gpointer mem,
+          gulong   size)
+{
+  gpointer p;
+
+#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
+  gulong *t;
+#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
+
+
+  if (size == 0)
+    return NULL;
+
+
+#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
+  size += SIZEOF_LONG;
+#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
+
+#ifdef ENABLE_MEM_CHECK
+  size += SIZEOF_LONG;
+#endif /* ENABLE_MEM_CHECK */
+
+
+  if (!mem)
+    p = (gpointer) malloc (size);
+  else
+    {
+#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
+      t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
+#ifdef ENABLE_MEM_PROFILE
+      freed_mem += *t;
+#endif /* ENABLE_MEM_PROFILE */
+      mem = t;
+#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
+
+#ifdef ENABLE_MEM_CHECK
+      t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
+      if (*t >= 1)
+       g_warning ("trying to realloc freed memory\n");
+      mem = t;
+#endif /* ENABLE_MEM_CHECK */
+
+      p = (gpointer) realloc (mem, size);
+    }
+
+  if (!p)
+    g_error ("could not reallocate %ld bytes", size);
+
+
+#ifdef ENABLE_MEM_CHECK
+  size -= SIZEOF_LONG;
+
+  t = p;
+  p = ((guchar*) p + SIZEOF_LONG);
+  *t = 0;
+#endif /* ENABLE_MEM_CHECK */
+
+#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
+  size -= SIZEOF_LONG;
+
+  t = p;
+  p = ((guchar*) p + SIZEOF_LONG);
+  *t = size;
+
+#ifdef ENABLE_MEM_PROFILE
+  if (size <= 4095)
+    allocations[size-1] += 1;
+  else
+    allocations[4095] += 1;
+  allocated_mem += size;
+#endif /* ENABLE_MEM_PROFILE */
+#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
+
+
+  return p;
+}
+
+void
+g_free (gpointer mem)
+{
+  if (mem)
+    {
+#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
+      gulong *t;
+      gulong size;
+#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
+
+#if defined(ENABLE_MEM_PROFILE) || defined(ENABLE_MEM_CHECK)
+      t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
+      size = *t;
+#ifdef ENABLE_MEM_PROFILE
+      freed_mem += size;
+#endif /* ENABLE_MEM_PROFILE */
+      mem = t;
+#endif /* ENABLE_MEM_PROFILE || ENABLE_MEM_CHECK */
+
+#ifdef ENABLE_MEM_CHECK
+      t = (gulong*) ((guchar*) mem - SIZEOF_LONG);
+      if (*t >= 1)
+       g_warning ("freeing previously freed memory\n");
+      *t += 1;
+      mem = t;
+
+      memset ((guchar*) mem + 8, 0, size);
+#else /* ENABLE_MEM_CHECK */
+      free (mem);
+#endif /* ENABLE_MEM_CHECK */
+    }
+}
+
+#endif /* ! USE_DMALLOC */
+
+
+void
+g_mem_profile (void)
+{
+#ifdef ENABLE_MEM_PROFILE
+  gint i;
+
+  for (i = 0; i < 4095; i++)
+    if (allocations[i] > 0)
+      g_print ("%lu allocations of %d bytes\n", allocations[i], i + 1);
+
+  if (allocations[4095] > 0)
+    g_print ("%lu allocations of greater than 4095 bytes\n", allocations[4095]);
+  g_print ("%lu bytes allocated\n", allocated_mem);
+  g_print ("%lu bytes freed\n", freed_mem);
+  g_print ("%lu bytes in use\n", allocated_mem - freed_mem);
+#endif /* ENABLE_MEM_PROFILE */
+}
+
+void
+g_mem_check (gpointer mem)
+{
+#ifdef ENABLE_MEM_CHECK
+  gulong *t;
+
+  t = (gulong*) ((guchar*) mem - SIZEOF_LONG - SIZEOF_LONG);
+
+  if (*t >= 1)
+    g_warning ("mem: 0x%08x has been freed: %lu\n", (gulong) mem, *t);
+#endif /* ENABLE_MEM_CHECK */
+}
+
+GMemChunk*
+g_mem_chunk_new (gchar  *name,
+                gint    atom_size,
+                gulong  area_size,
+                gint    type)
+{
+  GRealMemChunk *mem_chunk;
+  gulong rarea_size;
+
+  mem_chunk = g_new (struct _GRealMemChunk, 1);
+  mem_chunk->name = name;
+  mem_chunk->type = type;
+  mem_chunk->num_mem_areas = 0;
+  mem_chunk->num_marked_areas = 0;
+  mem_chunk->mem_area = NULL;
+  mem_chunk->free_mem_area = NULL;
+  mem_chunk->free_atoms = NULL;
+  mem_chunk->mem_tree = NULL;
+  mem_chunk->mem_areas = NULL;
+  mem_chunk->atom_size = atom_size;
+
+  if (mem_chunk->type == G_ALLOC_AND_FREE)
+    mem_chunk->mem_tree = g_tree_new ((GCompareFunc) g_mem_chunk_area_compare);
+
+  if (mem_chunk->atom_size % MEM_ALIGN)
+    mem_chunk->atom_size += MEM_ALIGN - (mem_chunk->atom_size % MEM_ALIGN);
+
+  mem_chunk->area_size = area_size;
+  if (mem_chunk->area_size > MAX_MEM_AREA)
+    mem_chunk->area_size = MAX_MEM_AREA;
+  while (mem_chunk->area_size < mem_chunk->atom_size)
+    mem_chunk->area_size *= 2;
+
+  rarea_size = mem_chunk->area_size + sizeof (GMemArea) - MEM_AREA_SIZE;
+  rarea_size = g_mem_chunk_compute_size (rarea_size);
+  mem_chunk->area_size = rarea_size - (sizeof (GMemArea) - MEM_AREA_SIZE);
+
+  /*
+  mem_chunk->area_size -= (sizeof (GMemArea) - MEM_AREA_SIZE);
+  if (mem_chunk->area_size < mem_chunk->atom_size)
+    {
+      mem_chunk->area_size = (mem_chunk->area_size + sizeof (GMemArea) - MEM_AREA_SIZE) * 2;
+      mem_chunk->area_size -= (sizeof (GMemArea) - MEM_AREA_SIZE);
+    }
+
+  if (mem_chunk->area_size % mem_chunk->atom_size)
+    mem_chunk->area_size += mem_chunk->atom_size - (mem_chunk->area_size % mem_chunk->atom_size);
+    */
+
+  mem_chunk->next = mem_chunks;
+  mem_chunk->prev = NULL;
+  if (mem_chunks)
+    mem_chunks->prev = mem_chunk;
+  mem_chunks = mem_chunk;
+
+  return ((GMemChunk*) mem_chunk);
+}
+
+void
+g_mem_chunk_destroy (GMemChunk *mem_chunk)
+{
+  GRealMemChunk *rmem_chunk;
+  GMemArea *mem_areas;
+  GMemArea *temp_area;
+
+  g_assert (mem_chunk != NULL);
+
+  rmem_chunk = (GRealMemChunk*) mem_chunk;
+
+  mem_areas = rmem_chunk->mem_areas;
+  while (mem_areas)
+    {
+      temp_area = mem_areas;
+      mem_areas = mem_areas->next;
+      g_free (temp_area);
+    }
+
+  if (rmem_chunk->next)
+    rmem_chunk->next->prev = rmem_chunk->prev;
+  if (rmem_chunk->prev)
+    rmem_chunk->prev->next = rmem_chunk->next;
+
+  if (rmem_chunk == mem_chunks)
+    mem_chunks = mem_chunks->next;
+
+  if (rmem_chunk->type == G_ALLOC_AND_FREE)
+    g_tree_destroy (rmem_chunk->mem_tree);
+
+  g_free (rmem_chunk);
+}
+
+gpointer
+g_mem_chunk_alloc (GMemChunk *mem_chunk)
+{
+  GRealMemChunk *rmem_chunk;
+  GMemArea *temp_area;
+  gpointer mem;
+
+  g_assert (mem_chunk != NULL);
+
+  rmem_chunk = (GRealMemChunk*) mem_chunk;
+
+  while (rmem_chunk->free_atoms)
+    {
+      /* Get the first piece of memory on the "free_atoms" list.
+       * We can go ahead and destroy the list node we used to keep
+       *  track of it with and to update the "free_atoms" list to
+       *  point to its next element.
+       */
+      mem = rmem_chunk->free_atoms;
+      rmem_chunk->free_atoms = rmem_chunk->free_atoms->next;
+
+      /* Determine which area this piece of memory is allocated from */
+      temp_area = g_tree_search (rmem_chunk->mem_tree,
+                                (GSearchFunc) g_mem_chunk_area_search,
+                                mem);
+
+      /* If the area has been marked, then it is being destroyed.
+       *  (ie marked to be destroyed).
+       * We check to see if all of the segments on the free list that
+       *  reference this area have been removed. This occurs when
+       *  the ammount of free memory is less than the allocatable size.
+       * If the chunk should be freed, then we place it in the "free_mem_area".
+       * This is so we make sure not to free the mem area here and then
+       *  allocate it again a few lines down.
+       * If we don't allocate a chunk a few lines down then the "free_mem_area"
+       *  will be freed.
+       * If there is already a "free_mem_area" then we'll just free this mem area.
+       */
+      if (temp_area->mark)
+        {
+          /* Update the "free" memory available in that area */
+          temp_area->free += rmem_chunk->atom_size;
+
+          if (temp_area->free == rmem_chunk->area_size)
+            {
+              if (temp_area == rmem_chunk->mem_area)
+                rmem_chunk->mem_area = NULL;
+
+              if (rmem_chunk->free_mem_area)
+                {
+                  rmem_chunk->num_mem_areas -= 1;
+
+                  if (temp_area->next)
+                    temp_area->next->prev = temp_area->prev;
+                  if (temp_area->prev)
+                    temp_area->prev->next = temp_area->next;
+                  if (temp_area == rmem_chunk->mem_areas)
+                    rmem_chunk->mem_areas = rmem_chunk->mem_areas->next;
+
+                 if (rmem_chunk->type == G_ALLOC_AND_FREE)
+                   g_tree_remove (rmem_chunk->mem_tree, temp_area);
+                  g_free (temp_area);
+                }
+              else
+                rmem_chunk->free_mem_area = temp_area;
+             
+             rmem_chunk->num_marked_areas -= 1;
+           }
+       }
+      else
+        {
+          /* Update the number of allocated atoms count.
+          */
+          temp_area->allocated += 1;
+
+          /* The area wasn't marked...return the memory
+          */
+         goto outa_here;
+        }
+    }
+
+  /* If there isn't a current mem area or the current mem area is out of space
+   *  then allocate a new mem area. We'll first check and see if we can use
+   *  the "free_mem_area". Otherwise we'll just malloc the mem area.
+   */
+  if ((!rmem_chunk->mem_area) ||
+      ((rmem_chunk->mem_area->index + rmem_chunk->atom_size) > rmem_chunk->area_size))
+    {
+      if (rmem_chunk->free_mem_area)
+        {
+          rmem_chunk->mem_area = rmem_chunk->free_mem_area;
+         rmem_chunk->free_mem_area = NULL;
+        }
+      else
+        {
+         rmem_chunk->mem_area = (GMemArea*) g_malloc (sizeof (GMemArea) -
+                                                      MEM_AREA_SIZE +
+                                                      rmem_chunk->area_size);
+
+         rmem_chunk->num_mem_areas += 1;
+         rmem_chunk->mem_area->next = rmem_chunk->mem_areas;
+         rmem_chunk->mem_area->prev = NULL;
+
+         if (rmem_chunk->mem_areas)
+           rmem_chunk->mem_areas->prev = rmem_chunk->mem_area;
+         rmem_chunk->mem_areas = rmem_chunk->mem_area;
+
+         if (rmem_chunk->type == G_ALLOC_AND_FREE)
+           g_tree_insert (rmem_chunk->mem_tree, rmem_chunk->mem_area, rmem_chunk->mem_area);
+        }
+
+      rmem_chunk->mem_area->index = 0;
+      rmem_chunk->mem_area->free = rmem_chunk->area_size;
+      rmem_chunk->mem_area->allocated = 0;
+      rmem_chunk->mem_area->mark = 0;
+    }
+
+  /* Get the memory and modify the state variables appropriately.
+   */
+  mem = (gpointer) &rmem_chunk->mem_area->mem[rmem_chunk->mem_area->index];
+  rmem_chunk->mem_area->index += rmem_chunk->atom_size;
+  rmem_chunk->mem_area->free -= rmem_chunk->atom_size;
+  rmem_chunk->mem_area->allocated += 1;
+
+outa_here:
+  return mem;
+}
+
+void
+g_mem_chunk_free (GMemChunk *mem_chunk,
+                 gpointer   mem)
+{
+  GRealMemChunk *rmem_chunk;
+  GMemArea *temp_area;
+  GFreeAtom *free_atom;
+
+  g_assert (mem_chunk != NULL);
+  g_assert (mem != NULL);
+
+  rmem_chunk = (GRealMemChunk*) mem_chunk;
+
+  /* Don't do anything if this is an ALLOC_ONLY chunk
+   */
+  if (rmem_chunk->type == G_ALLOC_AND_FREE)
+    {
+      /* Place the memory on the "free_atoms" list
+       */
+      free_atom = (GFreeAtom*) mem;
+      free_atom->next = rmem_chunk->free_atoms;
+      rmem_chunk->free_atoms = free_atom;
+
+      temp_area = g_tree_search (rmem_chunk->mem_tree,
+                                (GSearchFunc) g_mem_chunk_area_search,
+                                mem);
+
+      temp_area->allocated -= 1;
+
+      if (temp_area->allocated == 0)
+       {
+         temp_area->mark = 1;
+         rmem_chunk->num_marked_areas += 1;
+       }
+    }
+}
+
+/* This doesn't free the free_area if there is one */
+void
+g_mem_chunk_clean (GMemChunk *mem_chunk)
+{
+  GRealMemChunk *rmem_chunk;
+  GMemArea *mem_area;
+  GFreeAtom *prev_free_atom;
+  GFreeAtom *temp_free_atom;
+  gpointer mem;
+
+  g_assert (mem_chunk != NULL);
+
+  rmem_chunk = (GRealMemChunk*) mem_chunk;
+
+  if (rmem_chunk->type == G_ALLOC_AND_FREE)
+    {
+      prev_free_atom = NULL;
+      temp_free_atom = rmem_chunk->free_atoms;
+
+      while (temp_free_atom)
+       {
+         mem = (gpointer) temp_free_atom;
+
+         mem_area = g_tree_search (rmem_chunk->mem_tree,
+                                   (GSearchFunc) g_mem_chunk_area_search,
+                                   mem);
+
+          /* If this mem area is marked for destruction then delete the
+          *  area and list node and decrement the free mem.
+           */
+         if (mem_area->mark)
+           {
+             if (prev_free_atom)
+               prev_free_atom->next = temp_free_atom->next;
+             else
+               rmem_chunk->free_atoms = temp_free_atom->next;
+             temp_free_atom = temp_free_atom->next;
+
+             mem_area->free += rmem_chunk->atom_size;
+             if (mem_area->free == rmem_chunk->area_size)
+               {
+                 rmem_chunk->num_mem_areas -= 1;
+                 rmem_chunk->num_marked_areas -= 1;
+
+                 if (mem_area->next)
+                   mem_area->next->prev = mem_area->prev;
+                 if (mem_area->prev)
+                   mem_area->prev->next = mem_area->next;
+                 if (mem_area == rmem_chunk->mem_areas)
+                   rmem_chunk->mem_areas = rmem_chunk->mem_areas->next;
+                 if (mem_area == rmem_chunk->mem_area)
+                   rmem_chunk->mem_area = NULL;
+
+                 if (rmem_chunk->type == G_ALLOC_AND_FREE)
+                   g_tree_remove (rmem_chunk->mem_tree, mem_area);
+                 g_free (mem_area);
+               }
+           }
+         else
+           {
+             prev_free_atom = temp_free_atom;
+             temp_free_atom = temp_free_atom->next;
+           }
+       }
+    }
+}
+
+void
+g_mem_chunk_reset (GMemChunk *mem_chunk)
+{
+  GRealMemChunk *rmem_chunk;
+  GMemArea *mem_areas;
+  GMemArea *temp_area;
+
+  g_assert (mem_chunk != NULL);
+
+  rmem_chunk = (GRealMemChunk*) mem_chunk;
+
+  mem_areas = rmem_chunk->mem_areas;
+  rmem_chunk->num_mem_areas = 0;
+  rmem_chunk->mem_areas = NULL;
+  rmem_chunk->mem_area = NULL;
+
+  while (mem_areas)
+    {
+      temp_area = mem_areas;
+      mem_areas = mem_areas->next;
+      g_free (temp_area);
+    }
+
+  rmem_chunk->free_atoms = NULL;
+
+  if (rmem_chunk->mem_tree)
+    g_tree_destroy (rmem_chunk->mem_tree);
+  rmem_chunk->mem_tree = g_tree_new ((GCompareFunc) g_mem_chunk_area_compare);
+}
+
+void
+g_mem_chunk_print (GMemChunk *mem_chunk)
+{
+  GRealMemChunk *rmem_chunk;
+  GMemArea *mem_areas;
+  gulong mem;
+
+  g_assert (mem_chunk != NULL);
+
+  rmem_chunk = (GRealMemChunk*) mem_chunk;
+  mem_areas = rmem_chunk->mem_areas;
+  mem = 0;
+
+  while (mem_areas)
+    {
+      mem += rmem_chunk->area_size - mem_areas->free;
+      mem_areas = mem_areas->next;
+    }
+
+  g_print ("%s: %ld bytes using %d mem areas\n", rmem_chunk->name, mem, rmem_chunk->num_mem_areas);
+}
+
+void
+g_mem_chunk_info (void)
+{
+  GRealMemChunk *mem_chunk;
+  gint count;
+
+  count = 0;
+  mem_chunk = mem_chunks;
+  while (mem_chunk)
+    {
+      count += 1;
+      mem_chunk = mem_chunk->next;
+    }
+
+  g_print ("%d mem chunks\n", count);
+
+  mem_chunk = mem_chunks;
+  while (mem_chunk)
+    {
+      g_mem_chunk_print ((GMemChunk*) mem_chunk);
+      mem_chunk = mem_chunk->next;
+    }
+}
+
+void
+g_blow_chunks (void)
+{
+  GRealMemChunk *mem_chunk;
+
+  mem_chunk = mem_chunks;
+  while (mem_chunk)
+    {
+      g_mem_chunk_clean ((GMemChunk*) mem_chunk);
+      mem_chunk = mem_chunk->next;
+    }
+}
+
+
+static gulong
+g_mem_chunk_compute_size (gulong size)
+{
+  gulong power_of_2;
+  gulong lower, upper;
+
+  power_of_2 = 16;
+  while (power_of_2 < size)
+    power_of_2 <<= 1;
+
+  lower = power_of_2 >> 1;
+  upper = power_of_2;
+
+  if ((size - lower) < (upper - size))
+    return lower;
+  return upper;
+}
+
+static gint
+g_mem_chunk_area_compare (GMemArea *a,
+                         GMemArea *b)
+{
+  return (a->mem - b->mem);
+}
+
+static gint
+g_mem_chunk_area_search (GMemArea *a,
+                        gchar    *addr)
+{
+  if (a->mem <= addr)
+    {
+      if (addr < &a->mem[a->index])
+       return 0;
+      return 1;
+    }
+  return -1;
+}
diff --git a/gmessages.c b/gmessages.c
new file mode 100644 (file)
index 0000000..2e58fc3
--- /dev/null
@@ -0,0 +1,180 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include "glib.h"
+
+static GErrorFunc glib_error_func = NULL;
+static GWarningFunc glib_warning_func = NULL;
+static GPrintFunc glib_message_func = NULL;
+static GPrintFunc glib_print_func = NULL;
+
+extern char* g_vsprintf (const gchar *fmt, va_list *args, va_list *args2);
+
+void
+g_error (const gchar *format, ...)
+{
+  va_list args, args2;
+  char *buf;
+  static gboolean errored = 0;
+
+  if (errored++)
+    {
+      write (2, "g_error: recursed!\n", 19);
+      return;
+    }
+  
+  va_start (args, format);
+  va_start (args2, format);
+  buf = g_vsprintf (format, &args, &args2);
+  va_end (args);
+  va_end (args2);
+
+  if (glib_error_func)
+    {
+      (* glib_error_func) (buf);
+    }
+  else
+    {
+      /* Use write() here because we might be out of memory */
+      write (2, "\n** ERROR **: ", 14);
+      write (2, buf, strlen(buf));
+      write (2, "\n", 1);
+    }
+
+  abort ();
+}
+
+void
+g_warning (const gchar *format, ...)
+{
+  va_list args, args2;
+  char *buf;
+
+  va_start (args, format);
+  va_start (args2, format);
+  buf = g_vsprintf (format, &args, &args2);
+  va_end (args);
+  va_end (args2);
+
+  if (glib_warning_func)
+    {
+      (* glib_warning_func) (buf);
+    }
+  else
+    {
+      fputs ("\n** WARNING **: ", stderr);
+      fputs (buf, stderr);
+      fputc ('\n', stderr);
+    }
+}
+
+void
+g_message (const gchar *format, ...)
+{
+  va_list args, args2;
+  char *buf;
+
+  va_start (args, format);
+  va_start (args2, format);
+  buf = g_vsprintf (format, &args, &args2);
+  va_end (args);
+  va_end (args2);
+
+  if (glib_message_func)
+    {
+      (* glib_message_func) (buf);
+    }
+  else
+    {
+      fputs ("message: ", stdout);
+      fputs (buf, stdout);
+      fputc ('\n', stdout);
+    }
+}
+
+void
+g_print (const gchar *format, ...)
+{
+  va_list args, args2;
+  char *buf;
+
+  va_start (args, format);
+  va_start (args2, format);
+  buf = g_vsprintf (format, &args, &args2);
+  va_end (args);
+  va_end (args2);
+
+  if (glib_print_func)
+    {
+      (* glib_print_func) (buf);
+    }
+  else
+    {
+      fputs (buf, stdout);
+    }
+}
+
+GErrorFunc
+g_set_error_handler (GErrorFunc func)
+{
+  GErrorFunc old_error_func;
+
+  old_error_func = glib_error_func;
+  glib_error_func = func;
+
+  return old_error_func;
+}
+
+GWarningFunc
+g_set_warning_handler (GWarningFunc func)
+{
+  GWarningFunc old_warning_func;
+
+  old_warning_func = glib_warning_func;
+  glib_warning_func = func;
+
+  return old_warning_func;
+}
+
+GPrintFunc
+g_set_message_handler (GPrintFunc func)
+{
+  GPrintFunc old_message_func;
+
+  old_message_func = glib_message_func;
+  glib_message_func = func;
+
+  return old_message_func;
+}
+
+GPrintFunc
+g_set_print_handler (GPrintFunc func)
+{
+  GPrintFunc old_print_func;
+
+  old_print_func = glib_print_func;
+  glib_print_func = func;
+  
+  return old_print_func;
+}
+
diff --git a/gprimes.c b/gprimes.c
new file mode 100644 (file)
index 0000000..6a38b39
--- /dev/null
+++ b/gprimes.c
@@ -0,0 +1,62 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "glib.h"
+
+
+gint g_primes[] =
+{
+  11,
+  15,
+  23,
+  35,
+  49,
+  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,
+};
+
+gint g_nprimes = sizeof (g_primes) / sizeof (g_primes[0]);
diff --git a/gscanner.c b/gscanner.c
new file mode 100644 (file)
index 0000000..ccb6960
--- /dev/null
@@ -0,0 +1,1551 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * GScanner: Flexible lexical scanner for general purpose.
+ * Copyright (C) 1997, 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.
+ */
+#define                __gscanner_c__
+
+#include       <stdlib.h>
+#include       <stdarg.h>
+#include       <string.h>
+#include       <stdio.h>
+#include       <unistd.h>
+#include       <errno.h>
+#include       <sys/types.h>   /* needed for sys/stat.h */
+#include       <sys/stat.h>
+#include       "glib.h"
+
+
+
+/* --- defines --- */
+#define        to_lower(c)                             ( \
+       (guchar) (                                                      \
+         ( (((guchar)(c))>='A' && ((guchar)(c))<='Z') * ('a'-'A') ) |  \
+         ( (((guchar)(c))>=192 && ((guchar)(c))<=214) * (224-192) ) |  \
+         ( (((guchar)(c))>=216 && ((guchar)(c))<=222) * (248-216) ) |  \
+         ((guchar)(c))                                                 \
+       )                                                               \
+)
+
+
+/* --- typedefs --- */
+typedef        struct  _GScannerHashVal        GScannerHashVal;
+
+struct _GScannerHashVal
+{
+  gchar                *key;
+  gpointer     value;
+};
+
+
+
+/* --- variables --- */
+static GScannerConfig  g_scanner_config_template =
+{
+  (
+   " \t\n"
+   )                   /* cset_skip_characters */,
+  (
+   G_CSET_a_2_z
+   "_"
+   G_CSET_A_2_Z
+   )                   /* cset_identifier_first */,
+  (
+   G_CSET_a_2_z
+   "_0123456789"
+   G_CSET_A_2_Z
+   G_CSET_LATINS
+   G_CSET_LATINC
+   )                   /* cset_identifier_nth */,
+  ( "#\n" )            /* cpair_comment_single */,
+  
+  FALSE                        /* case_sensitive */,
+  
+  TRUE                 /* skip_comment_multi */,
+  TRUE                 /* skip_comment_single */,
+  TRUE                 /* scan_comment_multi */,
+  TRUE                 /* scan_identifier */,
+  FALSE                        /* scan_identifier_1char */,
+  FALSE                        /* scan_identifier_NULL */,
+  TRUE                 /* scan_symbols */,
+  FALSE                        /* scan_binary */,
+  TRUE                 /* scan_octal */,
+  TRUE                 /* scan_float */,
+  TRUE                 /* scan_hex */,
+  FALSE                        /* scan_hex_dollar */,
+  TRUE                 /* scan_string_sq */,
+  TRUE                 /* scan_string_dq */,
+  TRUE                 /* numbers_2_int */,
+  FALSE                        /* int_2_float */,
+  FALSE                        /* identifier_2_string */,
+  TRUE                 /* char_2_token */,
+  FALSE                        /* symbol_2_token */,
+};
+
+
+/* --- prototypes --- */
+extern char* g_vsprintf (gchar *fmt, va_list *args, va_list *args2);
+static GScannerHashVal* g_scanner_lookup_internal (GScanner    *scanner,
+                                                   const gchar *symbol);
+static void    g_scanner_get_token_ll  (GScanner       *scanner,
+                                        GTokenType     *token_p,
+                                        GValue         *value_p,
+                                        guint          *line_p,
+                                        guint          *position_p);
+static void    g_scanner_get_token_i   (GScanner       *scanner,
+                                        GTokenType     *token_p,
+                                        GValue         *value_p,
+                                        guint          *line_p,
+                                        guint          *position_p);
+static void    g_scanner_free_value    (GTokenType     *token_p,
+                                        GValue         *value_p);
+
+static inline
+gint           g_scanner_char_2_num    (guchar         c,
+                                        guchar         base);
+static guchar  g_scanner_peek_next_char(GScanner       *scanner);
+static guchar  g_scanner_get_char      (GScanner       *scanner,
+                                        guint          *line_p,
+                                        guint          *position_p);
+static  void   g_scanner_msg_handler   (GScanner       *scanner,
+                                        gchar          *message,
+                                        gint            is_error);
+
+
+/* --- functions --- */
+static gint
+g_scanner_char_2_num (guchar   c,
+                     guchar    base)
+{
+  if (c >= '0' && c <= '9')
+    c -= '0';
+  else if (c >= 'A' && c <= 'Z')
+    c -= 'A' - 10;
+  else if (c >= 'a' && c <= 'z')
+    c -= 'a' - 10;
+  else
+    return -1;
+  
+  if (c < base)
+    return c;
+  
+  return -1;
+}
+
+GScanner*
+g_scanner_new (GScannerConfig  *config_templ)
+{
+  register GScanner    *scanner;
+  
+  if (!config_templ)
+    config_templ = &g_scanner_config_template;
+  
+  scanner = g_new0 (GScanner, 1);
+  
+  scanner->user_data = NULL;
+  scanner->input_name = NULL;
+  scanner->parse_errors        = 0;
+  scanner->max_parse_errors = 0;
+  
+  scanner->config = g_new0 (GScannerConfig, 1);
+  
+  scanner->config->case_sensitive      = config_templ->case_sensitive;
+  scanner->config->cset_skip_characters        = config_templ->cset_skip_characters;
+  scanner->config->cset_identifier_first= config_templ->cset_identifier_first;
+  scanner->config->cset_identifier_nth = config_templ->cset_identifier_nth;
+  scanner->config->cpair_comment_single        = config_templ->cpair_comment_single;
+  scanner->config->skip_comment_multi  = config_templ->skip_comment_multi;
+  scanner->config->skip_comment_single = config_templ->skip_comment_single;
+  scanner->config->scan_comment_multi  = config_templ->scan_comment_multi;
+  scanner->config->scan_identifier     = config_templ->scan_identifier;
+  scanner->config->scan_identifier_1char= config_templ->scan_identifier_1char;
+  scanner->config->scan_identifier_NULL        = config_templ->scan_identifier_NULL;
+  scanner->config->scan_symbols                = config_templ->scan_symbols;
+  scanner->config->scan_binary         = config_templ->scan_binary;
+  scanner->config->scan_octal          = config_templ->scan_octal;
+  scanner->config->scan_float          = config_templ->scan_float;
+  scanner->config->scan_hex            = config_templ->scan_hex;
+  scanner->config->scan_hex_dollar     = config_templ->scan_hex_dollar;
+  scanner->config->scan_string_sq      = config_templ->scan_string_sq;
+  scanner->config->scan_string_dq      = config_templ->scan_string_dq;
+  scanner->config->numbers_2_int       = config_templ->numbers_2_int;
+  scanner->config->int_2_float         = config_templ->int_2_float;
+  scanner->config->identifier_2_string = config_templ->identifier_2_string;
+  scanner->config->char_2_token                = config_templ->char_2_token;
+  scanner->config->symbol_2_token      = config_templ->symbol_2_token;
+  
+  scanner->token = G_TOKEN_NONE;
+  scanner->value.v_int = 0;
+  scanner->line = 1;
+  scanner->position = 0;
+  
+  scanner->next_token = G_TOKEN_NONE;
+  scanner->next_value.v_int = 0;
+  scanner->next_line = 1;
+  scanner->next_position = 0;
+  
+  scanner->symbol_table = g_hash_table_new (g_str_hash, g_str_equal);
+  scanner->text = NULL;
+  scanner->text_len = 0;
+  scanner->input_fd = -1;
+  scanner->peeked_char = -1;
+
+  scanner->msg_handler = g_scanner_msg_handler;
+  
+  return scanner;
+}
+
+static void
+g_scanner_destroy_symbol_table_entry (gpointer key,
+                                     gpointer value,
+                                     gpointer user_data)
+{
+  g_free (key);
+  g_free (value);
+}
+
+void
+g_scanner_destroy (GScanner    *scanner)
+{
+  g_return_if_fail (scanner != NULL);
+  
+  g_hash_table_foreach (scanner->symbol_table, 
+                        g_scanner_destroy_symbol_table_entry, NULL);
+  g_hash_table_destroy (scanner->symbol_table);
+  g_scanner_free_value (&scanner->token, &scanner->value);
+  g_scanner_free_value (&scanner->next_token, &scanner->next_value);
+  g_free (scanner->config);
+  g_free (scanner);
+}
+
+static void
+g_scanner_msg_handler (GScanner                *scanner,
+                      gchar            *message,
+                      gint              is_error)
+{
+  g_return_if_fail (scanner != NULL);
+
+  fprintf (stdout, "%s:%d: ", scanner->input_name, scanner->line);
+  if (is_error)
+    fprintf (stdout, "error: ");
+  fprintf (stdout, "%s\n", message);
+}
+
+void
+g_scanner_error (GScanner       *scanner,
+                const gchar    *format,
+                ...)
+{
+  g_return_if_fail (scanner != NULL);
+  g_return_if_fail (format != NULL);
+
+  scanner->parse_errors++;
+
+  if (scanner->msg_handler)
+    {
+      va_list args, args2;
+      gchar *string;
+      
+      va_start (args, format);
+      va_start (args2, format);
+      string = g_vsprintf ((gchar*) format, &args, &args2);
+      va_end (args);
+      va_end (args2);
+
+      string = g_strdup (string);
+
+      scanner->msg_handler (scanner, string, TRUE);
+         
+      g_free (string);
+    }
+}
+
+void
+g_scanner_warn (GScanner       *scanner,
+               const gchar    *format,
+               ...)
+{
+  g_return_if_fail (scanner != NULL);
+  g_return_if_fail (format != NULL);
+  
+  if (scanner->msg_handler)
+    {
+      va_list args, args2;
+      gchar *string;
+      
+      va_start (args, format);
+      va_start (args2, format);
+      string = g_vsprintf ((gchar*) format, &args, &args2);
+      va_end (args);
+      va_end (args2);
+      
+      string = g_strdup (string);
+      
+      scanner->msg_handler (scanner, string, FALSE);
+      
+      g_free (string);
+    }
+}
+
+void
+g_scanner_input_file (GScanner *scanner,
+                     gint      input_fd)
+{
+  g_return_if_fail (input_fd >= 0);
+  
+  scanner->token = G_TOKEN_NONE;
+  scanner->value.v_int = 0;
+  scanner->line = 1;
+  scanner->position = 0;
+  scanner->next_token = G_TOKEN_NONE;
+  
+  scanner->text = NULL;
+  scanner->text_len = 0;
+  scanner->input_fd = input_fd;
+  scanner->peeked_char = -1;
+}
+
+void
+g_scanner_input_text (GScanner      *scanner,
+                     const  gchar   *text,
+                     guint           text_len)
+{
+  g_return_if_fail (text != NULL);
+  
+  scanner->token = G_TOKEN_NONE;
+  scanner->value.v_int = 0;
+  scanner->line = 1;
+  scanner->position = 0;
+  scanner->next_token = G_TOKEN_NONE;
+  
+  scanner->text = text;
+  scanner->text_len = text_len;
+  scanner->input_fd = -1;
+  scanner->peeked_char = -1;
+}
+
+void
+g_scanner_add_symbol (GScanner         *scanner,
+                     const gchar       *symbol,
+                     gpointer          value)
+{
+  register GScannerHashVal     *hash_val;
+  
+  g_return_if_fail (scanner != NULL);
+  g_return_if_fail (symbol != NULL);
+  
+  hash_val = g_scanner_lookup_internal (scanner, symbol);
+  
+  if (!hash_val)
+    {
+      hash_val = g_new (GScannerHashVal, 1);
+      hash_val->key = g_strdup (symbol);
+      hash_val->value = value;
+      if (!scanner->config->case_sensitive)
+       {
+         register guint        i, l;
+         
+         l = strlen (hash_val->key);
+         for (i = 0; i < l; i++)
+           hash_val->key[i] = to_lower (hash_val->key[i]);
+       }
+      g_hash_table_insert (scanner->symbol_table, hash_val->key, hash_val);
+    }
+  else
+    hash_val->value = value;
+}
+
+gpointer
+g_scanner_lookup_symbol (GScanner      *scanner,
+                        const gchar    *symbol)
+{
+  register GScannerHashVal     *hash_val;
+  
+  g_return_val_if_fail (scanner != NULL, NULL);
+  
+  if (!symbol)
+    return NULL;
+  
+  hash_val = g_scanner_lookup_internal (scanner, symbol);
+  
+  if (hash_val)
+    return hash_val->value;
+  else
+    return NULL;
+}
+
+static void
+g_scanner_foreach_internal (gpointer  key,
+                           gpointer  value,
+                           gpointer  user_data)
+{
+  register GScannerHashVal *hash_val;
+  register GHFunc func;
+  register gpointer func_data;
+  register gpointer *d;
+
+  d = user_data;
+  func = (GHFunc)d[0];
+  func_data = d[1];
+  hash_val = value;
+
+  func (key, hash_val->value, func_data);
+}
+
+void
+g_scanner_foreach_symbol (GScanner       *scanner,
+                         GHFunc          func,
+                         gpointer        func_data)
+{
+  gpointer d[2];
+
+  g_return_if_fail (scanner != NULL);
+
+  d[0] = (gpointer)func;
+  d[1] = func_data;
+
+  g_hash_table_foreach (scanner->symbol_table, g_scanner_foreach_internal, d);
+}
+
+void
+g_scanner_remove_symbol (GScanner      *scanner,
+                        const gchar    *symbol)
+{
+  register GScannerHashVal     *hash_val;
+  
+  g_return_if_fail (scanner != NULL);
+
+  hash_val = g_scanner_lookup_internal (scanner, symbol);
+  
+  if (hash_val)
+    {
+      g_hash_table_remove (scanner->symbol_table, hash_val->key);
+      g_free (hash_val->key);
+      g_free (hash_val);
+    }
+}
+
+void
+g_scanner_freeze_symbol_table (GScanner *scanner)
+{
+  g_return_if_fail (scanner != NULL);
+
+  g_hash_table_freeze (scanner->symbol_table);
+}
+
+void
+g_scanner_thaw_symbol_table (GScanner *scanner)
+{
+  g_return_if_fail (scanner != NULL);
+
+  g_hash_table_thaw (scanner->symbol_table);
+}
+
+GTokenType
+g_scanner_peek_next_token (GScanner    *scanner)
+{
+  g_return_val_if_fail (scanner != NULL, G_TOKEN_EOF);
+  
+  if (scanner->next_token == G_TOKEN_NONE)
+    {
+      scanner->next_line = scanner->line;
+      scanner->next_position = scanner->position;
+      g_scanner_get_token_i (scanner,
+                            &scanner->next_token,
+                            &scanner->next_value,
+                            &scanner->next_line,
+                            &scanner->next_position);
+    }
+  
+  return scanner->next_token;
+}
+
+GTokenType
+g_scanner_get_next_token (GScanner     *scanner)
+{
+  g_return_val_if_fail (scanner != NULL, G_TOKEN_EOF);
+  
+  if (scanner->next_token != G_TOKEN_NONE)
+    {
+      g_scanner_free_value (&scanner->token, &scanner->value);
+      
+      scanner->token = scanner->next_token;
+      scanner->value = scanner->next_value;
+      scanner->line = scanner->next_line;
+      scanner->position = scanner->next_position;
+      scanner->next_token = G_TOKEN_NONE;
+    }
+  else
+    g_scanner_get_token_i (scanner,
+                          &scanner->token,
+                          &scanner->value,
+                          &scanner->line,
+                          &scanner->position);
+  
+  return scanner->token;
+}
+
+GTokenType
+g_scanner_cur_token (GScanner *scanner)
+{
+  g_return_val_if_fail (scanner != NULL, G_TOKEN_EOF);
+  
+  return scanner->token;
+}
+
+GValue
+g_scanner_cur_value (GScanner *scanner)
+{
+  register GValue v;
+  
+  v.v_int = 0;
+  g_return_val_if_fail (scanner != NULL, v);
+  
+  return scanner->value;
+}
+
+guint
+g_scanner_cur_line (GScanner *scanner)
+{
+  g_return_val_if_fail (scanner != NULL, 0);
+  
+  return scanner->line;
+}
+
+guint
+g_scanner_cur_position (GScanner *scanner)
+{
+  g_return_val_if_fail (scanner != NULL, 0);
+  
+  return scanner->position;
+}
+
+gboolean
+g_scanner_eof (GScanner        *scanner)
+{
+  g_return_val_if_fail (scanner != NULL, TRUE);
+  
+  return scanner->token == G_TOKEN_EOF;
+}
+
+static GScannerHashVal*
+g_scanner_lookup_internal (GScanner    *scanner,
+                          const gchar  *symbol)
+{
+  register GScannerHashVal     *hash_val;
+  
+  if (!scanner->config->case_sensitive)
+    {
+      register gchar *buffer;
+      register guint i, l;
+      
+      l = strlen (symbol);
+      buffer = g_new (gchar, l + 1);
+      for (i = 0; i < l; i++)
+       buffer[i] = to_lower (symbol[i]);
+      buffer[i] = 0;
+      hash_val = g_hash_table_lookup (scanner->symbol_table, buffer);
+      g_free (buffer);
+    }
+  else
+    hash_val = g_hash_table_lookup (scanner->symbol_table, (gchar*) symbol);
+  
+  return hash_val;
+}
+
+static guchar
+g_scanner_peek_next_char (GScanner *scanner)
+{
+  guchar fchar;
+  
+  if (scanner->text_len)
+    {
+      fchar = scanner->text[0];
+    }
+  else if (scanner->input_fd >= 0)
+    {
+      if (scanner->peeked_char < 0)
+       {
+         register gint count;
+         
+         do
+           {
+             count = read (scanner->input_fd, &fchar, 1);
+           }
+         while (count == -1 &&
+                (errno == EINTR ||
+                 errno == EAGAIN));
+         
+         if (count != 1)
+           fchar = 0;
+         
+         scanner->peeked_char = fchar;
+       }
+      else
+       fchar = scanner->peeked_char;
+    }
+  else
+    fchar = 0;
+  
+  return fchar;
+}
+
+static guchar
+g_scanner_get_char (GScanner   *scanner,
+                   guint       *line_p,
+                   guint       *position_p)
+{
+  guchar fchar;
+  
+  if (scanner->text_len)
+    {
+      fchar = *(scanner->text++);
+      scanner->text_len--;
+    }
+  else if (scanner->input_fd >= 0)
+    {
+      if (scanner->peeked_char < 0)
+       {
+         register gint count;
+         
+         do
+           {
+             count = read (scanner->input_fd, &fchar, 1);
+           }
+         while (count == -1 &&
+                (errno == EINTR ||
+                 errno == EAGAIN));
+         if (count != 1 || fchar == 0)
+           {
+             fchar = 0;
+             scanner->peeked_char = 0;
+           }
+       }
+      else
+       {
+         fchar = scanner->peeked_char;
+         if (fchar)
+           scanner->peeked_char = -1;
+       }
+    }
+  else
+    fchar = 0;
+  
+  if (fchar == '\n')
+    {
+      (*position_p) = 0;
+      (*line_p)++;
+    }
+  else if (fchar)
+    {
+      (*position_p)++;
+    }
+  
+  return fchar;
+}
+
+void
+g_scanner_unexp_token (GScanner                *scanner,
+                      GTokenType        expected_token,
+                      const gchar      *identifier_spec,
+                      const gchar      *symbol_spec,
+                      const gchar      *symbol_name,
+                      const gchar      *message,
+                      gint              is_error)
+{
+  register gchar       *token_string;
+  register guint       token_string_len;
+  register gchar       *expected_string;
+  register guint       expected_string_len;
+  register gchar       *message_prefix;
+  register gboolean    print_unexp;
+  void (*msg_handler)   (GScanner*, const gchar*, ...);
+  
+  g_return_if_fail (scanner != NULL);
+
+  if (is_error)
+    msg_handler = g_scanner_error;
+  else
+    msg_handler = g_scanner_warn;
+
+  if (!identifier_spec)
+    identifier_spec = "identifier";
+  if (!symbol_spec)
+    symbol_spec = "symbol";
+  
+  token_string_len = 56;
+  token_string = g_new (gchar, token_string_len + 1);
+  expected_string_len = 64;
+  expected_string = g_new (gchar, expected_string_len + 1);
+  print_unexp = TRUE;
+  
+  switch (scanner->token)
+    {
+      
+    case  G_TOKEN_EOF:
+      g_snprintf (token_string, token_string_len, "end of file");
+      break;
+      
+    default:  /* 1 ... 255 */
+      if (scanner->token >= 1 && scanner->token <= 255)
+       {
+         if ((scanner->token >= ' ' && scanner->token <= '~') ||
+             strchr (scanner->config->cset_identifier_first, scanner->token) ||
+             strchr (scanner->config->cset_identifier_nth, scanner->token))
+           g_snprintf (token_string, expected_string_len, "character `%c'", scanner->token);
+         else
+           g_snprintf (token_string, expected_string_len, "character `\\%o'", scanner->token);
+       }
+      else
+       g_snprintf (token_string, token_string_len, "(unknown) token <%d>", scanner->token);
+      break;
+      
+    case  G_TOKEN_ERROR:
+      print_unexp = FALSE;
+      expected_token = G_TOKEN_NONE;
+      switch (scanner->value.v_error)
+       {
+       case  G_ERR_UNEXP_EOF:
+         g_snprintf (token_string, token_string_len, "scanner: unexpected end of file");
+         break;
+         
+       case  G_ERR_UNEXP_EOF_IN_STRING:
+         g_snprintf (token_string, token_string_len, "scanner: unterminated string constant");
+         break;
+         
+       case  G_ERR_UNEXP_EOF_IN_COMMENT:
+         g_snprintf (token_string, token_string_len, "scanner: unterminated comment");
+         break;
+         
+       case  G_ERR_NON_DIGIT_IN_CONST:
+         g_snprintf (token_string, token_string_len, "scanner: non digit in constant");
+         break;
+         
+       case  G_ERR_FLOAT_RADIX:
+         g_snprintf (token_string, token_string_len, "scanner: invalid radix for floating constant");
+         break;
+         
+       case  G_ERR_FLOAT_MALFORMED:
+         g_snprintf (token_string, token_string_len, "scanner: malformed floating constant");
+         break;
+         
+       case  G_ERR_DIGIT_RADIX:
+         g_snprintf (token_string, token_string_len, "scanner: digit is beyond radix");
+         break;
+         
+       case  G_ERR_UNKNOWN:
+       default:
+         g_snprintf (token_string, token_string_len, "scanner: unknown error");
+         break;
+       }
+      break;
+      
+    case  G_TOKEN_CHAR:
+      g_snprintf (token_string, token_string_len, "character `%c'", scanner->value.v_char);
+      break;
+      
+    case  G_TOKEN_SYMBOL:
+      if (expected_token == G_TOKEN_SYMBOL)
+       print_unexp = FALSE;
+      if (symbol_name)
+       g_snprintf (token_string,
+                 token_string_len,
+                 "%s%s `%s'",
+                 print_unexp ? "" : "invalid ",
+                 symbol_spec,
+                 symbol_name);
+      else
+       g_snprintf (token_string,
+                 token_string_len,
+                 "%s%s",
+                 print_unexp ? "" : "invalid ",
+                 symbol_spec);
+      break;
+      
+    case  G_TOKEN_IDENTIFIER:
+      if (expected_token == G_TOKEN_IDENTIFIER)
+       print_unexp = FALSE;
+      g_snprintf (token_string,
+               token_string_len,
+               "%s%s `%s'",
+               print_unexp ? "" : "invalid ",
+               identifier_spec,
+               scanner->value.v_string);
+      break;
+      
+    case  G_TOKEN_BINARY:
+    case  G_TOKEN_OCTAL:
+    case  G_TOKEN_INT:
+    case  G_TOKEN_HEX:
+      g_snprintf (token_string, token_string_len, "number `%ld'", scanner->value.v_int);
+      break;
+      
+    case  G_TOKEN_FLOAT:
+      g_snprintf (token_string, token_string_len, "number `%.3f'", scanner->value.v_float);
+      break;
+      
+    case  G_TOKEN_STRING:
+      g_snprintf (token_string,
+               token_string_len,
+               "%sstring constant \"%s\"",
+               scanner->value.v_string[0] == 0 ? "empty " : "",
+               scanner->value.v_string);
+      token_string[token_string_len - 2] = '"';
+      token_string[token_string_len - 1] = 0;
+      break;
+      
+    case  G_TOKEN_COMMENT_SINGLE:
+    case  G_TOKEN_COMMENT_MULTI:
+      g_snprintf (token_string, token_string_len, "comment");
+      break;
+      
+    case  G_TOKEN_NONE:
+      g_assert_not_reached ();
+      break;
+    }
+  
+  
+  switch (expected_token)
+    {
+    default: /* 1 ... 255 */
+      if (expected_token >= 1 && expected_token <= 255)
+       {
+         if ((expected_token >= ' ' && expected_token <= '~') ||
+             strchr (scanner->config->cset_identifier_first, expected_token) ||
+             strchr (scanner->config->cset_identifier_nth, expected_token))
+           g_snprintf (expected_string, expected_string_len, "character `%c'", expected_token);
+         else
+           g_snprintf (expected_string, expected_string_len, "character `\\%o'", expected_token);
+       }
+      else
+       g_snprintf (expected_string, expected_string_len, "(unknown) token <%d>", expected_token);
+      break;
+      
+    case  G_TOKEN_INT:
+      g_snprintf (expected_string, expected_string_len, "number (integer)");
+      break;
+      
+    case  G_TOKEN_FLOAT:
+      g_snprintf (expected_string, expected_string_len, "number (float)");
+      break;
+      
+    case  G_TOKEN_STRING:
+      g_snprintf (expected_string, expected_string_len, "string constant");
+      break;
+      
+    case  G_TOKEN_SYMBOL:
+      g_snprintf (expected_string,
+               expected_string_len,
+               "%s%s",
+               scanner->token == G_TOKEN_SYMBOL ? "valid " : "",
+               symbol_spec);
+      break;
+      
+    case  G_TOKEN_IDENTIFIER:
+      g_snprintf (expected_string,
+               expected_string_len,
+               "%s%s",
+               scanner->token == G_TOKEN_IDENTIFIER ? "valid " : "",
+               identifier_spec);
+      break;
+      
+    case  G_TOKEN_NONE:
+      break;
+    }
+  
+  if (message && message[0] != 0)
+    message_prefix = " - ";
+  else
+    {
+      message_prefix = "";
+      message = "";
+    }
+  
+  if (expected_token != G_TOKEN_NONE)
+    {
+      if (print_unexp)
+       msg_handler (scanner,
+                    "unexpected %s, expected %s%s%s",
+                    token_string,
+                    expected_string,
+                    message_prefix,
+                    message);
+      else
+       msg_handler (scanner,
+                    "%s, expected %s%s%s",
+                    token_string,
+                    expected_string,
+                    message_prefix,
+                    message);
+    }
+  else
+    {
+      if (print_unexp)
+       msg_handler (scanner,
+                    "unexpected %s%s%s",
+                    token_string,
+                    message_prefix,
+                    message);
+      else
+       msg_handler (scanner,
+                    "%s%s%s",
+                    token_string,
+                    message_prefix,
+                    message);
+    }
+  
+  g_free (token_string);
+  g_free (expected_string);
+}
+
+gint
+g_scanner_stat_mode (const gchar *filename)
+{
+  struct stat  *stat_buf;
+  gint          st_mode;
+
+  stat_buf = g_new0 (struct stat, 1);
+
+  lstat (filename, stat_buf);
+
+  st_mode = stat_buf->st_mode;
+
+  g_free (stat_buf);
+
+  return st_mode;
+}
+
+static void
+g_scanner_free_value (GTokenType     *token_p,
+                     GValue         *value_p)
+{
+  switch (*token_p)
+    {
+    case  G_TOKEN_STRING:
+    case  G_TOKEN_IDENTIFIER:
+    case  G_TOKEN_IDENTIFIER_NULL:
+    case  G_TOKEN_COMMENT_SINGLE:
+    case  G_TOKEN_COMMENT_MULTI:
+      g_free (value_p->v_string);
+      break;
+      
+    default:
+      break;
+    }
+  
+  *token_p = G_TOKEN_NONE;
+}
+
+static void
+g_scanner_get_token_i (GScanner        *scanner,
+                      GTokenType       *token_p,
+                      GValue           *value_p,
+                      guint            *line_p,
+                      guint            *position_p)
+{
+  do
+    {
+      g_scanner_free_value (token_p, value_p);
+      g_scanner_get_token_ll (scanner, token_p, value_p, line_p, position_p);
+    }
+  while (((*token_p > 0 && *token_p < 256) &&
+         strchr (scanner->config->cset_skip_characters, *token_p)) ||
+        (*token_p == G_TOKEN_CHAR &&
+         strchr (scanner->config->cset_skip_characters, value_p->v_char)) ||
+        (*token_p == G_TOKEN_COMMENT_MULTI &&
+         scanner->config->skip_comment_multi) ||
+        (*token_p == G_TOKEN_COMMENT_SINGLE &&
+         scanner->config->skip_comment_single));
+  
+  switch (*token_p)
+    {
+    case       G_TOKEN_IDENTIFIER:
+      if (scanner->config->identifier_2_string)
+       *token_p = G_TOKEN_STRING;
+      break;
+      
+    case       G_TOKEN_SYMBOL:
+      if (scanner->config->symbol_2_token)
+       *token_p = (GTokenType) value_p->v_symbol;
+      break;
+      
+    case       G_TOKEN_BINARY:
+    case       G_TOKEN_OCTAL:
+    case       G_TOKEN_HEX:
+      if (scanner->config->numbers_2_int)
+       *token_p = G_TOKEN_INT;
+      break;
+      
+    default:
+      break;
+    }
+  
+  if (*token_p == G_TOKEN_INT &&
+      scanner->config->int_2_float)
+    {
+      *token_p = G_TOKEN_FLOAT;
+      value_p->v_float = value_p->v_int;
+    }
+  
+  errno = 0;
+}
+
+static void
+g_scanner_get_token_ll (GScanner       *scanner,
+                        GTokenType     *token_p,
+                        GValue         *value_p,
+                        guint          *line_p,
+                        guint          *position_p)
+{
+  register GScannerConfig      *config;
+  register gboolean            in_comment_multi;
+  register gboolean            in_comment_single;
+  register gboolean            in_string_sq;
+  register gboolean            in_string_dq;
+  static   guchar              ch;
+  register GTokenType          token;
+  register GValue              value;
+  register GString             *gstring;
+  
+  config = scanner->config;
+  (*value_p).v_int = 0;
+  
+  if (scanner->token == G_TOKEN_EOF ||
+      (!scanner->text_len &&
+       (scanner->input_fd < 0 ||
+       scanner->peeked_char == 0)))
+    {
+      *token_p = G_TOKEN_EOF;
+      return;
+    }
+  
+  in_comment_multi = FALSE;
+  in_comment_single = FALSE;
+  in_string_sq = FALSE;
+  in_string_dq = FALSE;
+  gstring = NULL;
+  
+  do
+    {
+      register gboolean                dotted_float = FALSE;
+      
+      ch = g_scanner_get_char (scanner, line_p, position_p);
+      
+      value.v_int = 0;
+      token = G_TOKEN_NONE;
+      
+      /* this is *evil*, but needed ;(
+       * we first check for identifier first character, because         it
+       * might interfere with other key chars like slashes or numbers
+       */
+      if (config->scan_identifier &&
+         ch && strchr (config->cset_identifier_first, ch))
+       goto identifier_precedence;
+      
+      switch (ch)
+       {
+         register gboolean     in_number;
+         static         gchar          *endptr;
+         
+       case  0:
+         token = G_TOKEN_EOF;
+         (*position_p)++;
+         ch = 0;
+         break;
+         
+       case  '/':
+         if (!config->scan_comment_multi ||
+             g_scanner_peek_next_char (scanner) != '*')
+           goto default_case;
+         g_scanner_get_char (scanner, line_p, position_p);
+         token = G_TOKEN_COMMENT_MULTI;
+         in_comment_multi = TRUE;
+         gstring = g_string_new ("");
+         while ((ch = g_scanner_get_char (scanner, line_p, position_p)) != 0)
+           {
+             if (ch == '*' && g_scanner_peek_next_char (scanner) == '/')
+               {
+                 g_scanner_get_char (scanner, line_p, position_p);
+                 in_comment_multi = FALSE;
+                 break;
+               }
+             else
+               gstring = g_string_append_c (gstring, ch);
+           }
+         ch = 0;
+         break;
+         
+       case  '\'':
+         if (!config->scan_string_sq)
+           goto default_case;
+         token = G_TOKEN_STRING;
+         in_string_sq = TRUE;
+         gstring = g_string_new ("");
+         while ((ch = g_scanner_get_char (scanner, line_p, position_p)) != 0)
+           {
+             if (ch == '\'')
+               {
+                 in_string_sq = FALSE;
+                 break;
+               }
+             else
+               gstring = g_string_append_c (gstring, ch);
+           }
+         ch = 0;
+         break;
+         
+       case  '"':
+         if (!config->scan_string_dq)
+           goto default_case;
+         token = G_TOKEN_STRING;
+         in_string_dq = TRUE;
+         gstring = g_string_new ("");
+         while ((ch = g_scanner_get_char (scanner, line_p, position_p)) != 0)
+           {
+             if (ch == '"')
+               {
+                 in_string_dq = FALSE;
+                 break;
+               }
+             else
+               {
+                 if (ch == '\\')
+                   {
+                     ch = g_scanner_get_char (scanner, line_p, position_p);
+                     switch (ch)
+                       {
+                         register guint        i;
+                         register guint        fchar;
+                         
+                       case  0:
+                         break;
+                         
+                       case  '\\':
+                         gstring = g_string_append_c (gstring, '\\');
+                         break;
+                         
+                       case  'n':
+                         gstring = g_string_append_c (gstring, '\n');
+                         break;
+                         
+                       case  't':
+                         gstring = g_string_append_c (gstring, '\t');
+                         break;
+                         
+                       case  'r':
+                         gstring = g_string_append_c (gstring, '\r');
+                         break;
+                         
+                       case  'b':
+                         gstring = g_string_append_c (gstring, '\b');
+                         break;
+                         
+                       case  'f':
+                         gstring = g_string_append_c (gstring, '\f');
+                         break;
+                         
+                       case  '0':
+                       case  '1':
+                       case  '2':
+                       case  '3':
+                       case  '4':
+                       case  '5':
+                       case  '6':
+                       case  '7':
+                         i = ch - '0';
+                         fchar = g_scanner_peek_next_char (scanner);
+                         if (fchar >= '0' && fchar <= '7')
+                           {
+                             ch = g_scanner_get_char (scanner, line_p, position_p);
+                             i= i * 8 + ch - '0';
+                             fchar = g_scanner_peek_next_char (scanner);
+                             if (fchar >= '0' && fchar <= '7')
+                               {
+                                 ch = g_scanner_get_char (scanner, line_p, position_p);
+                                 i = i * 8 + ch - '0';
+                               }
+                           }
+                         gstring = g_string_append_c (gstring, i);
+                         break;
+                         
+                       default:
+                         gstring = g_string_append_c (gstring, ch);
+                         break;
+                       }
+                   }
+                 else
+                   gstring = g_string_append_c (gstring, ch);
+               }
+           }
+         ch = 0;
+         break;
+         
+       case  '.':
+         if (!config->scan_float)
+           goto default_case;
+         token = G_TOKEN_FLOAT;
+         dotted_float = TRUE;
+         ch = g_scanner_get_char (scanner, line_p, position_p);
+         goto number_parsing;
+         
+       case  '$':
+         if (!config->scan_hex_dollar)
+           goto default_case;
+         token = G_TOKEN_HEX;
+         ch = g_scanner_get_char (scanner, line_p, position_p);
+         goto number_parsing;
+         
+       case  '0':
+         if (config->scan_octal)
+           token = G_TOKEN_OCTAL;
+         else
+           token = G_TOKEN_INT;
+         ch = g_scanner_peek_next_char (scanner);
+         if (config->scan_hex && (ch == 'x' || ch == 'X'))
+           {
+             token = G_TOKEN_HEX;
+             g_scanner_get_char (scanner, line_p, position_p);
+             ch = g_scanner_get_char (scanner, line_p, position_p);
+             if (ch == 0)
+               {
+                 token = G_TOKEN_ERROR;
+                 value.v_error = G_ERR_UNEXP_EOF;
+                 (*position_p)++;
+                 break;
+               }
+             if (g_scanner_char_2_num (ch, 16) < 0)
+               {
+                 token = G_TOKEN_ERROR;
+                 value.v_error = G_ERR_DIGIT_RADIX;
+                 ch = 0;
+                 break;
+               }
+           }
+         else if (config->scan_binary && (ch == 'b' || ch == 'B'))
+           {
+             token = G_TOKEN_BINARY;
+             g_scanner_get_char (scanner, line_p, position_p);
+             ch = g_scanner_get_char (scanner, line_p, position_p);
+             if (ch == 0)
+               {
+                 token = G_TOKEN_ERROR;
+                 value.v_error = G_ERR_UNEXP_EOF;
+                 (*position_p)++;
+                 break;
+               }
+             if (g_scanner_char_2_num (ch, 10) < 0)
+               {
+                 token = G_TOKEN_ERROR;
+                 value.v_error = G_ERR_NON_DIGIT_IN_CONST;
+                 ch = 0;
+                 break;
+               }
+           }
+         else
+           ch = '0';
+         /* fall through */
+       case  '1':
+       case  '2':
+       case  '3':
+       case  '4':
+       case  '5':
+       case  '6':
+       case  '7':
+       case  '8':
+       case  '9':
+       number_parsing:
+       if (token == G_TOKEN_NONE)
+         token = G_TOKEN_INT;
+       
+       gstring = g_string_new (dotted_float ? "0." : "");
+       gstring = g_string_append_c (gstring, ch);
+       in_number = TRUE;
+       while (in_number)
+         {
+           register gboolean is_E;
+           
+           is_E = (ch == 'e' || ch == 'E') && token == G_TOKEN_FLOAT;
+           ch = g_scanner_peek_next_char (scanner);
+           
+           if (g_scanner_char_2_num (ch, 36) >= 0 ||
+               (config->scan_float && ch == '.') ||
+               (is_E && ch == '+') ||
+               (is_E && ch == '-') )
+             ch = g_scanner_get_char (scanner, line_p, position_p);
+           else
+             in_number = FALSE;
+           
+           if (in_number)
+             switch (ch)
+               {
+               case  '.':
+                 if (token != G_TOKEN_INT &&
+                     token != G_TOKEN_OCTAL)
+                   {
+                     token = G_TOKEN_ERROR;
+                     if (token == G_TOKEN_FLOAT)
+                       value.v_error = G_ERR_FLOAT_MALFORMED;
+                     else
+                       value.v_error = G_ERR_FLOAT_RADIX;
+                     in_number = FALSE;
+                   }
+                 else
+                   {
+                     token = G_TOKEN_FLOAT;
+                     gstring = g_string_append_c (gstring, ch);
+                   }
+                 break;
+                 
+               case    '0':
+               case  '1':
+               case  '2':
+               case  '3':
+               case  '4':
+               case  '5':
+               case  '6':
+               case  '7':
+               case  '8':
+               case  '9':
+                 gstring = g_string_append_c (gstring, ch);
+                 break;
+                 
+               case    '-':
+               case    '+':
+                 if (token != G_TOKEN_FLOAT)
+                   {
+                     token = G_TOKEN_ERROR;
+                     value.v_error = G_ERR_NON_DIGIT_IN_CONST;
+                     in_number = FALSE;
+                   }
+                 else
+                   gstring = g_string_append_c (gstring, ch);
+                 break;
+                 
+               case    'e':
+               case    'E':
+                 if ((token != G_TOKEN_HEX && !config->scan_float) ||
+                     (token != G_TOKEN_HEX &&
+                      token != G_TOKEN_OCTAL &&
+                      token != G_TOKEN_FLOAT &&
+                      token != G_TOKEN_INT))
+                   {
+                     token = G_TOKEN_ERROR;
+                     value.v_error = G_ERR_NON_DIGIT_IN_CONST;
+                     in_number = FALSE;
+                   }
+                 else
+                   {
+                     if (token != G_TOKEN_HEX)
+                       token = G_TOKEN_FLOAT;
+                     gstring = g_string_append_c (gstring, ch);
+                   }
+                 break;
+                 
+               default:
+                 if (token != G_TOKEN_HEX)
+                   {
+                     token = G_TOKEN_ERROR;
+                     value.v_error = G_ERR_NON_DIGIT_IN_CONST;
+                     in_number = FALSE;
+                   }
+                 else
+                   gstring = g_string_append_c (gstring, ch);
+                 break;
+               }
+         }
+       endptr = NULL;
+       switch (token)
+         {
+         case  G_TOKEN_BINARY:
+           value.v_binary = strtol (gstring->str, &endptr, 2);
+           break;
+           
+         case  G_TOKEN_OCTAL:
+           value.v_octal = strtol (gstring->str, &endptr, 8);
+           break;
+           
+         case  G_TOKEN_INT:
+           value.v_int = strtol (gstring->str, &endptr, 10);
+           break;
+           
+         case  G_TOKEN_FLOAT:
+           value.v_float = g_strtod (gstring->str, &endptr);
+           break;
+           
+         case  G_TOKEN_HEX:
+           value.v_hex = strtol (gstring->str, &endptr, 16);
+           break;
+           
+         default:
+           break;
+         }
+       if (endptr && *endptr)
+         {
+           token = G_TOKEN_ERROR;
+           if (*endptr == 'e' || *endptr == 'E')
+             value.v_error = G_ERR_NON_DIGIT_IN_CONST;
+           else
+             value.v_error = G_ERR_DIGIT_RADIX;
+         }
+       g_string_free (gstring, TRUE);
+       gstring = NULL;
+       ch = 0;
+       break;
+       
+       default:
+       default_case:
+       if (config->cpair_comment_single &&
+           ch == config->cpair_comment_single[0])
+         {
+           token = G_TOKEN_COMMENT_SINGLE;
+           in_comment_single = TRUE;
+           gstring = g_string_new ("");
+           while ((ch = g_scanner_get_char (scanner,
+                                            line_p,
+                                            position_p)) != 0)
+             {
+               if (ch == config->cpair_comment_single[1])
+                 {
+                   in_comment_single = FALSE;
+                   ch = 0;
+                   break;
+                 }
+               
+               gstring = g_string_append_c (gstring, ch);
+               ch = 0;
+             }
+         }
+       else if (config->scan_identifier && ch &&
+                strchr (config->cset_identifier_first, ch))
+         {
+         identifier_precedence:
+           
+           if (config->cset_identifier_nth && ch &&
+               strchr (config->cset_identifier_nth,
+                       g_scanner_peek_next_char (scanner)))
+             {
+               token = G_TOKEN_IDENTIFIER;
+               gstring = g_string_new ("");
+               gstring = g_string_append_c (gstring, ch);
+               do
+                 {
+                   ch = g_scanner_get_char (scanner, line_p, position_p);
+                   gstring = g_string_append_c (gstring, ch);
+                   ch = g_scanner_peek_next_char (scanner);
+                 }
+               while (ch && strchr (config->cset_identifier_nth, ch));
+               ch = 0;
+             }
+           else if (config->scan_identifier_1char)
+             {
+               token = G_TOKEN_IDENTIFIER;
+               value.v_identifier = g_new0 (gchar, 2);
+               value.v_identifier[0] = ch;
+               ch = 0;
+             }
+         }
+       if (ch)
+         {
+           if (config->char_2_token)
+             token = ch;
+           else
+             {
+               token = G_TOKEN_CHAR;
+               value.v_char = ch;
+             }
+           ch = 0;
+         }
+       break;
+       }
+      g_assert (ch == 0 && token != G_TOKEN_NONE);
+    }
+  while (ch != 0);
+  
+  if (in_comment_multi ||
+      in_comment_single ||
+      in_string_sq ||
+      in_string_dq)
+    {
+      token = G_TOKEN_ERROR;
+      if (gstring)
+       {
+         g_string_free (gstring, TRUE);
+         gstring = NULL;
+       }
+      (*position_p)++;
+      if (in_comment_multi || in_comment_single)
+       value.v_error = G_ERR_UNEXP_EOF_IN_COMMENT;
+      else if (in_string_sq || in_string_dq)
+       value.v_error = G_ERR_UNEXP_EOF_IN_STRING;
+    }
+  
+  if (gstring)
+    {
+      value.v_string = gstring->str;
+      g_string_free (gstring, FALSE);
+      gstring = NULL;
+    }
+  
+  if (token == G_TOKEN_IDENTIFIER &&
+      config->scan_symbols)
+    {
+      register GScannerHashVal *hash_val;
+      
+      hash_val = g_scanner_lookup_internal (scanner, value.v_identifier);
+      
+      if (hash_val)
+       {
+         g_free (value.v_identifier);
+         token = G_TOKEN_SYMBOL;
+         value.v_symbol = hash_val->value;
+       }
+    }
+
+  if (token == G_TOKEN_IDENTIFIER &&
+      config->scan_identifier_NULL &&
+      strlen (value.v_identifier) == 4)
+    {
+      gchar *null_upper = "NULL";
+      gchar *null_lower = "null";
+      
+      if (scanner->config->case_sensitive)
+       {
+         if (value.v_identifier[0] == null_upper[0] &&
+             value.v_identifier[1] == null_upper[1] &&
+             value.v_identifier[2] == null_upper[2] &&
+             value.v_identifier[3] == null_upper[3])
+           token = G_TOKEN_IDENTIFIER_NULL;
+       }
+      else
+       {
+         if ((value.v_identifier[0] == null_upper[0] ||
+              value.v_identifier[0] == null_lower[0]) &&
+             (value.v_identifier[1] == null_upper[1] ||
+              value.v_identifier[1] == null_lower[1]) &&
+             (value.v_identifier[2] == null_upper[2] ||
+              value.v_identifier[2] == null_lower[2]) &&
+             (value.v_identifier[3] == null_upper[3] ||
+              value.v_identifier[3] == null_lower[3]))
+           token = G_TOKEN_IDENTIFIER_NULL;
+       }
+    }
+  
+  *token_p = token;
+  *value_p = value;
+}
diff --git a/gslist.c b/gslist.c
new file mode 100644 (file)
index 0000000..3a201b4
--- /dev/null
+++ b/gslist.c
@@ -0,0 +1,456 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "glib.h"
+
+
+typedef struct _GRealListAllocator GRealListAllocator;
+
+struct _GRealListAllocator
+{
+  GMemChunk *list_mem_chunk;
+  GSList    *free_list;
+};
+
+
+static GRealListAllocator *default_allocator = NULL;
+static GRealListAllocator *current_allocator = NULL;
+
+GListAllocator*
+g_slist_set_allocator (GListAllocator* fallocator)
+{
+  GRealListAllocator* allocator = (GRealListAllocator *) fallocator;
+  GRealListAllocator* old_allocator = current_allocator;
+
+  if (allocator)
+    current_allocator = allocator;
+  else
+    {
+      if (!default_allocator)
+       default_allocator = (GRealListAllocator*) g_list_allocator_new ();
+      current_allocator = default_allocator;
+    }
+
+  if (!current_allocator->list_mem_chunk)
+    current_allocator->list_mem_chunk = g_mem_chunk_new ("slist mem chunk",
+                                                        sizeof (GSList),
+                                                        1024,
+                                                        G_ALLOC_ONLY);
+
+  return (GListAllocator*) (old_allocator == default_allocator ? NULL : old_allocator);
+}
+
+
+GSList*
+g_slist_alloc (void)
+{
+  GSList *new_list;
+
+  g_slist_set_allocator (NULL);
+  if (current_allocator->free_list)
+    {
+      new_list = current_allocator->free_list;
+      current_allocator->free_list = current_allocator->free_list->next;
+    }
+  else
+    {
+      new_list = g_chunk_new (GSList, current_allocator->list_mem_chunk);
+    }
+
+  new_list->data = NULL;
+  new_list->next = NULL;
+
+  return new_list;
+}
+
+void
+g_slist_free (GSList *list)
+{
+  GSList *last;
+
+  if (list)
+    {
+      last = g_slist_last (list);
+      last->next = current_allocator->free_list;
+      current_allocator->free_list = list;
+    }
+}
+
+void
+g_slist_free_1 (GSList *list)
+{
+  if (list)
+    {
+      list->next = current_allocator->free_list;
+      current_allocator->free_list = list;
+    }
+}
+
+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_reverse (GSList *list)
+{
+  GSList *tmp;
+  GSList *prev;
+  GSList *last;
+
+  last = NULL;
+  prev = NULL;
+
+  while (list)
+    {
+      last = list;
+
+      tmp = list->next;
+      list->next = prev;
+
+      prev = list;
+      list = tmp;
+    }
+
+  return last;
+}
+
+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;
+    }
+}
diff --git a/gstring.c b/gstring.c
new file mode 100644 (file)
index 0000000..8350552
--- /dev/null
+++ b/gstring.c
@@ -0,0 +1,647 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <glib.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.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;
+};
+
+
+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;
+}
+
+/* a char* hash function from ASU */
+guint
+g_str_hash (gconstpointer v)
+{
+  const char *s = (char*)v;
+  const char *p;
+  guint h=0, g;
+
+  for(p = s; *p != '\0'; p += 1) {
+    h = ( h << 4 ) + *p;
+    if ( ( g = h & 0xf0000000 ) ) {
+      h = h ^ (g >> 24);
+      h = h ^ g;
+    }
+  }
+
+  return h /* % M */;
+}
+
+
+/* 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)
+    {
+      GListAllocator *tmp_allocator = g_slist_set_allocator (NULL);
+
+      for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next)
+       g_free (tmp_list->data);
+
+      g_slist_free (chunk->storage_list);
+
+      g_slist_set_allocator (tmp_allocator);
+    }
+
+  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)
+    {
+      GListAllocator *tmp_allocator = g_slist_set_allocator (NULL);
+      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;
+
+      g_slist_set_allocator (tmp_allocator);
+    }
+
+  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;
+
+  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);
+
+  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_mem_chunk_free (string_mem_chunk, string);
+}
+
+GString*
+g_string_assign (GString *lval,
+                const gchar *rval)
+{
+  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);
+
+  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;
+  gchar *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;
+  gchar *s;
+
+  g_return_val_if_fail (string != NULL, NULL);
+
+  s = string->str;
+
+  while (*s)
+    {
+      *s = toupper (*s);
+      s++;
+    }
+
+  return fstring;
+}
+
+static int
+get_length_upper_bound (const gchar* fmt, va_list *args)
+{
+  int len = 0;
+  int short_int;
+  int long_int;
+  int done;
+  char *tmp;
+
+  while (*fmt)
+    {
+      char c = *fmt++;
+
+      short_int = FALSE;
+      long_int = FALSE;
+
+      if (c == '%')
+       {
+         done = FALSE;
+         while (*fmt && !done)
+           {
+             switch (*fmt++)
+               {
+               case '*':
+                 len += va_arg(*args, int);
+                 break;
+               case '1':
+               case '2':
+               case '3':
+               case '4':
+               case '5':
+               case '6':
+               case '7':
+               case '8':
+               case '9':
+                 fmt -= 1;
+                 len += strtol (fmt, (char **)&fmt, 10);
+                 break;
+               case 'h':
+                 short_int = TRUE;
+                 break;
+               case 'l':
+                 long_int = TRUE;
+                 break;
+
+                 /* I ignore 'q' and 'L', they're not portable anyway. */
+
+               case 's':
+                 tmp = va_arg(*args, char *);
+                 if(tmp)
+                   len += strlen (tmp);
+                 else
+                   len += strlen ("(null)");
+                 done = TRUE;
+                 break;
+               case 'd':
+               case 'i':
+               case 'o':
+               case 'u':
+               case 'x':
+               case 'X':
+                 if (long_int)
+                   (void)va_arg (*args, long);
+                 else if (short_int)
+                   (void)va_arg (*args, int);
+                 else
+                   (void)va_arg (*args, int);
+                 len += 32;
+                 done = TRUE;
+                 break;
+               case 'D':
+               case 'O':
+               case 'U':
+                 (void)va_arg (*args, long);
+                 len += 32;
+                 done = TRUE;
+                 break;
+               case 'e':
+               case 'E':
+               case 'f':
+               case 'g':
+                 (void)va_arg (*args, double);
+                 len += 32;
+                 done = TRUE;
+                 break;
+               case 'c':
+                 (void)va_arg (*args, int);
+                 len += 1;
+                 done = TRUE;
+                 break;
+               case 'p':
+               case 'n':
+                 (void)va_arg (*args, void*);
+                 len += 32;
+                 done = TRUE;
+                 break;
+               case '%':
+                 len += 1;
+                 done = TRUE;
+                 break;
+               default:
+                 break;
+               }
+           }
+       }
+      else
+       len += 1;
+    }
+
+  return len;
+}
+
+char*
+g_vsprintf (const gchar *fmt,
+           va_list *args,
+           va_list *args2)
+{
+  static gchar *buf = NULL;
+  static gint   alloc = 0;
+
+  gint len = get_length_upper_bound (fmt, args);
+
+  if (len >= alloc)
+    {
+      if (buf)
+       g_free (buf);
+
+      alloc = nearest_pow (MAX(len + 1, 1024));
+
+      buf = g_new (char, alloc);
+    }
+
+  vsprintf (buf, fmt, *args2);
+
+  return buf;
+}
+
+static void
+g_string_sprintfa_int (GString *string,
+                      const gchar *fmt,
+                      va_list *args,
+                      va_list *args2)
+{
+  g_string_append (string, g_vsprintf (fmt, args, args2));
+}
+
+void
+g_string_sprintf (GString *string,
+                 const gchar *fmt,
+                 ...)
+{
+  va_list args, args2;
+
+  va_start(args, fmt);
+  va_start(args2, fmt);
+
+  g_string_truncate (string, 0);
+
+  g_string_sprintfa_int (string, fmt, &args, &args2);
+
+  va_end(args);
+  va_end(args2);
+}
+
+void
+g_string_sprintfa (GString *string,
+                  const gchar *fmt,
+                  ...)
+{
+  va_list args, args2;
+
+  va_start(args, fmt);
+  va_start(args2, fmt);
+
+  g_string_sprintfa_int (string, fmt, &args, &args2);
+
+  va_end(args);
+  va_end(args2);
+}
diff --git a/gtimer.c b/gtimer.c
new file mode 100644 (file)
index 0000000..47946b3
--- /dev/null
+++ b/gtimer.c
@@ -0,0 +1,120 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <sys/time.h>
+#include <unistd.h>
+#include "glib.h"
+
+
+typedef struct _GRealTimer GRealTimer;
+
+struct _GRealTimer
+{
+  struct timeval start;
+  struct timeval end;
+  gint active;
+};
+
+
+GTimer*
+g_timer_new (void)
+{
+  GRealTimer *timer;
+
+  timer = g_new (GRealTimer, 1);
+  timer->active = TRUE;
+
+  gettimeofday (&timer->start, NULL);
+
+  return ((GTimer*) timer);
+}
+
+void
+g_timer_destroy (GTimer *timer)
+{
+  g_assert (timer != NULL);
+
+  g_free (timer);
+}
+
+void
+g_timer_start (GTimer *timer)
+{
+  GRealTimer *rtimer;
+
+  g_assert (timer != NULL);
+
+  rtimer = (GRealTimer*) timer;
+  gettimeofday (&rtimer->start, NULL);
+  rtimer->active = 1;
+}
+
+void
+g_timer_stop (GTimer *timer)
+{
+  GRealTimer *rtimer;
+
+  g_assert (timer != NULL);
+
+  rtimer = (GRealTimer*) timer;
+  gettimeofday (&rtimer->end, NULL);
+  rtimer->active = 0;
+}
+
+void
+g_timer_reset (GTimer *timer)
+{
+  GRealTimer *rtimer;
+
+  g_assert (timer != NULL);
+
+  rtimer = (GRealTimer*) timer;
+  gettimeofday (&rtimer->start, NULL);
+}
+
+gdouble
+g_timer_elapsed (GTimer *timer,
+                gulong *microseconds)
+{
+  GRealTimer *rtimer;
+  struct timeval elapsed;
+  gdouble total;
+
+  g_assert (timer != NULL);
+
+  rtimer = (GRealTimer*) timer;
+
+  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 (microseconds)
+    *microseconds = elapsed.tv_usec;
+
+  return total;
+}
diff --git a/gtree.c b/gtree.c
new file mode 100644 (file)
index 0000000..981ff39
--- /dev/null
+++ b/gtree.c
@@ -0,0 +1,719 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "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);
+
+
+static GMemChunk *node_mem_chunk = NULL;
+static GSList *node_free_list = NULL;
+
+
+GTree*
+g_tree_new (GCompareFunc key_compare_func)
+{
+  GRealTree *rtree;
+
+  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;
+
+  g_return_if_fail (rtree->root != NULL);
+
+  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;
+    }
+}
+
+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);
+  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);
+  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);
+  return 0;
+}
+
+
+static GTreeNode*
+g_tree_node_new (gpointer key,
+                gpointer value)
+{
+  GTreeNode *node;
+  GSList *tmp_list;
+
+  if (node_free_list)
+    {
+      tmp_list = node_free_list;
+      node_free_list = node_free_list->next;
+
+      node = tmp_list->data;
+
+      {
+       GListAllocator *tmp_allocator = g_list_set_allocator (NULL);
+       g_slist_free_1 (tmp_list);
+       g_list_set_allocator (tmp_allocator);
+      }
+    }
+  else
+    {
+      if (!node_mem_chunk)
+       node_mem_chunk = g_mem_chunk_new ("tree node mem chunk", sizeof (GTreeNode), 1024, G_ALLOC_ONLY);
+
+      node = g_chunk_new (GTreeNode, node_mem_chunk);
+    }
+
+  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)
+    {
+      node_free_list = g_slist_prepend (node_free_list, node);
+      g_tree_node_destroy (node->right);
+      g_tree_node_destroy (node->left);
+    }
+}
+
+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 *garbage;
+  GTreeNode *new_root;
+  gint old_balance;
+  gint cmp;
+
+  if (!node)
+    return NULL;
+
+  cmp = (* compare) (key, node->key);
+  if (cmp == 0)
+    {
+      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);
+       }
+
+      node_free_list = g_slist_prepend (node_free_list, garbage);
+    }
+  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;
+  GTreeNode *right;
+  gint a_bal;
+  gint b_bal;
+
+  left = node->left;
+  right = node->right;
+
+  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_print ("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);
+    }
+}
diff --git a/gutils.c b/gutils.c
new file mode 100644 (file)
index 0000000..8528163
--- /dev/null
+++ b/gutils.c
@@ -0,0 +1,858 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+#include <ctype.h>             /* For tolower() */
+#include "glib.h"
+
+const guint glib_major_version = GLIB_MAJOR_VERSION;
+const guint glib_minor_version = GLIB_MINOR_VERSION;
+const guint glib_micro_version = GLIB_MICRO_VERSION;
+
+extern char* g_vsprintf (const gchar *fmt, va_list *args, va_list *args2);
+
+gchar*
+g_strdup (const gchar *str)
+{
+  gchar *new_str;
+  
+  new_str = NULL;
+  if (str)
+    {
+      new_str = g_new (char, strlen (str) + 1);
+      strcpy (new_str, str);
+    }
+  
+  return new_str;
+}
+
+gchar*
+g_strconcat (const gchar *string1, ...)
+{
+  guint          l;
+  va_list args;
+  gchar          *s;
+  gchar          *concat;
+  
+  g_return_val_if_fail (string1 != NULL, NULL);
+  
+  l = 1 + strlen (string1);
+  va_start (args, string1);
+  s = va_arg (args, gchar*);
+  while (s)
+    {
+      l += strlen (s);
+      s = va_arg (args, gchar*);
+    }
+  va_end (args);
+  
+  concat = g_new (gchar, l);
+  concat[0] = 0;
+  
+  strcat (concat, string1);
+  va_start (args, string1);
+  s = va_arg (args, gchar*);
+  while (s)
+    {
+      strcat (concat, s);
+      s = va_arg (args, gchar*);
+    }
+  va_end (args);
+  
+  return concat;
+}
+
+gdouble
+g_strtod (const gchar *nptr,
+         gchar **endptr)
+{
+  gchar *fail_pos_1;
+  gchar *fail_pos_2;
+  gdouble val_1;
+  gdouble val_2 = 0;
+
+  g_return_val_if_fail (nptr != NULL, 0);
+
+  fail_pos_1 = NULL;
+  fail_pos_2 = NULL;
+
+  val_1 = strtod (nptr, &fail_pos_1);
+
+  if (fail_pos_1 && fail_pos_1[0] != 0)
+    {
+      gchar *old_locale;
+
+      old_locale = setlocale (LC_NUMERIC, "C");
+      val_2 = strtod (nptr, &fail_pos_2);
+      setlocale (LC_NUMERIC, old_locale);
+    }
+
+  if (!fail_pos_1 || fail_pos_1[0] == 0 || fail_pos_1 >= fail_pos_2)
+    {
+      if (endptr)
+       *endptr = fail_pos_1;
+      return val_1;
+    }
+  else
+    {
+      if (endptr)
+       *endptr = fail_pos_2;
+      return val_2;
+    }
+}
+
+gchar*
+g_strerror (gint errnum)
+{
+  static char msg[64];
+  
+#ifdef HAVE_STRERROR
+  return strerror (errnum);
+#elif NO_SYS_ERRLIST
+  switch (errnum)
+    {
+#ifdef E2BIG
+    case E2BIG: return "argument list too long";
+#endif
+#ifdef EACCES
+    case EACCES: return "permission denied";
+#endif
+#ifdef EADDRINUSE
+    case EADDRINUSE: return "address already in use";
+#endif
+#ifdef EADDRNOTAVAIL
+    case EADDRNOTAVAIL: return "can't assign requested address";
+#endif
+#ifdef EADV
+    case EADV: return "advertise error";
+#endif
+#ifdef EAFNOSUPPORT
+    case EAFNOSUPPORT: return "address family not supported by protocol family";
+#endif
+#ifdef EAGAIN
+    case EAGAIN: return "try again";
+#endif
+#ifdef EALIGN
+    case EALIGN: return "EALIGN";
+#endif
+#ifdef EALREADY
+    case EALREADY: return "operation already in progress";
+#endif
+#ifdef EBADE
+    case EBADE: return "bad exchange descriptor";
+#endif
+#ifdef EBADF
+    case EBADF: return "bad file number";
+#endif
+#ifdef EBADFD
+    case EBADFD: return "file descriptor in bad state";
+#endif
+#ifdef EBADMSG
+    case EBADMSG: return "not a data message";
+#endif
+#ifdef EBADR
+    case EBADR: return "bad request descriptor";
+#endif
+#ifdef EBADRPC
+    case EBADRPC: return "RPC structure is bad";
+#endif
+#ifdef EBADRQC
+    case EBADRQC: return "bad request code";
+#endif
+#ifdef EBADSLT
+    case EBADSLT: return "invalid slot";
+#endif
+#ifdef EBFONT
+    case EBFONT: return "bad font file format";
+#endif
+#ifdef EBUSY
+    case EBUSY: return "mount device busy";
+#endif
+#ifdef ECHILD
+    case ECHILD: return "no children";
+#endif
+#ifdef ECHRNG
+    case ECHRNG: return "channel number out of range";
+#endif
+#ifdef ECOMM
+    case ECOMM: return "communication error on send";
+#endif
+#ifdef ECONNABORTED
+    case ECONNABORTED: return "software caused connection abort";
+#endif
+#ifdef ECONNREFUSED
+    case ECONNREFUSED: return "connection refused";
+#endif
+#ifdef ECONNRESET
+    case ECONNRESET: return "connection reset by peer";
+#endif
+#if defined(EDEADLK) && (!defined(EWOULDBLOCK) || (EDEADLK != EWOULDBLOCK))
+    case EDEADLK: return "resource deadlock avoided";
+#endif
+#ifdef EDEADLOCK
+    case EDEADLOCK: return "resource deadlock avoided";
+#endif
+#ifdef EDESTADDRREQ
+    case EDESTADDRREQ: return "destination address required";
+#endif
+#ifdef EDIRTY
+    case EDIRTY: return "mounting a dirty fs w/o force";
+#endif
+#ifdef EDOM
+    case EDOM: return "math argument out of range";
+#endif
+#ifdef EDOTDOT
+    case EDOTDOT: return "cross mount point";
+#endif
+#ifdef EDQUOT
+    case EDQUOT: return "disk quota exceeded";
+#endif
+#ifdef EDUPPKG
+    case EDUPPKG: return "duplicate package name";
+#endif
+#ifdef EEXIST
+    case EEXIST: return "file already exists";
+#endif
+#ifdef EFAULT
+    case EFAULT: return "bad address in system call argument";
+#endif
+#ifdef EFBIG
+    case EFBIG: return "file too large";
+#endif
+#ifdef EHOSTDOWN
+    case EHOSTDOWN: return "host is down";
+#endif
+#ifdef EHOSTUNREACH
+    case EHOSTUNREACH: return "host is unreachable";
+#endif
+#ifdef EIDRM
+    case EIDRM: return "identifier removed";
+#endif
+#ifdef EINIT
+    case EINIT: return "initialization error";
+#endif
+#ifdef EINPROGRESS
+    case EINPROGRESS: return "operation now in progress";
+#endif
+#ifdef EINTR
+    case EINTR: return "interrupted system call";
+#endif
+#ifdef EINVAL
+    case EINVAL: return "invalid argument";
+#endif
+#ifdef EIO
+    case EIO: return "I/O error";
+#endif
+#ifdef EISCONN
+    case EISCONN: return "socket is already connected";
+#endif
+#ifdef EISDIR
+    case EISDIR: return "illegal operation on a directory";
+#endif
+#ifdef EISNAME
+    case EISNAM: return "is a name file";
+#endif
+#ifdef ELBIN
+    case ELBIN: return "ELBIN";
+#endif
+#ifdef EL2HLT
+    case EL2HLT: return "level 2 halted";
+#endif
+#ifdef EL2NSYNC
+    case EL2NSYNC: return "level 2 not synchronized";
+#endif
+#ifdef EL3HLT
+    case EL3HLT: return "level 3 halted";
+#endif
+#ifdef EL3RST
+    case EL3RST: return "level 3 reset";
+#endif
+#ifdef ELIBACC
+    case ELIBACC: return "can not access a needed shared library";
+#endif
+#ifdef ELIBBAD
+    case ELIBBAD: return "accessing a corrupted shared library";
+#endif
+#ifdef ELIBEXEC
+    case ELIBEXEC: return "can not exec a shared library directly";
+#endif
+#ifdef ELIBMAX
+    case ELIBMAX: return "attempting to link in more shared libraries than system limit";
+#endif
+#ifdef ELIBSCN
+    case ELIBSCN: return ".lib section in a.out corrupted";
+#endif
+#ifdef ELNRNG
+    case ELNRNG: return "link number out of range";
+#endif
+#ifdef ELOOP
+    case ELOOP: return "too many levels of symbolic links";
+#endif
+#ifdef EMFILE
+    case EMFILE: return "too many open files";
+#endif
+#ifdef EMLINK
+    case EMLINK: return "too many links";
+#endif
+#ifdef EMSGSIZE
+    case EMSGSIZE: return "message too long";
+#endif
+#ifdef EMULTIHOP
+    case EMULTIHOP: return "multihop attempted";
+#endif
+#ifdef ENAMETOOLONG
+    case ENAMETOOLONG: return "file name too long";
+#endif
+#ifdef ENAVAIL
+    case ENAVAIL: return "not available";
+#endif
+#ifdef ENET
+    case ENET: return "ENET";
+#endif
+#ifdef ENETDOWN
+    case ENETDOWN: return "network is down";
+#endif
+#ifdef ENETRESET
+    case ENETRESET: return "network dropped connection on reset";
+#endif
+#ifdef ENETUNREACH
+    case ENETUNREACH: return "network is unreachable";
+#endif
+#ifdef ENFILE
+    case ENFILE: return "file table overflow";
+#endif
+#ifdef ENOANO
+    case ENOANO: return "anode table overflow";
+#endif
+#if defined(ENOBUFS) && (!defined(ENOSR) || (ENOBUFS != ENOSR))
+    case ENOBUFS: return "no buffer space available";
+#endif
+#ifdef ENOCSI
+    case ENOCSI: return "no CSI structure available";
+#endif
+#ifdef ENODATA
+    case ENODATA: return "no data available";
+#endif
+#ifdef ENODEV
+    case ENODEV: return "no such device";
+#endif
+#ifdef ENOENT
+    case ENOENT: return "no such file or directory";
+#endif
+#ifdef ENOEXEC
+    case ENOEXEC: return "exec format error";
+#endif
+#ifdef ENOLCK
+    case ENOLCK: return "no locks available";
+#endif
+#ifdef ENOLINK
+    case ENOLINK: return "link has be severed";
+#endif
+#ifdef ENOMEM
+    case ENOMEM: return "not enough memory";
+#endif
+#ifdef ENOMSG
+    case ENOMSG: return "no message of desired type";
+#endif
+#ifdef ENONET
+    case ENONET: return "machine is not on the network";
+#endif
+#ifdef ENOPKG
+    case ENOPKG: return "package not installed";
+#endif
+#ifdef ENOPROTOOPT
+    case ENOPROTOOPT: return "bad proocol option";
+#endif
+#ifdef ENOSPC
+    case ENOSPC: return "no space left on device";
+#endif
+#ifdef ENOSR
+    case ENOSR: return "out of stream resources";
+#endif
+#ifdef ENOSTR
+    case ENOSTR: return "not a stream device";
+#endif
+#ifdef ENOSYM
+    case ENOSYM: return "unresolved symbol name";
+#endif
+#ifdef ENOSYS
+    case ENOSYS: return "function not implemented";
+#endif
+#ifdef ENOTBLK
+    case ENOTBLK: return "block device required";
+#endif
+#ifdef ENOTCONN
+    case ENOTCONN: return "socket is not connected";
+#endif
+#ifdef ENOTDIR
+    case ENOTDIR: return "not a directory";
+#endif
+#ifdef ENOTEMPTY
+    case ENOTEMPTY: return "directory not empty";
+#endif
+#ifdef ENOTNAM
+    case ENOTNAM: return "not a name file";
+#endif
+#ifdef ENOTSOCK
+    case ENOTSOCK: return "socket operation on non-socket";
+#endif
+#ifdef ENOTTY
+    case ENOTTY: return "inappropriate device for ioctl";
+#endif
+#ifdef ENOTUNIQ
+    case ENOTUNIQ: return "name not unique on network";
+#endif
+#ifdef ENXIO
+    case ENXIO: return "no such device or address";
+#endif
+#ifdef EOPNOTSUPP
+    case EOPNOTSUPP: return "operation not supported on socket";
+#endif
+#ifdef EPERM
+    case EPERM: return "not owner";
+#endif
+#ifdef EPFNOSUPPORT
+    case EPFNOSUPPORT: return "protocol family not supported";
+#endif
+#ifdef EPIPE
+    case EPIPE: return "broken pipe";
+#endif
+#ifdef EPROCLIM
+    case EPROCLIM: return "too many processes";
+#endif
+#ifdef EPROCUNAVAIL
+    case EPROCUNAVAIL: return "bad procedure for program";
+#endif
+#ifdef EPROGMISMATCH
+    case EPROGMISMATCH: return "program version wrong";
+#endif
+#ifdef EPROGUNAVAIL
+    case EPROGUNAVAIL: return "RPC program not available";
+#endif
+#ifdef EPROTO
+    case EPROTO: return "protocol error";
+#endif
+#ifdef EPROTONOSUPPORT
+    case EPROTONOSUPPORT: return "protocol not suppored";
+#endif
+#ifdef EPROTOTYPE
+    case EPROTOTYPE: return "protocol wrong type for socket";
+#endif
+#ifdef ERANGE
+    case ERANGE: return "math result unrepresentable";
+#endif
+#if defined(EREFUSED) && (!defined(ECONNREFUSED) || (EREFUSED != ECONNREFUSED))
+    case EREFUSED: return "EREFUSED";
+#endif
+#ifdef EREMCHG
+    case EREMCHG: return "remote address changed";
+#endif
+#ifdef EREMDEV
+    case EREMDEV: return "remote device";
+#endif
+#ifdef EREMOTE
+    case EREMOTE: return "pathname hit remote file system";
+#endif
+#ifdef EREMOTEIO
+    case EREMOTEIO: return "remote i/o error";
+#endif
+#ifdef EREMOTERELEASE
+    case EREMOTERELEASE: return "EREMOTERELEASE";
+#endif
+#ifdef EROFS
+    case EROFS: return "read-only file system";
+#endif
+#ifdef ERPCMISMATCH
+    case ERPCMISMATCH: return "RPC version is wrong";
+#endif
+#ifdef ERREMOTE
+    case ERREMOTE: return "object is remote";
+#endif
+#ifdef ESHUTDOWN
+    case ESHUTDOWN: return "can't send afer socket shutdown";
+#endif
+#ifdef ESOCKTNOSUPPORT
+    case ESOCKTNOSUPPORT: return "socket type not supported";
+#endif
+#ifdef ESPIPE
+    case ESPIPE: return "invalid seek";
+#endif
+#ifdef ESRCH
+    case ESRCH: return "no such process";
+#endif
+#ifdef ESRMNT
+    case ESRMNT: return "srmount error";
+#endif
+#ifdef ESTALE
+    case ESTALE: return "stale remote file handle";
+#endif
+#ifdef ESUCCESS
+    case ESUCCESS: return "Error 0";
+#endif
+#ifdef ETIME
+    case ETIME: return "timer expired";
+#endif
+#ifdef ETIMEDOUT
+    case ETIMEDOUT: return "connection timed out";
+#endif
+#ifdef ETOOMANYREFS
+    case ETOOMANYREFS: return "too many references: can't splice";
+#endif
+#ifdef ETXTBSY
+    case ETXTBSY: return "text file or pseudo-device busy";
+#endif
+#ifdef EUCLEAN
+    case EUCLEAN: return "structure needs cleaning";
+#endif
+#ifdef EUNATCH
+    case EUNATCH: return "protocol driver not attached";
+#endif
+#ifdef EUSERS
+    case EUSERS: return "too many users";
+#endif
+#ifdef EVERSION
+    case EVERSION: return "version mismatch";
+#endif
+#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
+    case EWOULDBLOCK: return "operation would block";
+#endif
+#ifdef EXDEV
+    case EXDEV: return "cross-domain link";
+#endif
+#ifdef EXFULL
+    case EXFULL: return "message tables full";
+#endif
+    }
+#else /* NO_SYS_ERRLIST */
+  extern int sys_nerr;
+  extern char *sys_errlist[];
+
+  if ((errnum > 0) && (errnum <= sys_nerr))
+    return sys_errlist [errnum];
+#endif /* NO_SYS_ERRLIST */
+
+  sprintf (msg, "unknown error (%d)", errnum);
+  return msg;
+}
+
+gchar*
+g_strsignal (gint signum)
+{
+  static char msg[64];
+
+#ifdef HAVE_STRSIGNAL
+  extern char *strsignal (int sig);
+  return strsignal (signum);
+#elif NO_SYS_SIGLIST
+  switch (signum)
+    {
+#ifdef SIGHUP
+    case SIGHUP: return "Hangup";
+#endif
+#ifdef SIGINT
+    case SIGINT: return "Interrupt";
+#endif
+#ifdef SIGQUIT
+    case SIGQUIT: return "Quit";
+#endif
+#ifdef SIGILL
+    case SIGILL: return "Illegal instruction";
+#endif
+#ifdef SIGTRAP
+    case SIGTRAP: return "Trace/breakpoint trap";
+#endif
+#ifdef SIGABRT
+    case SIGABRT: return "IOT trap/Abort";
+#endif
+#ifdef SIGBUS
+    case SIGBUS: return "Bus error";
+#endif
+#ifdef SIGFPE
+    case SIGFPE: return "Floating point exception";
+#endif
+#ifdef SIGKILL
+    case SIGKILL: return "Killed";
+#endif
+#ifdef SIGUSR1
+    case SIGUSR1: return "User defined signal 1";
+#endif
+#ifdef SIGSEGV
+    case SIGSEGV: return "Segmentation fault";
+#endif
+#ifdef SIGUSR2
+    case SIGUSR2: return "User defined signal 2";
+#endif
+#ifdef SIGPIPE
+    case SIGPIPE: return "Broken pipe";
+#endif
+#ifdef SIGALRM
+    case SIGALRM: return "Alarm clock";
+#endif
+#ifdef SIGTERM
+    case SIGTERM: return "Terminated";
+#endif
+#ifdef SIGSTKFLT
+    case SIGSTKFLT: return "Stack fault";
+#endif
+#ifdef SIGCHLD
+    case SIGCHLD: return "Child exited";
+#endif
+#ifdef SIGCONT
+    case SIGCONT: return "Continued";
+#endif
+#ifdef SIGSTOP
+    case SIGSTOP: return "Stopped (signal)";
+#endif
+#ifdef SIGTSTP
+    case SIGTSTP: return "Stopped";
+#endif
+#ifdef SIGTTIN
+    case SIGTTIN: return "Stopped (tty input)";
+#endif
+#ifdef SIGTTOU
+    case SIGTTOU: return "Stopped (tty output)";
+#endif
+#ifdef SIGURG
+    case SIGURG: return "Urgent condition";
+#endif
+#ifdef SIGXCPU
+    case SIGXCPU: return "CPU time limit exceeded";
+#endif
+#ifdef SIGXFSZ
+    case SIGXFSZ: return "File size limit exceeded";
+#endif
+#ifdef SIGVTALRM
+    case SIGVTALRM: return "Virtual time alarm";
+#endif
+#ifdef SIGPROF
+    case SIGPROF: return "Profile signal";
+#endif
+#ifdef SIGWINCH
+    case SIGWINCH: return "Window size changed";
+#endif
+#ifdef SIGIO
+    case SIGIO: return "Possible I/O";
+#endif
+#ifdef SIGPWR
+    case SIGPWR: return "Power failure";
+#endif
+#ifdef SIGUNUSED
+    case SIGUNUSED: return "Unused signal";
+#endif
+    }
+#else /* NO_SYS_SIGLIST */
+  extern char *sys_siglist[];
+  return sys_siglist [signum];
+#endif /* NO_SYS_SIGLIST */
+
+  sprintf (msg, "unknown signal (%d)", signum);
+  return msg;
+}
+
+gint
+g_snprintf (gchar       *str,
+           gulong       n,
+           gchar const *fmt,
+           ...)
+{
+#ifdef HAVE_VSNPRINTF
+  va_list args;
+  gint retval;
+  
+  va_start (args, fmt);
+  retval = vsnprintf (str, n, fmt, args);
+  va_end (args);
+
+  return retval;
+
+#else
+  gchar *printed;
+  va_list args, args2;
+
+  va_start (args, fmt);
+  va_start (args2, fmt);
+  
+  printed = g_vsprintf (fmt, &args, &args2);
+  strncpy (str, printed, n);
+  str[n-1] = '\0';
+  
+  va_end (args2);
+  va_end (args);
+
+  return strlen (str);
+
+#endif
+}
+
+void
+g_strdown (gchar  *string)
+{
+  register gchar *s;
+
+  g_return_if_fail (string != NULL);
+
+  s = string;
+
+  while (*s)
+    {
+      *s = tolower (*s);
+      s++;
+    }
+}
+
+void
+g_strup (gchar  *string)
+{
+  register gchar *s;
+
+  g_return_if_fail (string != NULL);
+
+  s = string;
+
+  while (*s)
+    {
+      *s = toupper (*s);
+      s++;
+    }
+}
+
+void
+g_strreverse (gchar       *string)
+{
+  g_return_if_fail (string != NULL);
+
+  if (*string)
+    {
+      register gchar *h, *t;
+
+      h = string;
+      t = string + strlen (string) - 1;
+      
+      while (h < t)
+       {
+         register gchar c;
+         
+         c = *h;
+         *h = *t;
+         h++;
+         *t = c;
+         t--;
+       }
+    }
+}
+
+gint
+g_strcasecmp (const gchar *s1,
+             const gchar *s2)
+{
+#ifdef HAVE_STRCASECMP
+  return strcasecmp (s1, s2);
+#else
+  gint c1, c2;
+
+  while (*s1 && *s2)
+    {
+      /* According to A. Cox, some platforms have islower's that
+       * don't work right on non-uppercase
+       */
+      c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1;
+      c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2;
+      if (c1 != c2)
+        return (c1 - c2);
+      s1++; s2++;
+    }
+
+  return (((gint)(guchar) *s1) - ((gint)(guchar) *s2));
+#endif
+}
+
+void
+g_strdelimit (gchar       *string,
+             const gchar *delimiters,
+             gchar        new_delim)
+{
+  register gchar *c;
+
+  g_return_if_fail (string != NULL);
+
+  if (!delimiters)
+    delimiters = G_STR_DELIMITERS;
+
+  for (c = string; *c; c++)
+    {
+      if (strchr (delimiters, *c))
+       *c = new_delim;
+    }
+}
+
+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;
+}
+
+guint
+g_direct_hash(gconstpointer key)
+{
+  return GPOINTER_TO_UINT (key);
+}
+
diff --git a/install-sh b/install-sh
new file mode 100755 (executable)
index 0000000..89fc9b0
--- /dev/null
@@ -0,0 +1,238 @@
+#! /bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+tranformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+       -c) instcmd="$cpprog"
+           shift
+           continue;;
+
+       -d) dir_arg=true
+           shift
+           continue;;
+
+       -m) chmodcmd="$chmodprog $2"
+           shift
+           shift
+           continue;;
+
+       -o) chowncmd="$chownprog $2"
+           shift
+           shift
+           continue;;
+
+       -g) chgrpcmd="$chgrpprog $2"
+           shift
+           shift
+           continue;;
+
+       -s) stripcmd="$stripprog"
+           shift
+           continue;;
+
+       -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+           shift
+           continue;;
+
+       -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+           shift
+           continue;;
+
+       *)  if [ x"$src" = x ]
+           then
+               src=$1
+           else
+               # this colon is to work around a 386BSD /bin/sh bug
+               :
+               dst=$1
+           fi
+           shift
+           continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+       echo "install:  no input file specified"
+       exit 1
+else
+       true
+fi
+
+if [ x"$dir_arg" != x ]; then
+       dst=$src
+       src=""
+       
+       if [ -d $dst ]; then
+               instcmd=:
+       else
+               instcmd=mkdir
+       fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+       if [ -f $src -o -d $src ]
+       then
+               true
+       else
+               echo "install:  $src does not exist"
+               exit 1
+       fi
+       
+       if [ x"$dst" = x ]
+       then
+               echo "install:  no destination specified"
+               exit 1
+       else
+               true
+       fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+       if [ -d $dst ]
+       then
+               dst="$dst"/`basename $src`
+       else
+               true
+       fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='   
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+       pathcomp="${pathcomp}${1}"
+       shift
+
+       if [ ! -d "${pathcomp}" ] ;
+        then
+               $mkdirprog "${pathcomp}"
+       else
+               true
+       fi
+
+       pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+       $doit $instcmd $dst &&
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+       if [ x"$transformarg" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               dstfile=`basename $dst $transformbasename | 
+                       sed $transformarg`$transformbasename
+       fi
+
+# don't allow the sed command to completely eliminate the filename
+
+       if [ x"$dstfile" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               true
+       fi
+
+# Make a temp file name in the proper directory.
+
+       dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+       $doit $instcmd $src $dsttmp &&
+
+       trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+       $doit $rmcmd -f $dstdir/$dstfile &&
+       $doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
diff --git a/ltconfig b/ltconfig
new file mode 100755 (executable)
index 0000000..878a7c8
--- /dev/null
+++ b/ltconfig
@@ -0,0 +1,1532 @@
+#! /bin/sh
+
+# ltconfig - Create a system-specific libtool.
+# Copyright (C) 1996-1998 Free Software Foundation, Inc.
+# Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A lot of this script is taken from autoconf-2.10.
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi
+
+echo=echo
+if test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then :
+else
+  # The Solaris, AIX, and Digital Unix default echo programs unquote
+  # backslashes.  This makes it impossible to quote backslashes using
+  #   echo "$something" | sed 's/\\/\\\\/g'
+  #
+  # So, first we look for a working echo in the user's PATH.
+  IFS="${IFS=  }"; save_ifs="$IFS"; IFS="${IFS}:"
+  for dir in $PATH /usr/ucb; do
+    if test -f $dir/echo && test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t'; then
+      echo="$dir/echo"
+      break
+    fi
+  done
+  IFS="$save_ifs"
+
+  if test "X$echo" = Xecho; then
+    # We didn't find a better echo, so look for alternatives.
+    if test "X`(print -r '\t') 2>/dev/null`" = 'X\t'; then
+      # This shell has a builtin print -r that does the trick.
+      echo='print -r'
+#
+# The following is from libtool-1.2a, won't work with this patched
+# libtool-1.2
+#
+#    elif test -f /bin/ksh && test "X$CONFIG_SHELL" != X/bin/ksh; then
+#      # If we have ksh, try running ltconfig again with it.
+#      CONFIG_SHELL=/bin/ksh
+#      export CONFIG_SHELL
+#      exec "$CONFIG_SHELL" "$0" --no-reexec ${1+"$@"}
+    else
+      # Try using printf.
+      echo='printf %s\n'
+      if test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then :
+      else
+        # Oops.  We lost completely, so just stick with echo.
+        echo=echo
+      fi
+    fi
+  fi
+fi
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
+
+# The name of this program.
+progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'`
+
+# Constants:
+PROGRAM=ltconfig
+PACKAGE=libtool
+VERSION=1.2
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.c 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.c $LIBS 1>&5'
+rm="rm -f"
+
+help="Try \`$progname --help' for more information."
+
+# Global variables:
+can_build_shared=yes
+enable_shared=yes
+# All known linkers require a `.a' archive for static linking.
+enable_static=yes
+ltmain=
+silent=
+srcdir=
+ac_config_guess=
+ac_config_sub=
+host=
+nonopt=
+verify_host=yes
+with_gcc=no
+with_gnu_ld=no
+
+old_AR="$AR"
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+old_CPPFLAGS="$CPPFLAGS"
+old_LD="$LD"
+old_LN_S="$LN_S"
+old_NM="$NM"
+old_RANLIB="$RANLIB"
+
+# Parse the command line options.
+args=
+prev=
+for option
+do
+  case "$option" in
+  -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    eval "$prev=\$option"
+    prev=
+    continue
+  fi
+
+  case "$option" in
+  --help) cat <<EOM
+Usage: $progname [OPTION]... LTMAIN [HOST]
+
+Generate a system-specific libtool script.
+
+    --disable-shared       do not build shared libraries
+    --disable-static       do not build static libraries
+    --help                 display this help and exit
+    --no-verify            do not verify that HOST is a valid host type
+    --quiet                same as \`--silent'
+    --silent               do not print informational messages
+    --srcdir=DIR           find \`config.guess' in DIR
+    --version              output version information and exit
+    --with-gcc             assume that the GNU C compiler will be used
+    --with-gnu-ld          assume that the C compiler uses the GNU linker
+
+LTMAIN is the \`ltmain.sh' shell script fragment that provides basic libtool
+functionality.
+
+HOST is the canonical host system name [default=guessed].
+EOM
+  exit 0
+  ;;
+
+  --disable-shared) enable_shared=no ;;
+
+  --disable-static) enable_static=no ;;
+
+  --quiet | --silent) silent=yes ;;
+
+  --srcdir) prev=srcdir ;;
+  --srcdir=*) srcdir="$optarg" ;;
+
+  --no-verify) verify_host=no ;;
+
+  --version) echo "$PROGRAM (GNU $PACKAGE) $VERSION"; exit 0 ;;
+
+  --with-gcc) with_gcc=yes ;;
+  --with-gnu-ld) with_gnu_ld=yes ;;
+
+  -*)
+    echo "$progname: unrecognized option \`$option'" 1>&2
+    echo "$help" 1>&2
+    exit 1
+    ;;
+
+  *)
+    if test -z "$ltmain"; then
+      ltmain="$option"
+    elif test -z "$host"; then
+# This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1
+#      if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then
+#        echo "$progname: warning \`$option' is not a valid host type" 1>&2
+#      fi
+      host="$option"
+    else
+      echo "$progname: too many arguments" 1>&2
+      echo "$help" 1>&2
+      exit 1
+    fi ;;
+  esac
+done
+
+if test -z "$ltmain"; then
+  echo "$progname: you must specify a LTMAIN file" 1>&2
+  echo "$help" 1>&2
+  exit 1
+fi
+
+if test -f "$ltmain"; then :
+else
+  echo "$progname: \`$ltmain' does not exist" 1>&2
+  echo "$help" 1>&2
+  exit 1
+fi
+
+# Quote any args containing shell metacharacters.
+ltconfig_args=
+for arg
+do
+  case "$arg" in
+  *" "*|*"     "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ltconfig_args="$ltconfig_args '$arg'" ;;
+  *) ltconfig_args="$ltconfig_args $arg" ;;
+  esac
+done
+
+# A relevant subset of AC_INIT.
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 5 compiler messages saved in config.log
+# 6 checking for... messages and results
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>>./config.log
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='       '
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+if test -z "$srcdir"; then
+  # Assume the source directory is the same one as the path to ltmain.sh.
+  srcdir=`$echo "$ltmain" | $Xsed -e 's%/[^/]*$%%'`
+  test "$srcdir" = "$ltmain" && srcdir=.
+fi
+
+trap "$rm conftest*; exit 1" 1 2 15
+if test "$verify_host" = yes; then
+  # Check for config.guess and config.sub.
+  ac_aux_dir=
+  for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+    if test -f $ac_dir/config.guess; then
+      ac_aux_dir=$ac_dir
+      break
+    fi
+  done
+  if test -z "$ac_aux_dir"; then
+    echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2
+    echo "$help" 1>&2
+    exit 1
+  fi
+  ac_config_guess=$ac_aux_dir/config.guess
+  ac_config_sub=$ac_aux_dir/config.sub
+
+  # Make sure we can run config.sub.
+  if $ac_config_sub sun4 >/dev/null 2>&1; then :
+  else
+    echo "$progname: cannot run $ac_config_sub" 1>&2
+    echo "$help" 1>&2
+    exit 1
+  fi
+
+  echo $ac_n "checking host system type""... $ac_c" 1>&6
+
+  host_alias=$host
+  case "$host_alias" in
+  "")
+    if host_alias=`$ac_config_guess`; then :
+    else
+      echo "$progname: cannot guess host type; you must specify one" 1>&2
+      echo "$help" 1>&2
+      exit 1
+    fi ;;
+  esac
+  host=`$ac_config_sub $host_alias`
+  echo "$ac_t$host" 1>&6
+
+  # Make sure the host verified.
+  test -z "$host" && exit 1
+
+elif test -z "$host"; then
+  echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2
+  echo "$help" 1>&2
+  exit 1
+else
+  host_alias=$host
+fi
+
+# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
+case "$host_os" in
+linux-gnu*) ;;
+linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+case "$host_os" in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "${COLLECT_NAMES+set}" != set; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR cru $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+# Set a sane default for `AR'.
+test -z "$AR" && AR=ar
+
+# If RANLIB is not set, then run the test.
+if test "${RANLIB+set}" != "set"; then
+  result=no
+
+  echo $ac_n "checking for ranlib... $ac_c" 1>&6
+  IFS="${IFS=  }"; save_ifs="$IFS"; IFS="${IFS}:"
+  for dir in $PATH; do
+    test -z "$dir" && dir=.
+    if test -f $dir/ranlib; then
+      RANLIB="ranlib"
+      result="ranlib"
+      break
+    fi
+  done
+  IFS="$save_ifs"
+
+  echo "$ac_t$result" 1>&6
+fi
+
+if test -n "$RANLIB"; then
+  old_archive_cmds="$old_archive_cmds;\$RANLIB \$oldlib"
+  old_postinstall_cmds="\$RANLIB \$oldlib;$old_postinstall_cmds"
+fi
+
+# Check to see if we are using GCC.
+if test "$with_gcc" != yes || test -z "$CC"; then
+  # If CC is not set, then try to find GCC or a usable CC.
+  if test -z "$CC"; then
+    echo $ac_n "checking for gcc... $ac_c" 1>&6
+    IFS="${IFS=        }"; save_ifs="$IFS"; IFS="${IFS}:"
+    for dir in $PATH; do
+      IFS="$save_ifs"
+      test -z "$dir" && dir=.
+      if test -f $dir/gcc; then
+       CC="gcc"
+       break
+      fi
+    done
+    IFS="$save_ifs"
+
+    if test -n "$CC"; then
+      echo "$ac_t$CC" 1>&6
+    else
+      echo "$ac_t"no 1>&6
+    fi
+  fi
+
+  # Not "gcc", so try "cc", rejecting "/usr/ucb/cc".
+  if test -z "$CC"; then
+    echo $ac_n "checking for cc... $ac_c" 1>&6
+    IFS="${IFS=        }"; save_ifs="$IFS"; IFS="${IFS}:"
+    cc_rejected=no
+    for dir in $PATH; do
+      test -z "$dir" && dir=.
+      if test -f $dir/cc; then
+       if test "$dir/cc" = "/usr/ucb/cc"; then
+         cc_rejected=yes
+         continue
+       fi
+       CC="cc"
+       break
+      fi
+    done
+    IFS="$save_ifs"
+    if test $cc_rejected = yes; then
+      # We found a bogon in the path, so make sure we never use it.
+      set dummy $CC
+      shift
+      if test $# -gt 0; then
+       # We chose a different compiler from the bogus one.
+       # However, it has the same name, so the bogon will be chosen
+       # first if we set CC to just the name; use the full file name.
+       shift
+       set dummy "$dir/cc" "$@"
+       shift
+       CC="$@"
+      fi
+    fi
+
+    if test -n "$CC"; then
+      echo "$ac_t$CC" 1>&6
+    else
+      echo "$ac_t"no 1>&6
+    fi
+
+    if test -z "$CC"; then
+      echo "$progname: error: no acceptable cc found in \$PATH" 1>&2
+      exit 1
+    fi
+  fi
+
+  # Now see if the compiler is really GCC.
+  with_gcc=no
+  echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6
+  echo "$progname:444: checking whether we are using GNU C" >&5
+
+  $rm conftest.c
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+  if { ac_try='${CC-cc} -E conftest.c'; { (eval echo $progname:452: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+    with_gcc=yes
+  fi
+  $rm conftest.c
+  echo "$ac_t$with_gcc" 1>&6
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="$2"
+
+echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6
+pic_flag=
+special_shlib_compile_flags=
+wl=
+link_static_flag=
+no_builtin_flag=
+
+if test "$with_gcc" = yes; then
+  wl='-Wl,'
+  link_static_flag='-static'
+  no_builtin_flag=' -fno-builtin'
+
+  case "$host_os" in
+  aix3* | aix4* | irix5* | irix6* | osf3* | osf4*)
+    # PIC is the default for these OSes.
+    ;;
+  os2*)
+    # We can build DLLs from non-PIC.
+    ;;
+  amigaos*)
+    # FIXME: we need at least 68020 code to build shared libraries, but
+    # adding the `-m68020' flag to GCC prevents building anything better,
+    # like `-m68040'.
+    pic_flag='-m68020 -resident32 -malways-restore-a4'
+    ;;
+  *)
+    pic_flag='-fPIC'
+    ;;
+  esac
+else
+  # PORTME Check for PIC flags for the system compiler.
+  case "$host_os" in
+  aix3* | aix4*)
+    # All AIX code is PIC.
+    link_static_flag='-bnso -bI:/lib/syscalls.exp'
+    ;;
+
+  hpux9* | hpux10*)
+    # Is there a better link_static_flag that works with the bundled CC?
+    wl='-Wl,'
+    link_static_flag="${wl}-a ${wl}archive"
+    pic_flag='+Z'
+    ;;
+
+  irix5* | irix6*)
+    wl='-Wl,'
+    link_static_flag='-non_shared'
+    # PIC (with -KPIC) is the default.
+    ;;
+
+  os2*)
+    # We can build DLLs from non-PIC.
+    ;;
+
+  osf3* | osf4*)
+    # All OSF/1 code is PIC.
+    wl='-Wl,'
+    link_static_flag='-non_shared'
+    ;;
+
+  sco3.2v5*)
+    pic_flag='-Kpic'
+    link_static_flag='-dn'
+    special_shlib_compile_flags='-belf'
+    ;;
+
+  solaris2*)
+    pic_flag='-KPIC'
+    link_static_flag='-Bstatic'
+    wl='-Wl,'
+    ;;
+
+  sunos4*)
+    pic_flag='-PIC'
+    link_static_flag='-Bstatic'
+    wl='-Qoption ld '
+    ;;
+
+  sysv4.2uw2*)
+    pic_flag='-KPIC'
+    link_static_flag='-Bstatic'
+    wl='-Wl,'
+    ;;
+
+  uts4*)
+    pic_flag='-pic'
+    link_static_flag='-Bstatic'
+    ;;
+
+  *)
+    can_build_shared=no
+    ;;
+  esac
+fi
+
+if test -n "$pic_flag"; then
+  echo "$ac_t$pic_flag" 1>&6
+
+  # Check to make sure the pic_flag actually works.
+  echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6
+  $rm conftest*
+  echo > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS $pic_flag -DPIC"
+  echo "$progname:567: checking if $compiler PIC flag $pic_flag works" >&5
+  if { (eval echo $progname:568: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; then
+    # Append any warnings to the config.log.
+    cat conftest.err 1>&5
+
+    # On HP-UX, both CC and GCC only warn that PIC is supported... then they
+    # create non-PIC objects.  So, if there were any warnings, we assume that
+    # PIC is not supported.
+    if test -s conftest.err; then
+      echo "$ac_t"no 1>&6
+      can_build_shared=no
+      pic_flag=
+    else
+      echo "$ac_t"yes 1>&6
+      pic_flag=" $pic_flag"
+    fi
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    can_build_shared=no
+    pic_flag=
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+else
+  echo "$ac_t"none 1>&6
+fi
+
+# Check for any special shared library compilation flags.
+if test -n "$special_shlib_compile_flags"; then
+  echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2
+  if echo "$old_CC $old_CFLAGS " | egrep -e "[         ]$special_shlib_compile_flags[  ]" >/dev/null; then :
+  else
+    echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2
+    can_build_shared=no
+  fi
+fi
+
+echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6
+$rm conftest*
+echo 'main(){return(0);}' > conftest.c
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS $link_static_flag"
+echo "$progname:611: checking if $compiler static flag $link_static_flag works" >&5
+if { (eval echo $progname:612: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  echo "$ac_t$link_static_flag" 1>&6
+else
+  echo "$ac_t"none 1>&6
+  link_static_flag=
+fi
+LDFLAGS="$save_LDFLAGS"
+$rm conftest*
+
+if test -z "$LN_S"; then
+  # Check to see if we can use ln -s, or we need hard links.
+  echo $ac_n "checking whether ln -s works... $ac_c" 1>&6
+  $rm conftestdata
+  if ln -s X conftestdata 2>/dev/null; then
+    $rm conftestdata
+    LN_S="ln -s"
+  else
+    LN_S=ln
+  fi
+  if test "$LN_S" = "ln -s"; then
+    echo "$ac_t"yes 1>&6
+  else
+    echo "$ac_t"no 1>&6
+  fi
+fi
+
+# Make sure LD is an absolute path.
+if test -z "$LD"; then
+  ac_prog=ld
+  if test "$with_gcc" = yes; then
+    # Check if gcc -print-prog-name=ld gives a path.
+    echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6
+    echo "$progname:644: checking for ld used by GCC" >&5
+    ac_prog=`($CC -print-prog-name=ld) 2>&5`
+    case "$ac_prog" in
+    # Accept absolute paths.
+    /* | [A-Za-z]:\\*)
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+    "")
+      # If it fails, then pretend we are not using GCC.
+      ac_prog=ld
+      ;;
+    *)
+      # If it is relative, then search for the first ld in PATH.
+      with_gnu_ld=unknown
+      ;;
+    esac
+  elif test "$with_gnu_ld" = yes; then
+    echo $ac_n "checking for GNU ld... $ac_c" 1>&6
+    echo "$progname:662: checking for GNU ld" >&5
+  else
+    echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+    echo "$progname:665: checking for non-GNU ld" >&5
+  fi
+
+  if test -z "$LD"; then
+    IFS="${IFS=        }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+    for ac_dir in $PATH; do
+      test -z "$ac_dir" && ac_dir=.
+      if test -f "$ac_dir/$ac_prog"; then
+       LD="$ac_dir/$ac_prog"
+       # Check to see if the program is GNU ld.  I'd rather use --version,
+       # but apparently some GNU ld's only accept -v.
+       # Break only if it was the GNU/non-GNU ld that we prefer.
+       if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+         test "$with_gnu_ld" != no && break
+       else
+         test "$with_gnu_ld" != yes && break
+       fi
+      fi
+    done
+    IFS="$ac_save_ifs"
+  fi
+
+  if test -n "$LD"; then
+    echo "$ac_t$LD" 1>&6
+  else
+    echo "$ac_t"no 1>&6
+  fi
+
+  if test -z "$LD"; then
+    echo "$progname: error: no acceptable ld found in \$PATH" 1>&2
+    exit 1
+  fi
+fi
+
+# Check to see if it really is or is not GNU ld.
+echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6
+# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+echo "$ac_t$with_gnu_ld" 1>&6
+
+# See if the linker supports building shared libraries.
+echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6
+
+allow_undefined_flag=
+no_undefined_flag=
+archive_cmds=
+old_archive_from_new_cmds=
+export_dynamic_flag_spec=
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_shlibpath_var=unsupported
+runpath_var=
+
+case "$host_os" in
+amigaos* | sunos4*)
+  # On these operating systems, we should treat GNU ld like the system ld.
+  gnu_ld_acts_native=yes
+  ;;
+*)
+  gnu_ld_acts_native=no
+  ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes && test "$gnu_ld_acts_native" != yes; then
+
+  # See if GNU ld supports shared libraries.
+  if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+    archive_cmds='$CC -shared ${wl}-soname $wl$soname -o $lib$libobjs'
+    runpath_var=LD_RUN_PATH
+    ld_shlibs=yes
+  else
+    ld_shlibs=no
+  fi
+
+  if test "$ld_shlibs" = yes; then
+    hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
+  fi
+else
+  # PORTME fill in a description of your system's linker (not GNU ld)
+  case "$host_os" in
+  aix3*)
+    allow_undefined_flag=unsupported
+    archive_cmds='$NM$libobjs | $global_symbol_pipe | sed '\''s/.* //'\'' > $lib.exp;$LD -o $objdir/$soname$libobjs -bE:$lib.exp -T512 -H512 -bM:SRE;$AR cru $lib $objdir/$soname'
+    # Note: this linker hardcodes the directories in LIBPATH if there
+    # are no directories specified by -L.
+    hardcode_minus_L=yes
+    if test "$with_gcc" = yes && test -z "$link_static_flag"; then
+      # Neither direct hardcoding nor static linking is supported with a
+      # broken collect2.
+      hardcode_direct=unsupported
+    fi
+    ;;
+
+  aix4*)
+    allow_undefined_flag=unsupported
+    archive_cmds='$NM$libobjs | $global_symbol_pipe | sed '\''s/.* //'\'' > $lib.exp;$CC -o $objdir/$soname$libobjs ${wl}-bE:$lib.exp ${wl}-bM:SRE ${wl}-bnoentry;$AR cru $lib $objdir/$soname'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    ;;
+
+  amigaos*)
+    archive_cmds='$rm $objdir/a2ixlibrary.data;$echo "#define NAME $libname" > $objdir/a2ixlibrary.data;$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data;$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data;$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data;$AR cru $lib$libobjs;$RANLIB $lib;(cd $objdir && a2ixlibrary -32)'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    ;;
+
+  # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+  # support.  Future versions do this automatically, but an explicit c++rt0.o
+  # does not break anything, and helps significantly (at the cost of a little
+  # extra space).
+  freebsd2.2*)
+    archive_cmds='$LD -Bshareable -o $lib$libobjs /usr/lib/c++rt0.o'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+  freebsd2*)
+    archive_cmds='$LD -Bshareable -o $lib$libobjs'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # FreeBSD 3, at last, uses gcc -shared to do shared libraries.
+  freebsd3*)
+    archive_cmds='$CC -shared -o $lib$libobjs'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  hpux9*)
+    archive_cmds='$rm $objdir/$soname;$LD -b +s +b $install_libdir -o $objdir/$soname$libobjs;mv $objdir/$soname $lib'
+    hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    export_dynamic_flag_spec='${wl}-E'
+    ;;
+
+  hpux10*)
+    archive_cmds='$LD -b +h $soname +s +b $install_libdir -o $lib$libobjs'
+    hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    export_dynamic_flag_spec='${wl}-E'
+    ;;
+
+  irix5* | irix6*)
+    archive_cmds='$LD -shared -o $lib -soname $soname -set_version $verstring$libobjs'
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    ;;
+
+  netbsd*)
+    # Tested with NetBSD 1.2 ld
+    archive_cmds='$LD -Bshareable -o $lib$libobjs'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  openbsd*)
+    archive_cmds='$LD -Bshareable -o $lib$libobjs'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  os2*)
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    allow_undefined_flag=unsupported
+    archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def;$echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def;$echo DATA >> $objdir/$libname.def;$echo " SINGLE NONSHARED" >> $objdir/$libname.def;$echo EXPORTS >> $objdir/$libname.def;emxexp$libobjs >> $objdir/$libname.def;$CC -Zdll -Zcrtdll -o $lib$libobjs $objdir/$libname.def'
+    old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def'
+    ;;
+
+  osf3* | osf4*)
+    allow_undefined_flag=' -expect_unresolved \*'
+    archive_cmds='$LD -shared${allow_undefined_flag} -o $lib -soname $soname -set_version $verstring$libobjs$deplibs'
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+
+  sco3.2v5*)
+    archive_cmds='$LD -G -o $lib$libobjs'
+    hardcode_direct=yes
+    ;;
+
+  solaris2*)
+    no_undefined_flag=' -z text'
+    archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib$libobjs'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_shlibpath_var=no
+
+    # Solaris 2 before 2.5 hardcodes -L paths.
+    case "$host_os" in
+    solaris2.[0-4]*)
+      hardcode_minus_L=yes
+      ;;
+    esac
+    ;;
+
+  sunos4*)
+    if test "$with_gcc" = yes; then
+      archive_cmds='$CC -shared -o $lib$libobjs'
+    else
+      archive_cmds='$LD -assert pure-text -Bstatic -o $lib$libobjs'
+    fi
+
+    if test "$with_gnu_ld" = yes; then
+      export_dynamic_flag_spec='${wl}-export-dynamic'
+    fi
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  uts4*)
+    archive_cmds='$LD -G -h $soname -o $lib$libobjs'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_direct=no
+    hardcode_minus_L=no
+    hardcode_shlibpath_var=no
+    ;;
+
+  *)
+    ld_shlibs=no
+    can_build_shared=no
+    ;;
+  esac
+fi
+echo "$ac_t$ld_shlibs" 1>&6
+
+if test -z "$NM"; then
+  echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6
+  case "$NM" in
+  /* | [A-Za-z]:\\*) ;; # Let the user override the test with a path.
+  *)
+    IFS="${IFS=        }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+    for ac_dir in /usr/ucb /usr/ccs/bin $PATH /bin; do
+      test -z "$ac_dir" && ac_dir=.
+      if test -f $ac_dir/nm; then
+        # Check to see if the nm accepts a BSD-compat flag.
+        # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+        #   nm: unknown option "B" ignored
+        if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+          NM="$ac_dir/nm -B"
+        elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+          NM="$ac_dir/nm -p"
+       else
+          NM="$ac_dir/nm"
+       fi
+        break
+      fi
+    done
+    IFS="$ac_save_ifs"
+    test -z "$NM" && NM=nm
+    ;;
+  esac
+  echo "$ac_t$NM" 1>&6
+fi
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRSTU]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \1'
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+  symcode='[BCDTU]'
+  ;;
+irix*)
+  # Cannot use undefined symbols on IRIX because inlined functions mess us up.
+  symcode='[BCDEGRST]'
+  ;;
+solaris2*)
+  symcode='[BDTU]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+  symcode='[ABCDGISTUW]'
+fi
+
+# Write the raw and C identifiers.
+global_symbol_pipe="sed -n -e 's/^.* $symcode $sympat$/$symxfrm/p'"
+
+# Check to see that the pipe works correctly.
+pipe_works=no
+$rm conftest*
+cat > conftest.c <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+echo "$progname:991: checking if global_symbol_pipe works" >&5
+if { (eval echo $progname:992: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.o; then
+  # Now try to grab the symbols.
+  nlist=conftest.nm
+  if { echo "$progname:995: eval \"$NM conftest.o | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.o | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then
+
+    # Try sorting and uniquifying the output.
+    if sort "$nlist" | uniq > "$nlist"T; then
+      mv -f "$nlist"T "$nlist"
+      wcout=`wc "$nlist" 2>/dev/null`
+      count=`$echo "X$wcout" | $Xsed -e 's/^[  ]*\([0-9][0-9]*\).*$/\1/'`
+      (test "$count" -ge 0) 2>/dev/null || count=-1
+    else
+      rm -f "$nlist"T
+      count=-1
+    fi
+
+    # Make sure that we snagged all the symbols we need.
+    if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+      if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+       cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+        # Now generate the symbol file.
+        sed 's/^.* \(.*\)$/extern char \1;/' < "$nlist" >> conftest.c
+
+       cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define __ptr_t void *
+#else
+# define __ptr_t char *
+#endif
+
+/* The number of symbols in dld_preloaded_symbols, -1 if unsorted. */
+int dld_preloaded_symbol_count = $count;
+
+/* The mapping between symbol names and symbols. */
+struct {
+  char *name;
+  __ptr_t address;
+}
+dld_preloaded_symbols[] =
+{
+EOF
+        sed 's/^\(.*\) \(.*\)$/  {"\1", (__ptr_t) \&\2},/' < "$nlist" >> conftest.c
+        cat <<\EOF >> conftest.c
+  {0, (__ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+        # Now try linking the two files.
+        mv conftest.o conftestm.o
+       save_LIBS="$LIBS"
+       save_CFLAGS="$CFLAGS"
+        LIBS='conftestm.o'
+       CFLAGS="$CFLAGS$no_builtin_flag"
+        if { (eval echo $progname:1053: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+          pipe_works=yes
+        else
+          echo "$progname: failed program was:" >&5
+          cat conftest.c >&5
+        fi
+        LIBS="$save_LIBS"
+      else
+        echo "cannot find nm_test_func in $nlist" >&5
+      fi
+    else
+      echo "cannot find nm_test_var in $nlist" >&5
+    fi
+  else
+    echo "cannot run $global_symbol_pipe" >&5
+  fi
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.c >&5
+fi
+$rm conftest*
+
+# Do not use the global_symbol_pipe unless it works.
+echo "$ac_t$pipe_works" 1>&6
+test "$pipe_works" = yes || global_symbol_pipe=
+
+# Check hardcoding attributes.
+echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+   test -n "$runpath_var"; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct" != no && \
+     test "$hardcode_minus_L" != no && \
+     test "$hardcode_shlibpath_var" != no; then
+
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+elif test "$hardcode_direct" != yes && \
+     test "$hardcode_minus_L" != yes && \
+     test "$hardcode_shlibpath_var" != yes; then
+  # We cannot hardcode anything.
+  hardcode_action=unsupported
+else
+  # We can only hardcode existing directories.
+  hardcode_action=relink
+fi
+echo "$ac_t$hardcode_action" 1>&6
+test "$hardcode_action" = unsupported && can_build_shared=no
+
+
+reload_flag=
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6
+# PORTME Some linker may need a different reload flag.
+reload_flag='-r'
+echo "$ac_t$reload_flag"
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+# PORTME Fill in your ld.so characteristics
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+version_type=none
+dynamic_linker="$host_os ld.so"
+
+echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6
+case "$host_os" in
+aix3* | aix4*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so.$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}.so.$major'
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+  ;;
+
+freebsd2* | freebsd3*)
+  version_type=sunos
+  library_names_spec='${libname}${release}.so.$versuffix $libname.so'
+  finish_cmds='PATH="$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+gnu*)
+  version_type=sunos
+  library_names_spec='${libname}${release}.so.$versuffix'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+hpux9* | hpux10*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  dynamic_linker="$host_os dld.sl"
+  version_type=sunos
+  shlibpath_var=SHLIB_PATH
+  library_names_spec='${libname}${release}.sl.$versuffix ${libname}${release}.sl.$major $libname.sl'
+  soname_spec='${libname}${release}.sl.$major'
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+irix5* | irix6*)
+  version_type=osf
+  soname_spec='${libname}${release}.so'
+  library_names_spec='${libname}${release}.so.$versuffix $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major $libname.so'
+  soname_spec='${libname}${release}.so.$major'
+  finish_cmds='PATH="$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+
+  if test -f /lib/ld.so.1; then
+    dynamic_linker='GNU ld.so'
+  else
+    # Only the GNU ld.so supports shared libraries on MkLinux.
+    case "$host_cpu" in
+    powerpc*) dynamic_linker=no ;;
+    *) dynamic_linker='Linux ld.so' ;;
+    esac
+  fi
+  ;;
+
+netbsd* | openbsd*)
+  version_type=sunos
+  library_names_spec='${libname}${release}.so.$versuffix'
+  finish_cmds='PATH="$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+os2*)
+  libname_spec='$name'
+  library_names_spec='$libname.dll $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4*)
+  version_type=osf
+  soname_spec='${libname}${release}.so'
+  library_names_spec='${libname}${release}.so.$versuffix $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='${libname}${release}.so.$major'
+  library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris2*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major $libname.so'
+  soname_spec='${libname}${release}.so.$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}.so.$versuffix'
+  finish_cmds='PATH="$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+sysv4.2uw2*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major $libname.so'
+  soname_spec='${libname}${release}.so.$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major $libname.so'
+  soname_spec='${libname}${release}.so.$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+echo "$ac_t$dynamic_linker"
+test "$dynamic_linker" = no && can_build_shared=no
+
+# Report the final consequences.
+echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6
+
+echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds;\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+esac
+
+echo "$ac_t$enable_shared" 1>&6
+
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+
+echo "checking whether to build static libraries... $enable_static" 1>&6
+
+echo $ac_n "checking for objdir... $ac_c" 1>&6
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+echo "$ac_t$objdir" 1>&6
+
+# Copy echo and quote the copy, instead of the original, because it is
+# used later.
+ltecho="$echo"
+
+# Now quote all the things that may contain metacharacters.
+for var in ltecho old_CC old_CFLAGS old_CPPFLAGS old_LD old_NM old_RANLIB \
+  old_LN_S AR CC LD LN_S NM reload_flag reload_cmds wl pic_flag \
+  link_static_flag no_builtin_flag export_dynamic_flag_spec \
+  libname_spec library_names_spec soname_spec RANLIB \
+  old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+  old_postuninstall_cmds archive_cmds postinstall_cmds postuninstall_cmds \
+  allow_undefined_flag no_undefined_flag \
+  finish_cmds finish_eval global_symbol_pipe \
+  hardcode_libdir_flag_spec hardcode_libdir_separator; do
+
+  case "$var" in
+  reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+  old_postinstall_cmds | old_postuninstall_cmds | archive_cmds | \
+  postinstall_cmds | postuninstall_cmds | finish_cmds)
+    # Double-quote double-evaled strings.
+    eval "$var=\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\"\`"
+    ;;
+  *)
+    eval "$var=\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`"
+    ;;
+  esac
+done
+
+ofile=libtool
+trap "$rm $ofile; exit 1" 1 2 15
+echo creating $ofile
+$rm $ofile
+cat <<EOF > $ofile
+#! /bin/sh
+
+# libtool - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM - GNU $PACKAGE $VERSION
+# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh.
+#
+# Copyright (C) 1996-1998 Free Software Foundation, Inc.
+# Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This program was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# CC="$old_CC" CFLAGS="$old_CFLAGS" CPPFLAGS="$old_CPPFLAGS" \\
+# LD="$old_LD" NM="$old_NM" RANLIB="$old_RANLIB" LN_S="$old_LN_S" \\
+#   $0$ltconfig_args
+#
+# Compiler and other test output produced by $progname, useful for
+# debugging $progname, is in ./config.log if it exists.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "\${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi
+
+# An echo program that does not interpret backslashes.
+echo="$ltecho"
+
+# The version of $progname that generated this script.
+LTCONFIG_VERSION="$VERSION"
+
+# Shell to use when invoking shell scripts.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Whether or not to build libtool libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build old-style libraries.
+build_old_libs=$enable_static
+
+# The host system.
+host_alias="$host_alias"
+host="$host"
+
+# The archiver.
+AR="$AR"
+
+# The default C compiler.
+CC="$CC"
+
+# The linker used to build libraries.
+LD="$LD"
+
+# Whether we need hard or soft links.
+LN_S="$LN_S"
+
+# A BSD-compatible nm program.
+NM="$NM"
+
+# The name of the directory that contains temporary libtool files.
+objdir="$objdir"
+
+# How to create reloadable object files.
+reload_flag="$reload_flag"
+reload_cmds="$reload_cmds"
+
+# How to pass a linker flag through the compiler.
+wl="$wl"
+
+# Additional compiler flags for building library objects.
+pic_flag="$pic_flag"
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag="$link_static_flag"
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag="$no_builtin_flag"
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec="$export_dynamic_flag_spec"
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec="$libname_spec"
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec="$library_names_spec"
+
+# The coded name of the library, if different from the real name.
+soname_spec="$soname_spec"
+
+# Commands used to build and install an old-style archive.
+RANLIB="$RANLIB"
+old_archive_cmds="$old_archive_cmds"
+old_postinstall_cmds="$old_postinstall_cmds"
+old_postuninstall_cmds="$old_postuninstall_cmds"
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds="$old_archive_from_new_cmds"
+
+# Commands used to build and install a shared archive.
+archive_cmds="$archive_cmds"
+postinstall_cmds="$postinstall_cmds"
+postuninstall_cmds="$postuninstall_cmds"
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag="$allow_undefined_flag"
+
+# Flag that forces no undefined symbols.
+no_undefined_flag="$no_undefined_flag"
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds="$finish_cmds"
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval="$finish_eval"
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe="$global_symbol_pipe"
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec="$hardcode_libdir_flag_spec"
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator="$hardcode_libdir_separator"
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+EOF
+
+case "$host_os" in
+aix3*)
+  cat <<\EOF >> $ofile
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "${COLLECT_NAMES+set}" != set; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+
+EOF
+  ;;
+esac
+
+# Append the ltmain.sh script.
+cat "$ltmain" >> $ofile || (rm -f $ofile; exit 1)
+
+chmod +x $ofile
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/ltmain.sh b/ltmain.sh
new file mode 100644 (file)
index 0000000..0e88420
--- /dev/null
+++ b/ltmain.sh
@@ -0,0 +1,2464 @@
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun ltconfig.
+#
+# Copyright (C) 1996-1998 Free Software Foundation, Inc.
+# Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# The name of this program.
+progname=`$echo "$0" | sed 's%^.*/%%'`
+modename="$progname"
+
+# Constants.
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.2
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+
+if test "$LTCONFIG_VERSION" != "$VERSION"; then
+  echo "$modename: ltconfig version \`$LTCONFIG_VERSION' does not match $PROGRAM version \`$VERSION'" 1>&2
+  echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit 1
+fi
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+  echo "$modename: not configured to build any kind of library" 1>&2
+  echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit 1
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+
+# Parse our command line options once, thoroughly.
+while test $# -gt 0
+do
+  arg="$1"
+  shift
+
+  case "$arg" in
+  -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    case "$prev" in
+    execute_dlfiles)
+      eval "$prev=\"\$$prev \$arg\""
+      ;;
+    *)
+      eval "$prev=\$arg"
+      ;;
+    esac
+
+    prev=
+    prevopt=
+    continue
+  fi
+
+  # Have we seen a non-optional argument yet?
+  case "$arg" in
+  --help)
+    show_help=yes
+    ;;
+
+  --version)
+    echo "$PROGRAM (GNU $PACKAGE) $VERSION"
+    exit 0
+    ;;
+
+  --dry-run | -n)
+    run=:
+    ;;
+
+  --features)
+    echo "host: $host"
+    if test "$build_libtool_libs" = yes; then
+      echo "enable shared libraries"
+    else
+      echo "disable shared libraries"
+    fi
+    if test "$build_old_libs" = yes; then
+      echo "enable static libraries"
+    else
+      echo "disable static libraries"
+    fi
+    exit 0
+    ;;
+
+  --finish) mode="finish" ;;
+
+  --mode) prevopt="--mode" prev=mode ;;
+  --mode=*) mode="$optarg" ;;
+
+  --quiet | --silent)
+    show=:
+    ;;
+
+  -dlopen)
+    prevopt="-dlopen"
+    prev=execute_dlfiles
+    ;;
+
+  -*)
+    $echo "$modename: unrecognized option \`$arg'" 1>&2
+    $echo "$help" 1>&2
+    exit 1
+    ;;
+
+  *)
+    nonopt="$arg"
+    break
+    ;;
+  esac
+done
+
+if test -n "$prevopt"; then
+  $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+  $echo "$help" 1>&2
+  exit 1
+fi
+
+if test -z "$show_help"; then
+
+  # Infer the operation mode.
+  if test -z "$mode"; then
+    case "$nonopt" in
+    *cc | *++ | gcc* | *-gcc*)
+      mode=link
+      for arg
+      do
+        case "$arg" in
+        -c)
+           mode=compile
+           break
+           ;;
+        esac
+      done
+      ;;
+    *db | *dbx)
+      mode=execute
+      ;;
+    *install*|cp|mv)
+      mode=install
+      ;;
+    *rm)
+      mode=uninstall
+      ;;
+    *)
+      # If we have no mode, but dlfiles were specified, then do execute mode.
+      test -n "$execute_dlfiles" && mode=execute
+
+      # Just use the default operation mode.
+      if test -z "$mode"; then
+        if test -n "$nonopt"; then
+          $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+        else
+          $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+        fi
+      fi
+      ;;
+    esac
+  fi
+
+  # Only execute mode is allowed to have -dlopen flags.
+  if test -n "$execute_dlfiles" && test "$mode" != execute; then
+    $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+    $echo "$help" 1>&2
+    exit 1
+  fi
+
+  # Change the help message to a mode-specific one.
+  generic_help="$help"
+  help="Try \`$modename --help --mode=$mode' for more information."
+
+  # These modes are in order of execution frequency so that they run quickly.
+  case "$mode" in
+  # libtool compile mode
+  compile)
+    modename="$modename: compile"
+    # Get the compilation command and the source file.
+    base_compile=
+    lastarg=
+    srcfile="$nonopt"
+    suppress_output=
+
+    for arg
+    do
+      # Accept any command-line options.
+      case "$arg" in
+      -o)
+       $echo "$modename: you cannot specify the output filename with \`-o'" 1>&2
+       $echo "$help" 1>&2
+       exit 1
+       ;;
+
+      -static)
+       build_libtool_libs=no
+       build_old_libs=yes
+       continue
+       ;;
+      esac
+
+      # Accept the current argument as the source file.
+      lastarg="$srcfile"
+      srcfile="$arg"
+
+      # Aesthetically quote the previous argument.
+
+      # Backslashify any backslashes, double quotes, and dollar signs.
+      # These are the only characters that are still specially
+      # interpreted inside of double-quoted scrings.
+      lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+      # Double-quote args containing other shell metacharacters.
+      # Many Bourne shells cannot handle close brackets correctly in scan
+      # sets, so we specify it separately.
+      case "$lastarg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*)
+       lastarg="\"$lastarg\""
+       ;;
+      esac
+
+      # Add the previous argument to base_compile.
+      if test -z "$base_compile"; then
+       base_compile="$lastarg"
+      else
+       base_compile="$base_compile $lastarg"
+      fi
+    done
+
+    # Get the name of the library object.
+    libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+
+    # Recognize several different file suffixes.
+    xform='[cCFSfms]'
+    case "$libobj" in
+    *.ada) xform=ada ;;
+    *.adb) xform=adb ;;
+    *.ads) xform=ads ;;
+    *.asm) xform=asm ;;
+    *.c++) xform=c++ ;;
+    *.cc) xform=cc ;;
+    *.cpp) xform=cpp ;;
+    *.cxx) xform=cxx ;;
+    *.f90) xform=f90 ;;
+    *.for) xform=for ;;
+    esac
+
+    libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+    case "$libobj" in
+    *.lo) obj=`$echo "X$libobj" | $Xsed -e 's/\.lo$/.o/'` ;;
+    *)
+      $echo "$modename: cannot determine name of library object from \`$srcfile'" 1>&2
+      exit 1
+      ;;
+    esac
+
+    if test -z "$base_compile"; then
+      $echo "$modename: you must specify a compilation command" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      $run $rm $obj $libobj
+      trap "$run $rm $obj $libobj; exit 1" 1 2 15
+    else
+      $run $rm $libobj
+      trap "$run $rm $libobj; exit 1" 1 2 15
+    fi
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      # All platforms use -DPIC, to notify preprocessed assembler code.
+      $show "$base_compile$pic_flag -DPIC $srcfile"
+      if $run eval "$base_compile\$pic_flag -DPIC \$srcfile"; then :
+      else
+        test -n "$obj" && $run $rm $obj
+        exit 1
+      fi
+
+      # If we have no pic_flag, then copy the object into place and finish.
+      if test -z "$pic_flag"; then
+        $show "$LN_S $obj $libobj"
+        $run $LN_S $obj $libobj
+        exit $?
+      fi
+
+      # Just move the object, then go on to compile the next one
+      $show "$mv $obj $libobj"
+      $run $mv $obj $libobj || exit 1
+
+      # Allow error messages only from the first compilation.
+      suppress_output=' >/dev/null 2>&1'
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      # Suppress compiler output if we already did a PIC compilation.
+      $show "$base_compile $srcfile$suppress_output"
+      if $run eval "$base_compile \$srcfile$suppress_output"; then :
+      else
+        $run $rm $obj $libobj
+        exit 1
+      fi
+    fi
+
+    # Create an invalid libtool object if no PIC, so that we do not
+    # accidentally link it into a program.
+    if test "$build_libtool_libs" != yes; then
+      $show "echo timestamp > $libobj"
+      $run eval "echo timestamp > \$libobj" || exit $?
+    fi
+
+    exit 0
+    ;;
+
+  # libtool link mode
+  link)
+    modename="$modename: link"
+    CC="$nonopt"
+    allow_undefined=yes
+    compile_command="$CC"
+    finalize_command="$CC"
+
+    compile_shlibpath=
+    finalize_shlibpath=
+    deplibs=
+    dlfiles=
+    dlprefiles=
+    export_dynamic=no
+    hardcode_libdirs=
+    libobjs=
+    link_against_libtool_libs=
+    ltlibs=
+    objs=
+    prev=
+    prevarg=
+    release=
+    postfix=
+    rpath=
+    perm_rpath=
+    temp_rpath=
+    vinfo=
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case "$arg" in
+      -all-static | -static)
+        if test "X$arg" = "X-all-static" && test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+           $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+        fi
+        build_libtool_libs=no
+       build_old_libs=yes
+        break
+        ;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    for arg
+    do
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+        case "$prev" in
+        output)
+          compile_command="$compile_command @OUTPUT@"
+          finalize_command="$finalize_command @OUTPUT@"
+          ;;
+        esac
+
+        case "$prev" in
+        dlfiles|dlprefiles)
+          case "$arg" in
+          *.la | *.lo) ;;  # We handle these cases below.
+          *)
+            dlprefiles="$dlprefiles $arg"
+            test "$prev" = dlfiles && dlfiles="$dlfiles $arg"
+            prev=
+            ;;
+          esac
+          ;;
+       release)
+         release="-$arg"
+         prev=
+         continue
+         ;;
+       postfix)
+         postfix="-$arg"
+         prev=
+         continue
+         ;;
+        rpath)
+          rpath="$rpath $arg"
+         prev=
+         continue
+         ;;
+        *)
+          eval "$prev=\"\$arg\""
+          prev=
+          continue
+          ;;
+        esac
+      fi
+
+      prevarg="$arg"
+
+      case "$arg" in
+      -all-static)
+       if test -n "$link_static_flag"; then
+          compile_command="$compile_command $link_static_flag"
+         finalize_command="$finalize_command $link_static_flag"
+        fi
+        continue
+       ;;
+
+      -allow-undefined)
+       # FIXME: remove this flag sometime in the future.
+       $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+       continue
+       ;;
+
+      -dlopen)
+        prev=dlfiles
+        continue
+        ;;
+
+      -dlpreopen)
+        prev=dlprefiles
+        continue
+        ;;
+
+      -export-dynamic)
+        if test "$export_dynamic" != yes; then
+          export_dynamic=yes
+         if test -n "$export_dynamic_flag_spec"; then
+           eval arg=\"$export_dynamic_flag_spec\"
+         else
+           arg=
+         fi
+
+          # Add the symbol object into the linking commands.
+         compile_command="$compile_command @SYMFILE@"
+         finalize_command="$finalize_command @SYMFILE@"
+        fi
+        ;;
+
+      -L*)
+        dir=`$echo "X$arg" | $Xsed -e 's%^-L\(.*\)$%\1%'`
+        case "$dir" in
+        /* | [A-Za-z]:\\*)
+         # Add the corresponding hardcode_libdir_flag, if it is not identical.
+          ;;
+        *)
+          $echo "$modename: \`-L$dir' cannot specify a relative directory" 1>&2
+          exit 1
+          ;;
+        esac
+        deplibs="$deplibs $arg"
+        ;;
+
+      -l*) deplibs="$deplibs $arg" ;;
+
+      -no-undefined)
+       allow_undefined=no
+       continue
+       ;;
+
+      -o) prev=output ;;
+
+      -release)
+       prev=release
+       continue
+       ;;
+
+      -postfix)
+       prev=postfix
+       continue
+       ;;
+
+      -rpath)
+        prev=rpath
+        continue
+        ;;
+
+      -static)
+       # If we have no pic_flag, then this is the same as -all-static.
+       if test -z "$pic_flag" && test -n "$link_static_flag"; then
+          compile_command="$compile_command $link_static_flag"
+         finalize_command="$finalize_command $link_static_flag"
+        fi
+       continue
+       ;;
+
+      -version-info)
+        prev=vinfo
+        continue
+        ;;
+
+      # Some other compiler flag.
+      -* | +*)
+       # Unknown arguments in both finalize_command and compile_command need
+       # to be aesthetically quoted because they are evaled later.
+       arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+       case "$arg" in
+       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*)
+         arg="\"$arg\""
+         ;;
+       esac
+        ;;
+
+      *.o | *.a)
+        # A standard object.
+        objs="$objs $arg"
+        ;;
+
+      *.lo)
+        # A library object.
+       if test "$prev" = dlfiles; then
+         dlfiles="$dlfiles $arg"
+         if test "$build_libtool_libs" = yes; then
+           prev=
+           continue
+         else
+           # If libtool objects are unsupported, then we need to preload.
+           prev=dlprefiles
+         fi
+       fi
+
+       if test "$prev" = dlprefiles; then
+         # Preload the old-style object.
+         dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e 's/\.lo$/\.o/'`
+         prev=
+       fi
+       libobjs="$libobjs $arg"
+        ;;
+
+      *.la)
+        # A libtool-controlled library.
+
+        dlname=
+        libdir=
+        library_names=
+        old_library=
+
+        # Check to see that this really is a libtool archive.
+        if (sed -e '2q' $arg | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then :
+        else
+          $echo "$modename: \`$arg' is not a valid libtool archive" 1>&2
+          exit 1
+        fi
+
+        # If there is no directory component, then add one.
+        case "$arg" in
+        */* | *\\*) . $arg ;;
+        *) . ./$arg ;;
+        esac
+
+        if test -z "$libdir"; then
+          $echo "$modename: \`$arg' contains no -rpath information" 1>&2
+          exit 1
+        fi
+
+        # Get the name of the library we link against.
+        linklib=
+        for l in $old_library $library_names; do
+          linklib="$l"
+        done
+
+        if test -z "$linklib"; then
+          $echo "$modename: cannot find name of link library for \`$arg'" 1>&2
+          exit 1
+        fi
+
+        # Find the relevant object directory and library name.
+        name=`$echo "X$arg" | $Xsed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'`
+        dir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+        if test "X$dir" = "X$arg"; then
+          dir="$objdir"
+        else
+          dir="$dir/$objdir"
+        fi
+
+        # This library was specified with -dlopen.
+        if test "$prev" = dlfiles; then
+          dlfiles="$dlfiles $arg"
+          if test -z "$dlname"; then
+            # If there is no dlname, we need to preload.
+            prev=dlprefiles
+          else
+            # We should not create a dependency on this library, but we
+           # may need any libraries it requires.
+           compile_command="$compile_command$dependency_libs"
+           finalize_command="$finalize_command$dependency_libs"
+            prev=
+            continue
+          fi
+        fi
+
+        # The library was specified with -dlpreopen.
+        if test "$prev" = dlprefiles; then
+          # Prefer using a static library (so that no silly _DYNAMIC symbols
+          # are required to link).
+          if test -n "$old_library"; then
+            dlprefiles="$dlprefiles $dir/$old_library"
+          else
+            dlprefiles="$dlprefiles $dir/$linklib"
+          fi
+          prev=
+        fi
+
+        if test "$build_libtool_libs" = yes && test -n "$library_names"; then
+          link_against_libtool_libs="$link_against_libtool_libs $arg"
+          if test -n "$shlibpath_var"; then
+            # Make sure the rpath contains only unique directories.
+            case "$temp_rpath " in
+            *" $dir "*) ;;
+            *) temp_rpath="$temp_rpath $dir" ;;
+            esac
+          fi
+
+         # This is the magic to use -rpath.
+          if test -n "$hardcode_libdir_flag_spec"; then
+            if test -n "$hardcode_libdir_separator"; then
+              if test -z "$hardcode_libdirs"; then
+                # Put the magic libdir with the hardcode flag.
+                hardcode_libdirs="$libdir"
+                libdir="@HARDCODE_LIBDIRS@"
+              else
+                # Just accumulate the unique libdirs.
+               case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+               *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+                 ;;
+               *)
+                 hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+                 ;;
+               esac
+                libdir=
+              fi
+            fi
+
+            if test -n "$libdir"; then
+              eval flag=\"$hardcode_libdir_flag_spec\"
+
+              compile_command="$compile_command $flag"
+              finalize_command="$finalize_command $flag"
+            fi
+          elif test -n "$runpath_var"; then
+            # Do the same for the permanent run path.
+            case "$perm_rpath " in
+            *" $libdir "*) ;;
+            *) perm_rpath="$perm_rpath $libdir" ;;
+            esac
+          fi
+
+
+          case "$hardcode_action" in
+          immediate)
+            if test "$hardcode_direct" = no; then
+              compile_command="$compile_command $dir/$linklib"
+            elif test "$hardcode_minus_L" = no; then
+              compile_command="$compile_command -L$dir -l$name"
+            elif test "$hardcode_shlibpath_var" = no; then
+              compile_shlibpath="$compile_shlibpath$dir:"
+              compile_command="$compile_command -l$name"
+            fi
+            ;;
+
+          relink)
+            # We need an absolute path.
+            case "$dir" in
+            /* | [A-Za-z]:\\*) ;;
+            *)
+              absdir=`cd "$dir" && pwd`
+              if test -z "$absdir"; then
+                $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
+                exit 1
+              fi
+              dir="$absdir"
+              ;;
+            esac
+
+            if test "$hardcode_direct" = yes; then
+              compile_command="$compile_command $dir/$linklib"
+            elif test "$hardcode_minus_L" = yes; then
+              compile_command="$compile_command -L$dir -l$name"
+            elif test "$hardcode_shlibpath_var" = yes; then
+              compile_shlibpath="$compile_shlibpath$dir:"
+              compile_command="$compile_command -l$name"
+            fi
+            ;;
+
+          *)
+            $echo "$modename: \`$hardcode_action' is an unknown hardcode action" 1>&2
+            exit 1
+            ;;
+          esac
+
+          # Finalize command for both is simple: just hardcode it.
+          if test "$hardcode_direct" = yes; then
+            finalize_command="$finalize_command $libdir/$linklib"
+          elif test "$hardcode_minus_L" = yes; then
+            finalize_command="$finalize_command -L$libdir -l$name"
+          elif test "$hardcode_shlibpath_var" = yes; then
+            finalize_shlibpath="$finalize_shlibpath$libdir:"
+            finalize_command="$finalize_command -l$name"
+          else
+            # We cannot seem to hardcode it, guess we'll fake it.
+            finalize_command="$finalize_command -L$libdir -l$name"
+          fi
+        else
+          # Transform directly to old archives if we don't build new libraries.
+          if test -n "$pic_flag" && test -z "$old_library"; then
+            $echo "$modename: cannot find static library for \`$arg'" 1>&2
+            exit 1
+          fi
+
+         # Here we assume that one of hardcode_direct or hardcode_minus_L
+         # is not unsupported.  This is valid on all known static and
+         # shared platforms.
+         if test "$hardcode_direct" != unsupported; then
+           test -n "$old_library" && linklib="$old_library"
+           compile_command="$compile_command $dir/$linklib"
+           finalize_command="$finalize_command $dir/$linklib"
+         else
+           compile_command="$compile_command -L$dir -l$name"
+           finalize_command="$finalize_command -L$dir -l$name"
+         fi
+        fi
+
+       # Add in any libraries that this one depends upon.
+       compile_command="$compile_command$dependency_libs"
+       finalize_command="$finalize_command$dependency_libs"
+       continue
+        ;;
+
+      # Some other compiler argument.
+      *)
+       # Unknown arguments in both finalize_command and compile_command need
+       # to be aesthetically quoted because they are evaled later.
+       arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+       case "$arg" in
+       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*)
+         arg="\"$arg\""
+         ;;
+       esac
+        ;;
+      esac
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+       compile_command="$compile_command $arg"
+       finalize_command="$finalize_command $arg"
+      fi
+    done
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test -n "$vinfo" && test -n "$release"; then
+      $echo "$modename: you cannot specify both \`-version-info' and \`-release'" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    oldlib=
+    oldobjs=
+    case "$output" in
+    "")
+      $echo "$modename: you must specify an output file" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+      ;;
+
+    */* | *\\*)
+      $echo "$modename: output file \`$output' must have no directory components" 1>&2
+      exit 1
+      ;;
+
+    *.a)
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      build_old_libs=yes
+      oldlib="$output"
+      $show "$rm $oldlib"
+      $run $rm $oldlib
+      ;;
+
+    *.la)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case "$output" in
+      lib*) ;;
+      *)
+       $echo "$modename: libtool library \`$arg' must begin with \`lib'" 1>&2
+       $echo "$help" 1>&2
+       exit 1
+       ;;
+      esac
+
+      name=`$echo "X$output" | $Xsed -e 's/\.la$//' -e 's/^lib//'`$postfix
+      eval libname=\"$libname_spec\"
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+      current=0
+      revision=0
+      age=0
+
+      if test -n "$objs"; then
+        $echo "$modename: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1
+        exit 1
+      fi
+
+      # How the heck are we supposed to write a wrapper for a shared library?
+      if test -n "$link_against_libtool_libs"; then
+        $echo "$modename: libtool library \`$output' may not depend on uninstalled libraries:$link_against_libtool_libs" 1>&2
+        exit 1
+      fi
+
+      if test -n "$dlfiles$dlprefiles"; then
+        $echo "$modename: warning: \`-dlopen' is ignored while creating libtool libraries" 1>&2
+        # Nullify the symbol file.
+        compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+        finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+      fi
+
+      if test -z "$rpath"; then
+        $echo "$modename: you must specify an installation directory with \`-rpath'" 1>&2
+       $echo "$help" 1>&2
+        exit 1
+      fi
+
+      set dummy $rpath
+      if test $# -gt 2; then
+       $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+      fi
+      install_libdir="$2"
+
+      # Parse the version information argument.
+      IFS="${IFS=      }"; save_ifs="$IFS"; IFS=':'
+      set dummy $vinfo
+      IFS="$save_ifs"
+
+      if test -n "$5"; then
+        $echo "$modename: too many parameters to \`-version-info'" 1>&2
+        $echo "$help" 1>&2
+        exit 1
+      fi
+
+      test -n "$2" && current="$2"
+      test -n "$3" && revision="$3"
+      test -n "$4" && age="$4"
+
+      # Check that each of the things are valid numbers.
+      case "$current" in
+      0 | [1-9] | [1-9][0-9]*) ;;
+      *)
+        $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2
+        $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+        exit 1
+        ;;
+      esac
+
+      case "$revision" in
+      0 | [1-9] | [1-9][0-9]*) ;;
+      *)
+        $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2
+        $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+        exit 1
+        ;;
+      esac
+
+      case "$age" in
+      0 | [1-9] | [1-9][0-9]*) ;;
+      *)
+        $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2
+        $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+        exit 1
+        ;;
+      esac
+
+      if test $age -gt $current; then
+        $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+        $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+        exit 1
+      fi
+
+      # Calculate the version variables.
+      version_vars="version_type current age revision"
+      case "$version_type" in
+      none) ;;
+
+      linux)
+        version_vars="$version_vars major versuffix"
+        major=`expr $current - $age`
+        versuffix="$major.$age.$revision"
+        ;;
+
+      osf)
+        version_vars="$version_vars versuffix verstring"
+        major=`expr $current - $age`
+        versuffix="$current.$age.$revision"
+        verstring="$versuffix"
+
+        # Add in all the interfaces that we are compatible with.
+        loop=$age
+        while test $loop != 0; do
+          iface=`expr $current - $loop`
+          loop=`expr $loop - 1`
+          verstring="$verstring:${iface}.0"
+        done
+
+        # Make executables depend on our current version.
+        verstring="$verstring:${current}.0"
+        ;;
+
+      sunos)
+        version_vars="$version_vars major versuffix"
+        major="$current"
+        versuffix="$current.$revision"
+        ;;
+
+      *)
+        $echo "$modename: unknown library version type \`$version_type'" 1>&2
+        echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+        exit 1
+        ;;
+      esac
+
+      # Create the output directory, or remove our outputs if we need to.
+      if test -d $objdir; then
+        $show "$rm $objdir/$output $objdir/$libname.* $objdir/${libname}${release}.*"
+        $run $rm $objdir/$output $objdir/$libname.* $objdir/${libname}${release}.*
+      else
+        $show "$mkdir $objdir"
+        $run $mkdir $objdir
+       status=$?
+       if test $status -eq 0 || test -d $objdir; then :
+       else
+         exit $status
+       fi
+      fi
+
+      # Check to see if the archive will have undefined symbols.
+      if test "$allow_undefined" = yes; then
+        if test "$allow_undefined_flag" = unsupported; then
+          $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+          build_libtool_libs=no
+         build_old_libs=yes
+        fi
+      else
+        # Don't allow undefined symbols.
+        allow_undefined_flag="$no_undefined_flag"
+      fi
+
+      # Add libc to deplibs on all systems.
+      dependency_libs="$deplibs"
+      deplibs="$deplibs -lc"
+
+      if test "$build_libtool_libs" = yes; then
+        # Get the real and link names of the library.
+        eval library_names=\"$library_names_spec\"
+        set dummy $library_names
+        realname="$2"
+        shift; shift
+
+        if test -n "$soname_spec"; then
+          eval soname=\"$soname_spec\"
+        else
+          soname="$realname"
+        fi
+
+        lib="$objdir/$realname"
+       for link
+       do
+         linknames="$linknames $link"
+       done
+
+        # Use standard objects if they are PIC.
+        test -z "$pic_flag" && libobjs=`$echo "X$libobjs " | $Xsed -e 's/\.lo /.o /g' -e 's/ $//g'`
+
+        # Do each of the archive commands.
+        eval cmds=\"$archive_cmds\"
+        IFS="${IFS=    }"; save_ifs="$IFS"; IFS=';'
+        for cmd in $cmds; do
+          IFS="$save_ifs"
+          $show "$cmd"
+          $run eval "$cmd" || exit $?
+        done
+        IFS="$save_ifs"
+
+        # Create links to the real library.
+        for linkname in $linknames; do
+          $show "(cd $objdir && $LN_S $realname $linkname)"
+          $run eval '(cd $objdir && $LN_S $realname $linkname)' || exit $?
+        done
+
+        # If -export-dynamic was specified, set the dlname.
+        if test "$export_dynamic" = yes; then
+          # On all known operating systems, these are identical.
+          dlname="$soname"
+        fi
+      fi
+
+      # Now set the variables for building old libraries.
+      oldlib="$objdir/$libname.a"
+      ;;
+
+    *.lo | *.o)
+      if test -n "$link_against_libtool_libs"; then
+        $echo "$modename: error: cannot link libtool libraries into reloadable objects" 1>&2
+        exit 1
+      fi
+
+      if test -n "$deplibs"; then
+        $echo "$modename: warning: \`-l' and \`-L' are ignored while creating objects" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles"; then
+        $echo "$modename: warning: \`-dlopen' is ignored while creating objects" 1>&2
+        # Nullify the symbol file.
+        compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+        finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+      fi
+
+      if test -n "$rpath"; then
+        $echo "$modename: warning: \`-rpath' is ignored while creating objects" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+        $echo "$modename: warning: \`-version-info' is ignored while creating objects" 1>&2
+      fi
+
+      if test -n "$release"; then
+        $echo "$modename: warning: \`-release' is ignored while creating objects" 1>&2
+      fi
+
+      case "$output" in
+      *.lo)
+        if test -n "$objs"; then
+          $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
+          exit 1
+        fi
+        libobj="$output"
+        obj=`$echo "X$output" | $Xsed -e 's/\.lo$/.o/'`
+        ;;
+      *)
+        libobj=
+        obj="$output"
+        ;;
+      esac
+
+      # Delete the old objects.
+      $run $rm $obj $libobj
+
+      # Create the old-style object.
+      reload_objs="$objs"`$echo "X$libobjs " | $Xsed -e 's/[^       ]*\.a //g' -e 's/\.lo /.o /g' -e 's/ $//g'`
+
+      output="$obj"
+      eval cmds=\"$reload_cmds\"
+      IFS="${IFS=      }"; save_ifs="$IFS"; IFS=';'
+      for cmd in $cmds; do
+        IFS="$save_ifs"
+        $show "$cmd"
+        $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+
+      # Exit if we aren't doing a library object file.
+      test -z "$libobj" && exit 0
+
+      if test "$build_libtool_libs" != yes; then
+        # Create an invalid libtool object if no PIC, so that we don't
+        # accidentally link it into a program.
+        $show "echo timestamp > $libobj"
+        $run eval "echo timestamp > $libobj" || exit $?
+        exit 0
+      fi
+
+      if test -n "$pic_flag"; then
+        # Only do commands if we really have different PIC objects.
+        reload_objs="$libobjs"
+        output="$libobj"
+        eval cmds=\"$reload_cmds\"
+        IFS="${IFS=    }"; save_ifs="$IFS"; IFS=';'
+        for cmd in $cmds; do
+          IFS="$save_ifs"
+          $show "$cmd"
+          $run eval "$cmd" || exit $?
+        done
+        IFS="$save_ifs"
+      else
+        # Just create a symlink.
+        $show "$LN_S $obj $libobj"
+        $run $LN_S $obj $libobj || exit 1
+      fi
+
+      exit 0
+      ;;
+
+    *)
+      if test -n "$vinfo"; then
+        $echo "$modename: warning: \`-version-info' is ignored while linking programs" 1>&2
+      fi
+
+      if test -n "$release"; then
+        $echo "$modename: warning: \`-release' is ignored while creating objects" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+       # If the user specified any rpath flags, then add them.
+       for libdir in $rpath; do
+          if test -n "$hardcode_libdir_flag_spec"; then
+            if test -n "$hardcode_libdir_separator"; then
+              if test -z "$hardcode_libdirs"; then
+                # Put the magic libdir with the hardcode flag.
+                hardcode_libdirs="$libdir"
+                libdir="@HARDCODE_LIBDIRS@"
+              else
+                # Just accumulate the unique libdirs.
+               case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+               *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+                 ;;
+               *)
+                 hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+                 ;;
+               esac
+                libdir=
+              fi
+            fi
+
+            if test -n "$libdir"; then
+              eval flag=\"$hardcode_libdir_flag_spec\"
+
+              compile_command="$compile_command $flag"
+              finalize_command="$finalize_command $flag"
+            fi
+          elif test -n "$runpath_var"; then
+            case "$perm_rpath " in
+            *" $libdir "*) ;;
+            *) perm_rpath="$perm_rpath $libdir" ;;
+            esac
+          fi
+       done
+      fi
+
+      # Substitute the hardcoded libdirs into the compile commands.
+      if test -n "$hardcode_libdir_separator"; then
+       compile_command=`$echo "X$compile_command" | $Xsed -e "s%@HARDCODE_LIBDIRS@%$hardcode_libdirs%g"`
+       finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@HARDCODE_LIBDIRS@%$hardcode_libdirs%g"`
+      fi
+
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
+        # Transform all the library objects into standard objects.
+        compile_command=`$echo "X$compile_command " | $Xsed -e 's/\.lo /.o /g' -e 's/ $//'`
+        finalize_command=`$echo "X$finalize_command " | $Xsed -e 's/\.lo /.o /g' -e 's/ $//'`
+      fi
+
+      if test "$export_dynamic" = yes && test -n "$NM" && test -n "$global_symbol_pipe"; then
+        dlsyms="${output}S.c"
+      else
+        dlsyms=
+      fi
+
+      if test -n "$dlsyms"; then
+        # Add our own program objects to the preloaded list.
+        dlprefiles=`$echo "X$objs$dlprefiles " | $Xsed -e 's/\.lo /.o /g' -e 's/ $//'`
+
+       # Discover the nlist of each of the dlfiles.
+        nlist="$objdir/${output}.nm"
+
+       if test -d $objdir; then
+         $show "$rm $nlist ${nlist}T"
+         $run $rm "$nlist" "${nlist}T"
+       else
+         $show "$mkdir $objdir"
+         $run $mkdir $objdir
+         status=$?
+         if test $status -eq 0 || test -d $objdir; then :
+         else
+           exit $status
+         fi
+       fi
+
+        for arg in $dlprefiles; do
+         $show "extracting global C symbols from \`$arg'"
+         $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+        done
+
+        # Parse the name list into a source file.
+        $show "creating $objdir/$dlsyms"
+        if test -z "$run"; then
+         # Make sure we at least have an empty file.
+         test -f "$nlist" || : > "$nlist"
+
+         # Try sorting and uniquifying the output.
+         if sort "$nlist" | uniq > "$nlist"T; then
+           mv -f "$nlist"T "$nlist"
+           wcout=`wc "$nlist" 2>/dev/null`
+           count=`echo "X$wcout" | $Xsed -e 's/^[      ]*\([0-9][0-9]*\).*$/\1/'`
+           (test "$count" -ge 0) 2>/dev/null || count=-1
+         else
+           $rm "$nlist"T
+           count=-1
+         fi
+
+         case "$dlsyms" in
+         "") ;;
+         *.c)
+           $echo > "$objdir/$dlsyms" "\
+/* $dlsyms - symbol resolution table for \`$output' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define dld_preloaded_symbol_count some_other_symbol
+#define dld_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */\
+"
+
+           if test -f "$nlist"; then
+             sed -e 's/^.* \(.*\)$/extern char \1;/' < "$nlist" >> "$objdir/$dlsyms"
+           else
+             echo '/* NONE */' >> "$objdir/$dlsyms"
+           fi
+
+           $echo >> "$objdir/$dlsyms" "\
+
+#undef dld_preloaded_symbol_count
+#undef dld_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define __ptr_t void *
+#else
+# define __ptr_t char *
+#endif
+
+/* The number of symbols in dld_preloaded_symbols, -1 if unsorted. */
+int dld_preloaded_symbol_count = $count;
+
+/* The mapping between symbol names and symbols. */
+struct {
+  char *name;
+  __ptr_t address;
+}
+dld_preloaded_symbols[] =
+{\
+"
+
+           if test -f "$nlist"; then
+             sed 's/^\(.*\) \(.*\)$/  {"\1", (__ptr_t) \&\2},/' < "$nlist" >> "$objdir/$dlsyms"
+           fi
+
+           $echo >> "$objdir/$dlsyms" "\
+  {0, (__ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif\
+"
+           ;;
+
+         *)
+           $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
+           exit 1
+           ;;
+         esac
+        fi
+
+        # Now compile the dynamic symbol file.
+        $show "(cd $objdir && $CC -c$no_builtin_flag \"$dlsyms\")"
+        $run eval '(cd $objdir && $CC -c$no_builtin_flag "$dlsyms")' || exit $?
+
+        # Transform the symbol file into the correct name.
+        compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$objdir/${output}S.o%"`
+        finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$objdir/${output}S.o%"`
+      elif test "$export_dynamic" != yes; then
+        test -n "$dlfiles$dlprefiles" && $echo "$modename: warning: \`-dlopen' and \`-dlpreopen' are ignored without \`-export-dynamic'" 1>&2
+      else
+        # We keep going just in case the user didn't refer to
+        # dld_preloaded_symbols.  The linker will fail if global_symbol_pipe
+        # really was required.
+        $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+
+        # Nullify the symbol file.
+        compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+        finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+      fi
+
+      if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then
+        # Replace the output file specification.
+        compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+        finalize_command=`$echo "X$finalize_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+
+        # We have no uninstalled library dependencies, so finalize right now.
+        $show "$compile_command"
+        $run eval "$compile_command"
+        exit $?
+      fi
+
+      # Replace the output file specification.
+      compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$objdir/$output"'%g'`
+      finalize_command=`$echo "X$finalize_command" | $Xsed -e 's%@OUTPUT@%'"$objdir/$output"'T%g'`
+
+      # Create the binary in the object directory, then wrap it.
+      if test -d $objdir; then :
+      else
+        $show "$mkdir $objdir"
+       $run $mkdir $objdir
+       status=$?
+       if test $status -eq 0 || test -d $objdir; then :
+       else
+         exit $status
+       fi
+      fi
+
+      if test -n "$shlibpath_var"; then
+        # We should set the shlibpath_var
+        rpath=
+        for dir in $temp_rpath; do
+          case "$dir" in
+          /* | [A-Za-z]:\\*)
+            # Absolute path.
+            rpath="$rpath$dir:"
+            ;;
+          *)
+            # Relative path: add a thisdir entry.
+            rpath="$rpath\$thisdir/$dir:"
+            ;;
+          esac
+        done
+        temp_rpath="$rpath"
+      fi
+
+      # Delete the old output file.
+      $run $rm $output
+
+      if test -n "$compile_shlibpath"; then
+        compile_command="$shlibpath_var=\"$compile_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+        finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      if test -n "$runpath_var" && test -n "$perm_rpath"; then
+        # We should set the runpath_var.
+        rpath=
+        for dir in $perm_rpath; do
+          rpath="$rpath$dir:"
+        done
+        compile_command="$runpath_var=\"$rpath\$$runpath_var\" $compile_command"
+        finalize_command="$runpath_var=\"$rpath\$$runpath_var\" $finalize_command"
+      fi
+
+      case "$hardcode_action" in
+      relink)
+        # AGH! Flame the AIX and HP-UX people for me, will ya?
+        $echo "$modename: warning: using a buggy system linker" 1>&2
+        $echo "$modename: relinking will be required before \`$output' can be installed" 1>&2
+        ;;
+      esac
+
+      $show "$compile_command"
+      $run eval "$compile_command" || exit $?
+
+      # Now create the wrapper script.
+      $show "creating $output"
+
+      # Quote the finalize command for shipping.
+      finalize_command=`$echo "X$finalize_command" | $Xsed -e "$sed_quote_subst"`
+
+      # Quote $echo for shipping.
+      qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
+
+      # Only actually do things if our run command is non-null.
+      if test -z "$run"; then
+        $rm $output
+        trap "$rm $output; exit 1" 1 2 15
+
+        $echo > $output "\
+#! /bin/sh
+
+# $output - temporary wrapper script for $objdir/$output
+# Generated by ltmain.sh - GNU $PACKAGE $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of \``pwd`'.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test \"\${CDPATH+set}\" = set; then CDPATH=; export CDPATH; fi
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variables:
+  link_against_libtool_libs='$link_against_libtool_libs'
+  finalize_command=\"$finalize_command\"
+else
+  # When we are sourced in execute mode, \$file and \$echo are already set.
+  if test \"\$libtool_execute_magic\" = \"$magic\"; then :
+  else
+    echo=\"$qecho\"
+    file=\"\$0\"
+  fi\
+"
+        $echo >> $output "\
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      /* | [A-Za-z]:\\*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
+
+    file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\`
+  done
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+
+  progdir=\"\$thisdir/$objdir\"
+  program='$output'
+
+  if test -f \"\$progdir/\$program\"; then"
+
+        # Export our shlibpath_var if we have one.
+        if test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+          $echo >> $output "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/:*\$//'\`
+
+    export $shlibpath_var
+"
+        fi
+
+        $echo >> $output "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+
+      # Export the path to the program.
+      PATH=\"\$progdir:\$PATH\"
+      export PATH
+
+      exec \$program \${1+\"\$@\"}
+
+      \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+      exit 1
+    fi
+  else
+    # The program doesn't exist.
+    \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
+    \$echo \"This script is just a wrapper for \$program.\" 1>&2
+    echo \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit 1
+  fi
+fi\
+"
+        chmod +x $output
+      fi
+      exit 0
+      ;;
+    esac
+
+    # See if we need to build an old-fashioned archive.
+    if test "$build_old_libs" = "yes"; then
+      # Transform .lo files to .o files.
+      oldobjs="$objs"`$echo "X$libobjs " | $Xsed -e 's/[^   ]*\.a //g' -e 's/\.lo /.o /g' -e 's/ $//g'`
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+       eval cmds=\"$old_archive_from_new_cmds\"
+      else
+       eval cmds=\"$old_archive_cmds\"
+      fi
+      IFS="${IFS=      }"; save_ifs="$IFS"; IFS=';'
+      for cmd in $cmds; do
+        IFS="$save_ifs"
+        $show "$cmd"
+        $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    fi
+
+    # Now create the libtool archive.
+    case "$output" in
+    *.la)
+      old_library=
+      test "$build_old_libs" = yes && old_library="$libname.a"
+
+      $show "creating $output"
+
+      # Only create the output if not a dry run.
+      if test -z "$run"; then
+        $echo > $output "\
+# $output - a libtool library file
+# Generated by ltmain.sh - GNU $PACKAGE $VERSION
+
+# The name that we can dlopen(3).
+dlname='$dlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'\
+"
+      fi
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      $show "(cd $objdir && $LN_S ../$output $output)"
+      $run eval "(cd $objdir && $LN_S ../$output $output)" || exit 1
+      ;;
+    esac
+    exit 0
+    ;;
+
+  # libtool install mode
+  install)
+    modename="$modename: install"
+
+    # There may be an optional /bin/sh argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$nonopt" = "$SHELL"; then
+      # Aesthetically quote it.
+      arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
+      case "$arg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*)
+       arg="\"$arg\""
+       ;;
+      esac
+      install_prog="$arg "
+      arg="$1"
+      shift
+    else
+      install_prog=
+      arg="$nonopt"
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+    case "$arg" in
+    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \      ]*|*]*)
+      arg="\"$arg\""
+      ;;
+    esac
+    install_prog="$install_prog$arg"
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=
+    stripme=
+    for arg
+    do
+      if test -n "$dest"; then
+        files="$files $dest"
+        dest="$arg"
+        continue
+      fi
+
+      case "$arg" in
+      -d) isdir=yes ;;
+      -f) prev="-f" ;;
+      -g) prev="-g" ;;
+      -m) prev="-m" ;;
+      -o) prev="-o" ;;
+      -s)
+        stripme=" -s"
+        continue
+        ;;
+      -*) ;;
+
+      *)
+        # If the previous option needed an argument, then skip it.
+        if test -n "$prev"; then
+          prev=
+        else
+          dest="$arg"
+          continue
+        fi
+        ;;
+      esac
+
+      # Aesthetically quote the argument.
+      arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+      case "$arg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*)
+       arg="\"$arg\""
+       ;;
+      esac
+      install_prog="$install_prog $arg"
+    done
+
+    if test -z "$install_prog"; then
+      $echo "$modename: you must specify an install program" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prev' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+        $echo "$modename: no file or destination specified" 1>&2
+      else
+        $echo "$modename: you must specify a destination" 1>&2
+      fi
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    # Strip any trailing slash from the destination.
+    dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test -n "$isdir"; then
+      destdir="$dest"
+      destname=
+    else
+      destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
+      test "X$destdir" = "X$dest" && destdir=.
+      destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files
+      if test $# -gt 2; then
+        $echo "$modename: \`$dest' is not a directory" 1>&2
+        $echo "$help" 1>&2
+        exit 1
+      fi
+    fi
+    case "$destdir" in
+    /* | [A-Za-z]:\\*) ;;
+    *)
+      for file in $files; do
+        case "$file" in
+        *.lo) ;;
+        *)
+          $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
+          $echo "$help" 1>&2
+          exit 1
+          ;;
+        esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case "$file" in
+      *.a)
+        # Do the static libraries later.
+        staticlibs="$staticlibs $file"
+        ;;
+
+      *.la)
+        # Check to see that this really is a libtool archive.
+        if (sed -e '2q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then :
+        else
+          $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
+          $echo "$help" 1>&2
+          exit 1
+        fi
+
+        library_names=
+        old_library=
+        # If there is no directory component, then add one.
+        case "$file" in
+        */* | *\\*) . $file ;;
+        *) . ./$file ;;
+        esac
+
+        # Add the libdir to current_libdirs if it is the destination.
+        if test "X$destdir" = "X$libdir"; then
+          case "$current_libdirs " in
+          *" $libdir "*) ;;
+          *) current_libdirs="$current_libdirs $libdir" ;;
+          esac
+        else
+          # Note the libdir as a future libdir.
+          case "$future_libdirs " in
+          *" $libdir "*) ;;
+          *) future_libdirs="$future_libdirs $libdir" ;;
+          esac
+        fi
+
+        dir="`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/"
+        test "X$dir" = "X$file/" && dir=
+        dir="$dir$objdir"
+
+        # See the names of the shared library.
+        set dummy $library_names
+        if test -n "$2"; then
+          realname="$2"
+          shift
+          shift
+
+          # Install the shared library and build the symlinks.
+          $show "$install_prog $dir/$realname $destdir/$realname"
+          $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $?
+          test "X$dlname" = "X$realname" && dlname=
+
+          if test $# -gt 0; then
+            # Delete the old symlinks.
+            rmcmd="$rm"
+            for linkname
+            do
+              rmcmd="$rmcmd $destdir/$linkname"
+            done
+            $show "$rmcmd"
+            $run $rmcmd
+
+            # ... and create new ones.
+            for linkname
+            do
+              test "X$dlname" = "X$linkname" && dlname=
+              $show "(cd $destdir && $LN_S $realname $linkname)"
+              $run eval "(cd $destdir && $LN_S $realname $linkname)"
+            done
+          fi
+
+          if test -n "$dlname"; then
+            # Install the dynamically-loadable library.
+            $show "$install_prog $dir/$dlname $destdir/$dlname"
+            $run eval "$install_prog $dir/$dlname $destdir/$dlname" || exit $?
+          fi
+
+          # Do each command in the postinstall commands.
+          lib="$destdir/$realname"
+          eval cmds=\"$postinstall_cmds\"
+          IFS="${IFS=  }"; save_ifs="$IFS"; IFS=';'
+          for cmd in $cmds; do
+            IFS="$save_ifs"
+            $show "$cmd"
+            $run eval "$cmd" || exit $?
+          done
+          IFS="$save_ifs"
+        fi
+
+        # Install the pseudo-library for information purposes.
+        name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+        $show "$install_prog $file $destdir/$name"
+        $run eval "$install_prog $file $destdir/$name" || exit $?
+
+        # Maybe install the static library, too.
+        test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+        ;;
+
+      *.lo)
+        # Install (i.e. copy) a libtool object.
+
+        # Figure out destination file name, if it wasn't already specified.
+        if test -n "$destname"; then
+          destfile="$destdir/$destname"
+        else
+          destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+          destfile="$destdir/$destfile"
+        fi
+
+        # Deduce the name of the destination old-style object file.
+        case "$destfile" in
+        *.lo)
+          staticdest=`$echo "X$destfile" | $Xsed -e 's/\.lo$/\.o/'`
+          ;;
+        *.o)
+          staticdest="$destfile"
+          destfile=
+          ;;
+        *)
+          $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
+          $echo "$help" 1>&2
+          exit 1
+          ;;
+        esac
+
+        # Install the libtool object if requested.
+        if test -n "$destfile"; then
+          $show "$install_prog $file $destfile"
+          $run eval "$install_prog $file $destfile" || exit $?
+        fi
+
+        # Install the old object if enabled.
+        if test "$build_old_libs" = yes; then
+          # Deduce the name of the old-style object file.
+          staticobj=`$echo "X$file" | $Xsed -e 's/\.lo$/\.o/'`
+
+          $show "$install_prog $staticobj $staticdest"
+          $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+        fi
+        exit 0
+        ;;
+
+      *)
+        # Do a test to see if this is really a libtool program.
+        if (sed -e '4q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then
+          link_against_libtool_libs=
+          finalize_command=
+
+          # If there is no directory component, then add one.
+          case "$file" in
+          */* | *\\*) . $file ;;
+          *) . ./$file ;;
+          esac
+
+          # Check the variables that should have been set.
+          if test -z "$link_against_libtool_libs" || test -z "$finalize_command"; then
+            $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2
+            exit 1
+          fi
+
+          finalize=yes
+          for lib in $link_against_libtool_libs; do
+            # Check to see that each library is installed.
+            libdir=
+            if test -f "$lib"; then
+              # If there is no directory component, then add one.
+              case "$lib" in
+              */* | *\\*) . $lib ;;
+              *) . ./$lib ;;
+              esac
+            fi
+            libfile="$libdir/`$echo "X$lib" | $Xsed -e 's%^.*/%%g'`"
+            if test -z "$libdir"; then
+              $echo "$modename: warning: \`$lib' contains no -rpath information" 1>&2
+            elif test -f "$libfile"; then :
+            else
+              $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+              finalize=no
+            fi
+          done
+
+          if test "$hardcode_action" = relink; then
+            if test "$finalize" = yes; then
+              $echo "$modename: warning: relinking \`$file' on behalf of your buggy system linker" 1>&2
+              $show "$finalize_command"
+              if $run eval "$finalize_command"; then :
+              else
+                $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+                continue
+              fi
+              file="$objdir/$file"T
+            else
+              $echo "$modename: warning: cannot relink \`$file' on behalf of your buggy system linker" 1>&2
+            fi
+          else
+            # Install the binary that we compiled earlier.
+           file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+          fi
+        fi
+
+        $show "$install_prog$stripme $file $dest"
+        $run eval "$install_prog\$stripme \$file \$dest" || exit $?
+        ;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+
+      $show "$install_prog $file $oldlib"
+      $run eval "$install_prog \$file \$oldlib" || exit $?
+
+      # Do each command in the postinstall commands.
+      eval cmds=\"$old_postinstall_cmds\"
+      IFS="${IFS=      }"; save_ifs="$IFS"; IFS=';'
+      for cmd in $cmds; do
+        IFS="$save_ifs"
+        $show "$cmd"
+        $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$future_libdirs"; then
+      $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+    fi
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      test -n "$run" && current_libdirs=" -n$current_libdirs"
+      exec $SHELL $0 --finish$current_libdirs
+      exit 1
+    fi
+
+    exit 0
+    ;;
+
+  # libtool finish mode
+  finish)
+    modename="$modename: finish"
+    libdirs="$nonopt"
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for dir
+      do
+        libdirs="$libdirs $dir"
+      done
+
+      for libdir in $libdirs; do
+       if test -n "$finish_cmds"; then
+         # Do each command in the finish commands.
+         eval cmds=\"$finish_cmds\"
+          IFS="${IFS=  }"; save_ifs="$IFS"; IFS=';'
+          for cmd in $cmds; do
+            IFS="$save_ifs"
+            $show "$cmd"
+            $run eval "$cmd"
+          done
+          IFS="$save_ifs"
+       fi
+       if test -n "$finish_eval"; then
+         # Do the single finish_eval.
+         eval cmds=\"$finish_eval\"
+         $run eval "$cmds"
+       fi
+      done
+    fi
+
+    echo "------------------------------------------------------------------------------"
+    echo "Libraries have been installed in:"
+    for libdir in $libdirs; do
+      echo "   $libdir"
+    done
+    echo
+    echo "To link against installed libraries in a given directory, LIBDIR,"
+    echo "you must use the \`-LLIBDIR' flag during linking."
+    echo
+    echo " You will also need to do one of the following:"
+    if test -n "$shlibpath_var"; then
+      echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
+      echo "     during execution"
+    fi
+    if test -n "$runpath_var"; then
+      echo "   - add LIBDIR to the \`$runpath_var' environment variable"
+      echo "     during linking"
+    fi
+    if test -n "$hardcode_libdir_flag_spec"; then
+      libdir=LIBDIR
+      eval flag=\"$hardcode_libdir_flag_spec\"
+
+      echo "   - use the \`$flag' linker flag"
+    fi
+    if test -f /etc/ld.so.conf; then
+      echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+    fi
+    echo
+    echo "See any operating system documentation about shared libraries for"
+    echo "more information, such as the ld(1) and ld.so(8) manual pages."
+    echo "------------------------------------------------------------------------------"
+    exit 0
+    ;;
+
+  # libtool execute mode
+  execute)
+    modename="$modename: execute"
+
+    # The first argument is the command name.
+    cmd="$nonopt"
+    if test -z "$cmd"; then
+      $echo "$modename: you must specify a COMMAND" 1>&2
+      $echo "$help"
+      exit 1
+    fi
+
+    # Handle -dlopen flags immediately.
+    for file in $execute_dlfiles; do
+      if test -f "$file"; then :
+      else
+       $echo "$modename: \`$file' is not a file" 1>&2
+       $echo "$help" 1>&2
+       exit 1
+      fi
+
+      dir=
+      case "$file" in
+      *.la)
+        # Check to see that this really is a libtool archive.
+        if (sed -e '2q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then :
+        else
+          $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+          $echo "$help" 1>&2
+          exit 1
+        fi
+
+       # Read the libtool library.
+       dlname=
+       library_names=
+
+        # If there is no directory component, then add one.
+       case "$file" in
+       */* | *\\*) . $file ;;
+        *) . ./$file ;;
+       esac
+
+       # Skip this library if it cannot be dlopened.
+       if test -z "$dlname"; then
+         # Warn if it was a shared library.
+         test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
+         continue
+       fi
+
+       dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+       test "X$dir" = "X$file" && dir=.
+
+       if test -f "$dir/$objdir/$dlname"; then
+         dir="$dir/$objdir"
+       else
+         $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+         exit 1
+       fi
+       ;;
+
+      *.lo)
+       # Just add the directory containing the .lo file.
+       dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+       test "X$dir" = "X$file" && dir=.
+       ;;
+
+      *)
+       $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+        continue
+       ;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir="$absdir"
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+       eval "$shlibpath_var=\"\$dir\""
+      else
+       eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic="$magic"
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case "$file" in
+      -*) ;;
+      *)
+        # Do a test to see if this is really a libtool program.
+        if (sed -e '4q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then
+         # If there is no directory component, then add one.
+         case "$file" in
+         */* | *\\*) . $file ;;
+         *) . ./$file ;;
+         esac
+
+         # Transform arg to wrapped name.
+         file="$progdir/$program"
+       fi
+        ;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
+      args="$args \"$file\""
+    done
+
+    if test -z "$run"; then
+      # Export the shlibpath_var.
+      eval "export $shlibpath_var"
+
+      # Now actually exec the command.
+      eval "exec \$cmd$args"
+
+      $echo "$modename: cannot exec \$cmd$args"
+      exit 1
+    else
+      # Display what would be done.
+      eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+      $echo "export $shlibpath_var"
+      $echo "$cmd$args"
+      exit 0
+    fi
+    ;;
+
+  # libtool uninstall mode
+  uninstall)
+    modename="$modename: uninstall"
+    rm="$nonopt"
+    files=
+
+    for arg
+    do
+      case "$arg" in
+      -*) rm="$rm $arg" ;;
+      *) files="$files $arg" ;;
+      esac
+    done
+
+    if test -z "$rm"; then
+      $echo "$modename: you must specify an RM program" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    for file in $files; do
+      dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+      test "X$dir" = "X$file" && dir=.
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+      rmfiles="$file"
+
+      case "$name" in
+      *.la)
+        # Possibly a libtool archive, so verify it.
+        if (sed -e '2q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then
+          . $dir/$name
+
+          # Delete the libtool libraries and symlinks.
+          for n in $library_names; do
+            rmfiles="$rmfiles $dir/$n"
+            test "X$n" = "X$dlname" && dlname=
+          done
+          test -n "$dlname" && rmfiles="$rmfiles $dir/$dlname"
+          test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library"
+
+         $show "$rm $rmfiles"
+         $run $rm $rmfiles
+
+         if test -n "$library_names"; then
+           # Do each command in the postuninstall commands.
+           eval cmds=\"$postuninstall_cmds\"
+           IFS="${IFS=         }"; save_ifs="$IFS"; IFS=';'
+           for cmd in $cmds; do
+             IFS="$save_ifs"
+             $show "$cmd"
+             $run eval "$cmd"
+           done
+           IFS="$save_ifs"
+         fi
+
+          if test -n "$old_library"; then
+           # Do each command in the old_postuninstall commands.
+           eval cmds=\"$old_postuninstall_cmds\"
+           IFS="${IFS=         }"; save_ifs="$IFS"; IFS=';'
+           for cmd in $cmds; do
+             IFS="$save_ifs"
+             $show "$cmd"
+             $run eval "$cmd"
+           done
+           IFS="$save_ifs"
+         fi
+
+          # FIXME: should reinstall the best remaining shared library.
+        fi
+        ;;
+
+      *.lo)
+        if test "$build_old_libs" = yes; then
+          oldobj=`$echo "X$name" | $Xsed -e 's/\.lo$/\.o/'`
+          rmfiles="$rmfiles $dir/$oldobj"
+        fi
+       $show "$rm $rmfiles"
+       $run $rm $rmfiles
+        ;;
+
+      *)
+       $show "$rm $rmfiles"
+       $run $rm $rmfiles
+       ;;
+      esac
+    done
+    exit 0
+    ;;
+
+  "")
+    $echo "$modename: you must specify a MODE" 1>&2
+    $echo "$generic_help" 1>&2
+    exit 1
+    ;;
+  esac
+
+  $echo "$modename: invalid operation mode \`$mode'" 1>&2
+  $echo "$generic_help" 1>&2
+  exit 1
+fi # test -z "$show_help"
+
+# We need to display help for each of the modes.
+case "$mode" in
+"") $echo \
+"Usage: $modename [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+-n, --dry-run         display commands without modifying any files
+    --features        display configuration information and exit
+    --finish          same as \`--mode=finish'
+    --help            display this help message and exit
+    --mode=MODE       use operation mode MODE [default=inferred from MODE-ARGS]
+    --quiet           same as \`--silent'
+    --silent          don't print informational messages
+    --version         print version information
+
+MODE must be one of the following:
+
+      compile         compile a source file into a libtool object
+      execute         automatically set library path, then run a program
+      finish          complete the installation of libtool libraries
+      install         install libraries or executables
+      link            create a library or an executable
+      uninstall       remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE.  Try \`$modename --help --mode=MODE' for
+a more detailed description of MODE."
+  exit 0
+  ;;
+
+compile)
+  $echo \
+"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+  ;;
+
+execute)
+  $echo \
+"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+  ;;
+
+finish)
+  $echo \
+"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the \`--dry-run' option if you just want to see what would be executed."
+  ;;
+
+install)
+  $echo \
+"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+  ;;
+
+link)
+  $echo \
+"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to dld_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -static           do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+                    specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only
+library objects (\`.lo' files) may be specified, and \`-rpath' is required.
+
+If OUTPUT-FILE ends in \`.a', then a standard library is created using \`ar'
+and \`ranlib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.o', then a reloadable object file is
+created, otherwise an executable program is created."
+  ;;
+
+uninstall)
+  $echo
+"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+  ;;
+
+*)
+  $echo "$modename: invalid operation mode \`$mode'" 1>&2
+  $echo "$help" 1>&2
+  exit 1
+  ;;
+esac
+
+echo
+$echo "Try \`$modename --help' for more information about other modes."
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/missing b/missing
new file mode 100755 (executable)
index 0000000..e4b838c
--- /dev/null
+++ b/missing
@@ -0,0 +1,134 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+case "$1" in
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  automake     touch all \`Makefile.in' files
+  bison        touch file \`y.tab.c'
+  makeinfo     touch the output file
+  yacc         touch file \`y.tab.c'"
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing - GNU libit 0.0"
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+  aclocal)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  It should be needed only if
+         you modified \`acinclude.m4' or \`configure.in'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  It should be needed only if
+         you modified \`configure.in'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  It should be needed only if
+         you modified \`acconfig.h' or \`configure.in'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    touch config.h.in
+    ;;
+
+  automake)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  It should be needed only if
+         you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print \
+      | sed 's/^\(.*\).am$/touch \1.in/' \
+      | sh
+    ;;
+
+  bison|yacc)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  It should be needed only if
+         your modified any \`.y' file.  For being effective, your
+         modifications might require the \`Bison' package.  Grab it from
+         any GNU archive site."
+    touch y.tab.c
+    ;;
+
+  makeinfo)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  It should be needed only if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+      file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+    fi
+    touch $file
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+         system.  You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequirements for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
diff --git a/mkinstalldirs b/mkinstalldirs
new file mode 100755 (executable)
index 0000000..fef1eb9
--- /dev/null
@@ -0,0 +1,36 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Last modified: 1994-03-25
+# Public domain
+
+errstatus=0
+
+for file in ${1+"$@"} ; do
+   set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+   shift
+
+   pathcomp=
+   for d in ${1+"$@"} ; do
+     pathcomp="$pathcomp$d"
+     case "$pathcomp" in
+       -* ) pathcomp=./$pathcomp ;;
+     esac
+
+     if test ! -d "$pathcomp"; then
+        echo "mkdir $pathcomp" 1>&2
+        mkdir "$pathcomp" > /dev/null 2>&1 || lasterr=$?
+     fi
+
+     if test ! -d "$pathcomp"; then
+       errstatus=$lasterr
+     fi
+
+     pathcomp="$pathcomp/"
+   done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
diff --git a/stamp-h.in b/stamp-h.in
new file mode 100644 (file)
index 0000000..9788f70
--- /dev/null
@@ -0,0 +1 @@
+timestamp
diff --git a/testglib.c b/testglib.c
new file mode 100644 (file)
index 0000000..e96dfb5
--- /dev/null
@@ -0,0 +1,401 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "glib.h"
+
+int array[10000];
+
+void
+my_hash_callback (gpointer key,
+                 gpointer value,
+                 gpointer user_data)
+{
+  int *d = value;
+  *d = 1;
+}
+
+guint
+my_hash (gconstpointer key)
+{
+  return (guint) *((const gint*) key);
+}
+
+gint
+my_hash_compare (gconstpointer a,
+                gconstpointer b)
+{
+  return *((const gint*) a) == *((const gint*) b);
+}
+
+gint 
+my_list_compare_one (gconstpointer a, gconstpointer b)
+{
+  gint one = *((const gint*)a);
+  gint two = *((const gint*)b);
+  return one-two;
+}
+
+gint 
+my_list_compare_two (gconstpointer a, gconstpointer b)
+{
+  gint one = *((const gint*)a);
+  gint two = *((const gint*)b);
+  return two-one;
+}
+
+/* void
+my_list_print (gpointer a, gpointer b)
+{
+  gint three = *((gint*)a);
+  g_print("%d", three);
+}; */
+
+gint
+my_compare (gconstpointer a,
+           gconstpointer b)
+{
+  const char *cha = a;
+  const char *chb = b;
+
+  return *cha - *chb;
+}
+
+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 *mem[10000], *tmp_string, *tmp_string_2;
+  gint i, j;
+  GArray *garray;
+  GString *string1, *string2;
+  GTree *tree;
+  char chars[62];
+
+  g_print ("checking size of gint8...%ld (should be 1)\n", (glong)sizeof (gint8));
+  g_print ("checking size of gint16...%ld (should be 2)\n", (glong)sizeof (gint16));
+  g_print ("checking size of gint32...%ld (should be 4)\n", (glong)sizeof (gint32));
+
+  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);
+
+  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);
+
+  g_print ("ok\n");
+
+
+  g_print ("checking 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");
+
+
+  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]);
+
+  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);
+  for (i = 0; i < 10000; i++)
+    g_array_append_val (garray, gint, 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);
+  for (i = 0; i < 10000; i++)
+    g_array_prepend_val (garray, gint, i);
+
+  for (i = 0; i < 10000; i++)
+    if (g_array_index (garray, gint, i) != (10000 - i - 1))
+      g_print ("uh oh: %d ( %d )\n", g_array_index (garray, gint, i), 10000 - 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));
+
+  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);
+
+  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...\n");
+
+  /* g_debug (argv[0]); */
+
+
+  return 0;
+}
diff --git a/tests/testglib.c b/tests/testglib.c
new file mode 100644 (file)
index 0000000..e96dfb5
--- /dev/null
@@ -0,0 +1,401 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "glib.h"
+
+int array[10000];
+
+void
+my_hash_callback (gpointer key,
+                 gpointer value,
+                 gpointer user_data)
+{
+  int *d = value;
+  *d = 1;
+}
+
+guint
+my_hash (gconstpointer key)
+{
+  return (guint) *((const gint*) key);
+}
+
+gint
+my_hash_compare (gconstpointer a,
+                gconstpointer b)
+{
+  return *((const gint*) a) == *((const gint*) b);
+}
+
+gint 
+my_list_compare_one (gconstpointer a, gconstpointer b)
+{
+  gint one = *((const gint*)a);
+  gint two = *((const gint*)b);
+  return one-two;
+}
+
+gint 
+my_list_compare_two (gconstpointer a, gconstpointer b)
+{
+  gint one = *((const gint*)a);
+  gint two = *((const gint*)b);
+  return two-one;
+}
+
+/* void
+my_list_print (gpointer a, gpointer b)
+{
+  gint three = *((gint*)a);
+  g_print("%d", three);
+}; */
+
+gint
+my_compare (gconstpointer a,
+           gconstpointer b)
+{
+  const char *cha = a;
+  const char *chb = b;
+
+  return *cha - *chb;
+}
+
+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 *mem[10000], *tmp_string, *tmp_string_2;
+  gint i, j;
+  GArray *garray;
+  GString *string1, *string2;
+  GTree *tree;
+  char chars[62];
+
+  g_print ("checking size of gint8...%ld (should be 1)\n", (glong)sizeof (gint8));
+  g_print ("checking size of gint16...%ld (should be 2)\n", (glong)sizeof (gint16));
+  g_print ("checking size of gint32...%ld (should be 4)\n", (glong)sizeof (gint32));
+
+  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);
+
+  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);
+
+  g_print ("ok\n");
+
+
+  g_print ("checking 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");
+
+
+  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]);
+
+  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);
+  for (i = 0; i < 10000; i++)
+    g_array_append_val (garray, gint, 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);
+  for (i = 0; i < 10000; i++)
+    g_array_prepend_val (garray, gint, i);
+
+  for (i = 0; i < 10000; i++)
+    if (g_array_index (garray, gint, i) != (10000 - i - 1))
+      g_print ("uh oh: %d ( %d )\n", g_array_index (garray, gint, i), 10000 - 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));
+
+  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);
+
+  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...\n");
+
+  /* g_debug (argv[0]); */
+
+
+  return 0;
+}