From 2e0320d57e417f7d1c838d729a99545db2228e93 Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Wed, 10 Jun 1998 23:21:14 +0000 Subject: [PATCH 1/1] Initial revision --- .cvsignore | 17 + AUTHORS | 1 + COPYING | 0 ChangeLog | 443 ++++++++++ ChangeLog.pre-2-0 | 443 ++++++++++ ChangeLog.pre-2-10 | 443 ++++++++++ ChangeLog.pre-2-12 | 443 ++++++++++ ChangeLog.pre-2-2 | 443 ++++++++++ ChangeLog.pre-2-4 | 443 ++++++++++ ChangeLog.pre-2-6 | 443 ++++++++++ ChangeLog.pre-2-8 | 443 ++++++++++ INSTALL | 0 Makefile.am | 54 ++ NEWS | 0 README | 0 acconfig.h | 76 ++ autogen.sh | 50 ++ config.guess | 883 +++++++++++++++++++ config.h.in | 81 ++ config.sub | 954 ++++++++++++++++++++ configure.in | 221 +++++ garray.c | 143 +++ gbacktrace.c | 260 ++++++ gcache.c | 212 +++++ gcompletion.c | 238 +++++ gdataset.c | 342 ++++++++ gerror.c | 260 ++++++ ghash.c | 426 +++++++++ glib-config | 57 ++ glib-config.in | 57 ++ glib.m4 | 183 ++++ glib/Makefile.am | 54 ++ glib/garray.c | 143 +++ glib/gbacktrace.c | 260 ++++++ glib/gcache.c | 212 +++++ glib/gcompletion.c | 238 +++++ glib/gdataset.c | 342 ++++++++ glib/gerror.c | 260 ++++++ glib/ghash.c | 426 +++++++++ glib/glist.c | 481 ++++++++++ glib/gmem.c | 807 +++++++++++++++++ glib/gmessages.c | 180 ++++ glib/gprimes.c | 62 ++ glib/gscanner.c | 1551 +++++++++++++++++++++++++++++++++ glib/gslist.c | 456 ++++++++++ glib/gstring.c | 647 ++++++++++++++ glib/gtimer.c | 120 +++ glib/gtree.c | 719 +++++++++++++++ glib/gutils.c | 858 ++++++++++++++++++ glibconfig.h.in | 87 ++ glist.c | 481 ++++++++++ gmem.c | 807 +++++++++++++++++ gmessages.c | 180 ++++ gprimes.c | 62 ++ gscanner.c | 1551 +++++++++++++++++++++++++++++++++ gslist.c | 456 ++++++++++ gstring.c | 647 ++++++++++++++ gtimer.c | 120 +++ gtree.c | 719 +++++++++++++++ gutils.c | 858 ++++++++++++++++++ install-sh | 238 +++++ ltconfig | 1532 ++++++++++++++++++++++++++++++++ ltmain.sh | 2464 ++++++++++++++++++++++++++++++++++++++++++++++++++++ missing | 134 +++ mkinstalldirs | 36 + stamp-h.in | 1 + testglib.c | 401 +++++++++ tests/testglib.c | 401 +++++++++ 68 files changed, 27050 insertions(+) create mode 100644 .cvsignore create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 ChangeLog.pre-2-0 create mode 100644 ChangeLog.pre-2-10 create mode 100644 ChangeLog.pre-2-12 create mode 100644 ChangeLog.pre-2-2 create mode 100644 ChangeLog.pre-2-4 create mode 100644 ChangeLog.pre-2-6 create mode 100644 ChangeLog.pre-2-8 create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 NEWS create mode 100644 README create mode 100644 acconfig.h create mode 100755 autogen.sh create mode 100755 config.guess create mode 100644 config.h.in create mode 100755 config.sub create mode 100644 configure.in create mode 100644 garray.c create mode 100644 gbacktrace.c create mode 100644 gcache.c create mode 100644 gcompletion.c create mode 100644 gdataset.c create mode 100644 gerror.c create mode 100644 ghash.c create mode 100755 glib-config create mode 100644 glib-config.in create mode 100644 glib.m4 create mode 100644 glib/Makefile.am create mode 100644 glib/garray.c create mode 100644 glib/gbacktrace.c create mode 100644 glib/gcache.c create mode 100644 glib/gcompletion.c create mode 100644 glib/gdataset.c create mode 100644 glib/gerror.c create mode 100644 glib/ghash.c create mode 100644 glib/glist.c create mode 100644 glib/gmem.c create mode 100644 glib/gmessages.c create mode 100644 glib/gprimes.c create mode 100644 glib/gscanner.c create mode 100644 glib/gslist.c create mode 100644 glib/gstring.c create mode 100644 glib/gtimer.c create mode 100644 glib/gtree.c create mode 100644 glib/gutils.c create mode 100644 glibconfig.h.in create mode 100644 glist.c create mode 100644 gmem.c create mode 100644 gmessages.c create mode 100644 gprimes.c create mode 100644 gscanner.c create mode 100644 gslist.c create mode 100644 gstring.c create mode 100644 gtimer.c create mode 100644 gtree.c create mode 100644 gutils.c create mode 100755 install-sh create mode 100755 ltconfig create mode 100644 ltmain.sh create mode 100755 missing create mode 100755 mkinstalldirs create mode 100644 stamp-h.in create mode 100644 testglib.c create mode 100644 tests/testglib.c diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 0000000..b03d5fc --- /dev/null +++ b/.cvsignore @@ -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 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 index 0000000..e69de29 diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..4b21235 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,443 @@ +Wed Jun 10 12:56:07 1998 Owen Taylor + + * glib.h: renamed g_const_pointer => gconstpointer + +Tue Jun 9 17:47:33 1998 Owen Taylor + + * glib.h: Remove #error - HP/UX. + +Sat May 23 19:00:01 1998 Owen Taylor + [ Combination of: + gtk-rrh-980412-0.patch (Raja R Harinath ) + gtk-jbuhler-980516-0 (Jeremy Buhler ) ] + + * 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 + + * glib.h: added enum-helper macros for code generation. + added G_BREAKPOINT(). + +Sat Jun 6 14:09:22 PDT 1998 Manish Singh + + * gmem.c: commented out MEM_PROFILE and MEM_CHECK, causing weird + problems + +Wed Jun 3 06:19:42 1998 Tim Janik + + * 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 + + * 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 + + * 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 +(Yasuhiro SHIRASAKI : gtk-joke-980517-0.patch) + + * gutils.c: Restored a missing prototype for g_vsprintf. + +Wed May 20 05:02:26 1998 Tim Janik + + * 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 + + * gcompletion.c: generic functions for completion... + +Sun May 17 10:48:27 1998 Tim Janik + + * 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 + + * 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 + + * gscanner.c: replaced some snprintf with g_snprintf + +Fri May 15 00:56:59 1998 Tim Janik + + * 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 + + * 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 + + * 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 + (James A : 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 + + * 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 in gutils.c which was causing problems for the + g_strsignal implementation on FreeBSD boxes. + +Mon May 11 09:53:43 1998 Tim Janik + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * gutils.c (g_parse_debug_string): Make debug string + parsine case-insensitive + +Fri Apr 3 17:03:18 PST 1998 Manish Singh + + * gstring.c: corrected possible overrun when inserting into + GStrings (thanks Elrond) + +Fri Apr 3 18:05:45 1998 Owen Taylor + + * testglib.c: Removed literal german from strings + to appease SGI compiler. + +Thu Mar 26 20:47:21 1998 Owen Taylor + + * 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 + + * 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 + + * garray.c: g_rarray_truncate length done correctly + +Sun Mar 15 07:13:34 1998 Tim Janik + + * 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 + + * 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 + + * Makefile.am (configincludedir): Moved glibconfig.h to + $(pkglibdir)/include + +Tue Mar 10 02:03:12 1998 Tim Janik + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * gstring.c glib.h: removed deprecated g_string_equal + and g_string_hash. + +Tue Feb 10 13:04:36 1998 Owen Taylor + + * 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 + + * gstring.c gutils.c: added some additional consts in + appropriate places to remove a warning + +Sat Feb 7 11:15:54 1998 Owen Taylor + + * gutils.c: include for tolower() + +Fri Jan 30 23:57:17 PST 1998 Manish Singh + + * added and autoconfigured in a new utility function + g_strcasecmp + +Wed Jan 28 23:53:27 PST 1998 Manish Singh + + * 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 + + * 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 + + * 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 + + * Applied patch from (Raja R Harinath ) + 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 + + * 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 + + * 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 + + * 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 + + * glib.h: Changed guint32 -> guint for bitfields. + (Bitfields must be int or unsigned int?) + +Fri Jan 2 23:52 PST 1998 Jay Painter + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * Started ChangeLog diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 new file mode 100644 index 0000000..4b21235 --- /dev/null +++ b/ChangeLog.pre-2-0 @@ -0,0 +1,443 @@ +Wed Jun 10 12:56:07 1998 Owen Taylor + + * glib.h: renamed g_const_pointer => gconstpointer + +Tue Jun 9 17:47:33 1998 Owen Taylor + + * glib.h: Remove #error - HP/UX. + +Sat May 23 19:00:01 1998 Owen Taylor + [ Combination of: + gtk-rrh-980412-0.patch (Raja R Harinath ) + gtk-jbuhler-980516-0 (Jeremy Buhler ) ] + + * 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 + + * glib.h: added enum-helper macros for code generation. + added G_BREAKPOINT(). + +Sat Jun 6 14:09:22 PDT 1998 Manish Singh + + * gmem.c: commented out MEM_PROFILE and MEM_CHECK, causing weird + problems + +Wed Jun 3 06:19:42 1998 Tim Janik + + * 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 + + * 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 + + * 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 +(Yasuhiro SHIRASAKI : gtk-joke-980517-0.patch) + + * gutils.c: Restored a missing prototype for g_vsprintf. + +Wed May 20 05:02:26 1998 Tim Janik + + * 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 + + * gcompletion.c: generic functions for completion... + +Sun May 17 10:48:27 1998 Tim Janik + + * 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 + + * 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 + + * gscanner.c: replaced some snprintf with g_snprintf + +Fri May 15 00:56:59 1998 Tim Janik + + * 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 + + * 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 + + * 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 + (James A : 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 + + * 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 in gutils.c which was causing problems for the + g_strsignal implementation on FreeBSD boxes. + +Mon May 11 09:53:43 1998 Tim Janik + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * gutils.c (g_parse_debug_string): Make debug string + parsine case-insensitive + +Fri Apr 3 17:03:18 PST 1998 Manish Singh + + * gstring.c: corrected possible overrun when inserting into + GStrings (thanks Elrond) + +Fri Apr 3 18:05:45 1998 Owen Taylor + + * testglib.c: Removed literal german from strings + to appease SGI compiler. + +Thu Mar 26 20:47:21 1998 Owen Taylor + + * 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 + + * 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 + + * garray.c: g_rarray_truncate length done correctly + +Sun Mar 15 07:13:34 1998 Tim Janik + + * 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 + + * 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 + + * Makefile.am (configincludedir): Moved glibconfig.h to + $(pkglibdir)/include + +Tue Mar 10 02:03:12 1998 Tim Janik + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * gstring.c glib.h: removed deprecated g_string_equal + and g_string_hash. + +Tue Feb 10 13:04:36 1998 Owen Taylor + + * 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 + + * gstring.c gutils.c: added some additional consts in + appropriate places to remove a warning + +Sat Feb 7 11:15:54 1998 Owen Taylor + + * gutils.c: include for tolower() + +Fri Jan 30 23:57:17 PST 1998 Manish Singh + + * added and autoconfigured in a new utility function + g_strcasecmp + +Wed Jan 28 23:53:27 PST 1998 Manish Singh + + * 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 + + * 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 + + * 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 + + * Applied patch from (Raja R Harinath ) + 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 + + * 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 + + * 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 + + * 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 + + * glib.h: Changed guint32 -> guint for bitfields. + (Bitfields must be int or unsigned int?) + +Fri Jan 2 23:52 PST 1998 Jay Painter + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * Started ChangeLog diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 new file mode 100644 index 0000000..4b21235 --- /dev/null +++ b/ChangeLog.pre-2-10 @@ -0,0 +1,443 @@ +Wed Jun 10 12:56:07 1998 Owen Taylor + + * glib.h: renamed g_const_pointer => gconstpointer + +Tue Jun 9 17:47:33 1998 Owen Taylor + + * glib.h: Remove #error - HP/UX. + +Sat May 23 19:00:01 1998 Owen Taylor + [ Combination of: + gtk-rrh-980412-0.patch (Raja R Harinath ) + gtk-jbuhler-980516-0 (Jeremy Buhler ) ] + + * 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 + + * glib.h: added enum-helper macros for code generation. + added G_BREAKPOINT(). + +Sat Jun 6 14:09:22 PDT 1998 Manish Singh + + * gmem.c: commented out MEM_PROFILE and MEM_CHECK, causing weird + problems + +Wed Jun 3 06:19:42 1998 Tim Janik + + * 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 + + * 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 + + * 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 +(Yasuhiro SHIRASAKI : gtk-joke-980517-0.patch) + + * gutils.c: Restored a missing prototype for g_vsprintf. + +Wed May 20 05:02:26 1998 Tim Janik + + * 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 + + * gcompletion.c: generic functions for completion... + +Sun May 17 10:48:27 1998 Tim Janik + + * 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 + + * 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 + + * gscanner.c: replaced some snprintf with g_snprintf + +Fri May 15 00:56:59 1998 Tim Janik + + * 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 + + * 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 + + * 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 + (James A : 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 + + * 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 in gutils.c which was causing problems for the + g_strsignal implementation on FreeBSD boxes. + +Mon May 11 09:53:43 1998 Tim Janik + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * gutils.c (g_parse_debug_string): Make debug string + parsine case-insensitive + +Fri Apr 3 17:03:18 PST 1998 Manish Singh + + * gstring.c: corrected possible overrun when inserting into + GStrings (thanks Elrond) + +Fri Apr 3 18:05:45 1998 Owen Taylor + + * testglib.c: Removed literal german from strings + to appease SGI compiler. + +Thu Mar 26 20:47:21 1998 Owen Taylor + + * 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 + + * 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 + + * garray.c: g_rarray_truncate length done correctly + +Sun Mar 15 07:13:34 1998 Tim Janik + + * 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 + + * 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 + + * Makefile.am (configincludedir): Moved glibconfig.h to + $(pkglibdir)/include + +Tue Mar 10 02:03:12 1998 Tim Janik + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * gstring.c glib.h: removed deprecated g_string_equal + and g_string_hash. + +Tue Feb 10 13:04:36 1998 Owen Taylor + + * 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 + + * gstring.c gutils.c: added some additional consts in + appropriate places to remove a warning + +Sat Feb 7 11:15:54 1998 Owen Taylor + + * gutils.c: include for tolower() + +Fri Jan 30 23:57:17 PST 1998 Manish Singh + + * added and autoconfigured in a new utility function + g_strcasecmp + +Wed Jan 28 23:53:27 PST 1998 Manish Singh + + * 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 + + * 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 + + * 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 + + * Applied patch from (Raja R Harinath ) + 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 + + * 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 + + * 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 + + * 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 + + * glib.h: Changed guint32 -> guint for bitfields. + (Bitfields must be int or unsigned int?) + +Fri Jan 2 23:52 PST 1998 Jay Painter + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * Started ChangeLog diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 new file mode 100644 index 0000000..4b21235 --- /dev/null +++ b/ChangeLog.pre-2-12 @@ -0,0 +1,443 @@ +Wed Jun 10 12:56:07 1998 Owen Taylor + + * glib.h: renamed g_const_pointer => gconstpointer + +Tue Jun 9 17:47:33 1998 Owen Taylor + + * glib.h: Remove #error - HP/UX. + +Sat May 23 19:00:01 1998 Owen Taylor + [ Combination of: + gtk-rrh-980412-0.patch (Raja R Harinath ) + gtk-jbuhler-980516-0 (Jeremy Buhler ) ] + + * 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 + + * glib.h: added enum-helper macros for code generation. + added G_BREAKPOINT(). + +Sat Jun 6 14:09:22 PDT 1998 Manish Singh + + * gmem.c: commented out MEM_PROFILE and MEM_CHECK, causing weird + problems + +Wed Jun 3 06:19:42 1998 Tim Janik + + * 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 + + * 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 + + * 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 +(Yasuhiro SHIRASAKI : gtk-joke-980517-0.patch) + + * gutils.c: Restored a missing prototype for g_vsprintf. + +Wed May 20 05:02:26 1998 Tim Janik + + * 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 + + * gcompletion.c: generic functions for completion... + +Sun May 17 10:48:27 1998 Tim Janik + + * 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 + + * 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 + + * gscanner.c: replaced some snprintf with g_snprintf + +Fri May 15 00:56:59 1998 Tim Janik + + * 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 + + * 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 + + * 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 + (James A : 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 + + * 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 in gutils.c which was causing problems for the + g_strsignal implementation on FreeBSD boxes. + +Mon May 11 09:53:43 1998 Tim Janik + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * gutils.c (g_parse_debug_string): Make debug string + parsine case-insensitive + +Fri Apr 3 17:03:18 PST 1998 Manish Singh + + * gstring.c: corrected possible overrun when inserting into + GStrings (thanks Elrond) + +Fri Apr 3 18:05:45 1998 Owen Taylor + + * testglib.c: Removed literal german from strings + to appease SGI compiler. + +Thu Mar 26 20:47:21 1998 Owen Taylor + + * 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 + + * 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 + + * garray.c: g_rarray_truncate length done correctly + +Sun Mar 15 07:13:34 1998 Tim Janik + + * 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 + + * 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 + + * Makefile.am (configincludedir): Moved glibconfig.h to + $(pkglibdir)/include + +Tue Mar 10 02:03:12 1998 Tim Janik + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * gstring.c glib.h: removed deprecated g_string_equal + and g_string_hash. + +Tue Feb 10 13:04:36 1998 Owen Taylor + + * 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 + + * gstring.c gutils.c: added some additional consts in + appropriate places to remove a warning + +Sat Feb 7 11:15:54 1998 Owen Taylor + + * gutils.c: include for tolower() + +Fri Jan 30 23:57:17 PST 1998 Manish Singh + + * added and autoconfigured in a new utility function + g_strcasecmp + +Wed Jan 28 23:53:27 PST 1998 Manish Singh + + * 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 + + * 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 + + * 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 + + * Applied patch from (Raja R Harinath ) + 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 + + * 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 + + * 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 + + * 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 + + * glib.h: Changed guint32 -> guint for bitfields. + (Bitfields must be int or unsigned int?) + +Fri Jan 2 23:52 PST 1998 Jay Painter + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * Started ChangeLog diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 new file mode 100644 index 0000000..4b21235 --- /dev/null +++ b/ChangeLog.pre-2-2 @@ -0,0 +1,443 @@ +Wed Jun 10 12:56:07 1998 Owen Taylor + + * glib.h: renamed g_const_pointer => gconstpointer + +Tue Jun 9 17:47:33 1998 Owen Taylor + + * glib.h: Remove #error - HP/UX. + +Sat May 23 19:00:01 1998 Owen Taylor + [ Combination of: + gtk-rrh-980412-0.patch (Raja R Harinath ) + gtk-jbuhler-980516-0 (Jeremy Buhler ) ] + + * 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 + + * glib.h: added enum-helper macros for code generation. + added G_BREAKPOINT(). + +Sat Jun 6 14:09:22 PDT 1998 Manish Singh + + * gmem.c: commented out MEM_PROFILE and MEM_CHECK, causing weird + problems + +Wed Jun 3 06:19:42 1998 Tim Janik + + * 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 + + * 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 + + * 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 +(Yasuhiro SHIRASAKI : gtk-joke-980517-0.patch) + + * gutils.c: Restored a missing prototype for g_vsprintf. + +Wed May 20 05:02:26 1998 Tim Janik + + * 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 + + * gcompletion.c: generic functions for completion... + +Sun May 17 10:48:27 1998 Tim Janik + + * 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 + + * 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 + + * gscanner.c: replaced some snprintf with g_snprintf + +Fri May 15 00:56:59 1998 Tim Janik + + * 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 + + * 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 + + * 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 + (James A : 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 + + * 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 in gutils.c which was causing problems for the + g_strsignal implementation on FreeBSD boxes. + +Mon May 11 09:53:43 1998 Tim Janik + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * gutils.c (g_parse_debug_string): Make debug string + parsine case-insensitive + +Fri Apr 3 17:03:18 PST 1998 Manish Singh + + * gstring.c: corrected possible overrun when inserting into + GStrings (thanks Elrond) + +Fri Apr 3 18:05:45 1998 Owen Taylor + + * testglib.c: Removed literal german from strings + to appease SGI compiler. + +Thu Mar 26 20:47:21 1998 Owen Taylor + + * 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 + + * 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 + + * garray.c: g_rarray_truncate length done correctly + +Sun Mar 15 07:13:34 1998 Tim Janik + + * 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 + + * 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 + + * Makefile.am (configincludedir): Moved glibconfig.h to + $(pkglibdir)/include + +Tue Mar 10 02:03:12 1998 Tim Janik + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * gstring.c glib.h: removed deprecated g_string_equal + and g_string_hash. + +Tue Feb 10 13:04:36 1998 Owen Taylor + + * 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 + + * gstring.c gutils.c: added some additional consts in + appropriate places to remove a warning + +Sat Feb 7 11:15:54 1998 Owen Taylor + + * gutils.c: include for tolower() + +Fri Jan 30 23:57:17 PST 1998 Manish Singh + + * added and autoconfigured in a new utility function + g_strcasecmp + +Wed Jan 28 23:53:27 PST 1998 Manish Singh + + * 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 + + * 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 + + * 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 + + * Applied patch from (Raja R Harinath ) + 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 + + * 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 + + * 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 + + * 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 + + * glib.h: Changed guint32 -> guint for bitfields. + (Bitfields must be int or unsigned int?) + +Fri Jan 2 23:52 PST 1998 Jay Painter + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * Started ChangeLog diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 new file mode 100644 index 0000000..4b21235 --- /dev/null +++ b/ChangeLog.pre-2-4 @@ -0,0 +1,443 @@ +Wed Jun 10 12:56:07 1998 Owen Taylor + + * glib.h: renamed g_const_pointer => gconstpointer + +Tue Jun 9 17:47:33 1998 Owen Taylor + + * glib.h: Remove #error - HP/UX. + +Sat May 23 19:00:01 1998 Owen Taylor + [ Combination of: + gtk-rrh-980412-0.patch (Raja R Harinath ) + gtk-jbuhler-980516-0 (Jeremy Buhler ) ] + + * 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 + + * glib.h: added enum-helper macros for code generation. + added G_BREAKPOINT(). + +Sat Jun 6 14:09:22 PDT 1998 Manish Singh + + * gmem.c: commented out MEM_PROFILE and MEM_CHECK, causing weird + problems + +Wed Jun 3 06:19:42 1998 Tim Janik + + * 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 + + * 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 + + * 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 +(Yasuhiro SHIRASAKI : gtk-joke-980517-0.patch) + + * gutils.c: Restored a missing prototype for g_vsprintf. + +Wed May 20 05:02:26 1998 Tim Janik + + * 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 + + * gcompletion.c: generic functions for completion... + +Sun May 17 10:48:27 1998 Tim Janik + + * 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 + + * 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 + + * gscanner.c: replaced some snprintf with g_snprintf + +Fri May 15 00:56:59 1998 Tim Janik + + * 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 + + * 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 + + * 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 + (James A : 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 + + * 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 in gutils.c which was causing problems for the + g_strsignal implementation on FreeBSD boxes. + +Mon May 11 09:53:43 1998 Tim Janik + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * gutils.c (g_parse_debug_string): Make debug string + parsine case-insensitive + +Fri Apr 3 17:03:18 PST 1998 Manish Singh + + * gstring.c: corrected possible overrun when inserting into + GStrings (thanks Elrond) + +Fri Apr 3 18:05:45 1998 Owen Taylor + + * testglib.c: Removed literal german from strings + to appease SGI compiler. + +Thu Mar 26 20:47:21 1998 Owen Taylor + + * 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 + + * 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 + + * garray.c: g_rarray_truncate length done correctly + +Sun Mar 15 07:13:34 1998 Tim Janik + + * 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 + + * 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 + + * Makefile.am (configincludedir): Moved glibconfig.h to + $(pkglibdir)/include + +Tue Mar 10 02:03:12 1998 Tim Janik + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * gstring.c glib.h: removed deprecated g_string_equal + and g_string_hash. + +Tue Feb 10 13:04:36 1998 Owen Taylor + + * 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 + + * gstring.c gutils.c: added some additional consts in + appropriate places to remove a warning + +Sat Feb 7 11:15:54 1998 Owen Taylor + + * gutils.c: include for tolower() + +Fri Jan 30 23:57:17 PST 1998 Manish Singh + + * added and autoconfigured in a new utility function + g_strcasecmp + +Wed Jan 28 23:53:27 PST 1998 Manish Singh + + * 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 + + * 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 + + * 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 + + * Applied patch from (Raja R Harinath ) + 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 + + * 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 + + * 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 + + * 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 + + * glib.h: Changed guint32 -> guint for bitfields. + (Bitfields must be int or unsigned int?) + +Fri Jan 2 23:52 PST 1998 Jay Painter + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * Started ChangeLog diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 new file mode 100644 index 0000000..4b21235 --- /dev/null +++ b/ChangeLog.pre-2-6 @@ -0,0 +1,443 @@ +Wed Jun 10 12:56:07 1998 Owen Taylor + + * glib.h: renamed g_const_pointer => gconstpointer + +Tue Jun 9 17:47:33 1998 Owen Taylor + + * glib.h: Remove #error - HP/UX. + +Sat May 23 19:00:01 1998 Owen Taylor + [ Combination of: + gtk-rrh-980412-0.patch (Raja R Harinath ) + gtk-jbuhler-980516-0 (Jeremy Buhler ) ] + + * 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 + + * glib.h: added enum-helper macros for code generation. + added G_BREAKPOINT(). + +Sat Jun 6 14:09:22 PDT 1998 Manish Singh + + * gmem.c: commented out MEM_PROFILE and MEM_CHECK, causing weird + problems + +Wed Jun 3 06:19:42 1998 Tim Janik + + * 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 + + * 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 + + * 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 +(Yasuhiro SHIRASAKI : gtk-joke-980517-0.patch) + + * gutils.c: Restored a missing prototype for g_vsprintf. + +Wed May 20 05:02:26 1998 Tim Janik + + * 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 + + * gcompletion.c: generic functions for completion... + +Sun May 17 10:48:27 1998 Tim Janik + + * 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 + + * 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 + + * gscanner.c: replaced some snprintf with g_snprintf + +Fri May 15 00:56:59 1998 Tim Janik + + * 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 + + * 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 + + * 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 + (James A : 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 + + * 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 in gutils.c which was causing problems for the + g_strsignal implementation on FreeBSD boxes. + +Mon May 11 09:53:43 1998 Tim Janik + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * gutils.c (g_parse_debug_string): Make debug string + parsine case-insensitive + +Fri Apr 3 17:03:18 PST 1998 Manish Singh + + * gstring.c: corrected possible overrun when inserting into + GStrings (thanks Elrond) + +Fri Apr 3 18:05:45 1998 Owen Taylor + + * testglib.c: Removed literal german from strings + to appease SGI compiler. + +Thu Mar 26 20:47:21 1998 Owen Taylor + + * 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 + + * 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 + + * garray.c: g_rarray_truncate length done correctly + +Sun Mar 15 07:13:34 1998 Tim Janik + + * 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 + + * 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 + + * Makefile.am (configincludedir): Moved glibconfig.h to + $(pkglibdir)/include + +Tue Mar 10 02:03:12 1998 Tim Janik + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * gstring.c glib.h: removed deprecated g_string_equal + and g_string_hash. + +Tue Feb 10 13:04:36 1998 Owen Taylor + + * 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 + + * gstring.c gutils.c: added some additional consts in + appropriate places to remove a warning + +Sat Feb 7 11:15:54 1998 Owen Taylor + + * gutils.c: include for tolower() + +Fri Jan 30 23:57:17 PST 1998 Manish Singh + + * added and autoconfigured in a new utility function + g_strcasecmp + +Wed Jan 28 23:53:27 PST 1998 Manish Singh + + * 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 + + * 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 + + * 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 + + * Applied patch from (Raja R Harinath ) + 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 + + * 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 + + * 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 + + * 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 + + * glib.h: Changed guint32 -> guint for bitfields. + (Bitfields must be int or unsigned int?) + +Fri Jan 2 23:52 PST 1998 Jay Painter + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * Started ChangeLog diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 new file mode 100644 index 0000000..4b21235 --- /dev/null +++ b/ChangeLog.pre-2-8 @@ -0,0 +1,443 @@ +Wed Jun 10 12:56:07 1998 Owen Taylor + + * glib.h: renamed g_const_pointer => gconstpointer + +Tue Jun 9 17:47:33 1998 Owen Taylor + + * glib.h: Remove #error - HP/UX. + +Sat May 23 19:00:01 1998 Owen Taylor + [ Combination of: + gtk-rrh-980412-0.patch (Raja R Harinath ) + gtk-jbuhler-980516-0 (Jeremy Buhler ) ] + + * 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 + + * glib.h: added enum-helper macros for code generation. + added G_BREAKPOINT(). + +Sat Jun 6 14:09:22 PDT 1998 Manish Singh + + * gmem.c: commented out MEM_PROFILE and MEM_CHECK, causing weird + problems + +Wed Jun 3 06:19:42 1998 Tim Janik + + * 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 + + * 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 + + * 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 +(Yasuhiro SHIRASAKI : gtk-joke-980517-0.patch) + + * gutils.c: Restored a missing prototype for g_vsprintf. + +Wed May 20 05:02:26 1998 Tim Janik + + * 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 + + * gcompletion.c: generic functions for completion... + +Sun May 17 10:48:27 1998 Tim Janik + + * 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 + + * 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 + + * gscanner.c: replaced some snprintf with g_snprintf + +Fri May 15 00:56:59 1998 Tim Janik + + * 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 + + * 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 + + * 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 + (James A : 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 + + * 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 in gutils.c which was causing problems for the + g_strsignal implementation on FreeBSD boxes. + +Mon May 11 09:53:43 1998 Tim Janik + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * gutils.c (g_parse_debug_string): Make debug string + parsine case-insensitive + +Fri Apr 3 17:03:18 PST 1998 Manish Singh + + * gstring.c: corrected possible overrun when inserting into + GStrings (thanks Elrond) + +Fri Apr 3 18:05:45 1998 Owen Taylor + + * testglib.c: Removed literal german from strings + to appease SGI compiler. + +Thu Mar 26 20:47:21 1998 Owen Taylor + + * 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 + + * 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 + + * garray.c: g_rarray_truncate length done correctly + +Sun Mar 15 07:13:34 1998 Tim Janik + + * 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 + + * 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 + + * Makefile.am (configincludedir): Moved glibconfig.h to + $(pkglibdir)/include + +Tue Mar 10 02:03:12 1998 Tim Janik + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * gstring.c glib.h: removed deprecated g_string_equal + and g_string_hash. + +Tue Feb 10 13:04:36 1998 Owen Taylor + + * 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 + + * gstring.c gutils.c: added some additional consts in + appropriate places to remove a warning + +Sat Feb 7 11:15:54 1998 Owen Taylor + + * gutils.c: include for tolower() + +Fri Jan 30 23:57:17 PST 1998 Manish Singh + + * added and autoconfigured in a new utility function + g_strcasecmp + +Wed Jan 28 23:53:27 PST 1998 Manish Singh + + * 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 + + * 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 + + * 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 + + * Applied patch from (Raja R Harinath ) + 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 + + * 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 + + * 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 + + * 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 + + * glib.h: Changed guint32 -> guint for bitfields. + (Bitfields must be int or unsigned int?) + +Fri Jan 2 23:52 PST 1998 Jay Painter + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * Started ChangeLog diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..e69de29 diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..84f5635 --- /dev/null +++ b/Makefile.am @@ -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 index 0000000..e69de29 diff --git a/README b/README new file mode 100644 index 0000000..e69de29 diff --git a/acconfig.h b/acconfig.h new file mode 100644 index 0000000..e79f1d6 --- /dev/null +++ b/acconfig.h @@ -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. */ + + +/* 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 */ + + +/* 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 index 0000000..d9da49b --- /dev/null +++ b/autogen.sh @@ -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 index 0000000..413ed41 --- /dev/null +++ b/config.guess @@ -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 . +# 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 <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 + + 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 + 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/^ //' <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 </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 < +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' /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 + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # 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 < +# include +#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 + 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 index 0000000..97e6082 --- /dev/null +++ b/config.h.in @@ -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 header file. */ +#undef HAVE_FLOAT_H + +/* Define if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define if you have the header file. */ +#undef HAVE_VALUES_H diff --git a/config.sub b/config.sub new file mode 100755 index 0000000..213a6d4 --- /dev/null +++ b/config.sub @@ -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 index 0000000..bb4f00b --- /dev/null +++ b/configure.in @@ -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 ], + [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 ], 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 ], 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 ],[ +#if (defined(HAVE_WCTYPE_H) || defined(HAVE_WCHAR_H)) +# ifdef HAVE_WCTYPE_H +# include +# else +# ifdef HAVE_WCHAR_H +# include +# 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 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 +#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 index 0000000..1c4ce5c --- /dev/null +++ b/gbacktrace.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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include "glib.h" + +#ifdef HAVE_SYS_SELECT_H +#include +#endif /* HAVE_SYS_SELECT_H */ + +#ifdef STDC_HEADERS +#include /* 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 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 index 0000000..947a6bd --- /dev/null +++ b/gcompletion.c @@ -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 + +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 + +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 index 0000000..aef270c --- /dev/null +++ b/gdataset.c @@ -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 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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include "glib.h" + +#ifdef HAVE_SYS_SELECT_H +#include +#endif /* HAVE_SYS_SELECT_H */ + +#ifdef STDC_HEADERS +#include /* 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 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 index 0000000..3ed07a0 --- /dev/null +++ b/glib-config @@ -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 index 0000000..ad92c6f --- /dev/null +++ b/glib-config.in @@ -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 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 +#include +#include + +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, µ) != 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 +#include +], [ 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 index 0000000..84f5635 --- /dev/null +++ b/glib/Makefile.am @@ -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 index 0000000..4d814a4 --- /dev/null +++ b/glib/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 +#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 index 0000000..1c4ce5c --- /dev/null +++ b/glib/gbacktrace.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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include "glib.h" + +#ifdef HAVE_SYS_SELECT_H +#include +#endif /* HAVE_SYS_SELECT_H */ + +#ifdef STDC_HEADERS +#include /* 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 index 0000000..b2fe779 --- /dev/null +++ b/glib/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/glib/gcompletion.c b/glib/gcompletion.c new file mode 100644 index 0000000..947a6bd --- /dev/null +++ b/glib/gcompletion.c @@ -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 + +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 + +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 index 0000000..aef270c --- /dev/null +++ b/glib/gdataset.c @@ -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 index 0000000..1c4ce5c --- /dev/null +++ b/glib/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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include "glib.h" + +#ifdef HAVE_SYS_SELECT_H +#include +#endif /* HAVE_SYS_SELECT_H */ + +#ifdef STDC_HEADERS +#include /* 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 index 0000000..ceee098 --- /dev/null +++ b/glib/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/glist.c b/glib/glist.c new file mode 100644 index 0000000..dc21158 --- /dev/null +++ b/glib/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/glib/gmem.c b/glib/gmem.c new file mode 100644 index 0000000..a3fa6f5 --- /dev/null +++ b/glib/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 +#include +#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 index 0000000..2e58fc3 --- /dev/null +++ b/glib/gmessages.c @@ -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 +#include +#include +#include +#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 index 0000000..6a38b39 --- /dev/null +++ b/glib/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/glib/gscanner.c b/glib/gscanner.c new file mode 100644 index 0000000..ccb6960 --- /dev/null +++ b/glib/gscanner.c @@ -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 +#include +#include +#include +#include +#include +#include /* needed for sys/stat.h */ +#include +#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 index 0000000..3a201b4 --- /dev/null +++ b/glib/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/glib/gstring.c b/glib/gstring.c new file mode 100644 index 0000000..8350552 --- /dev/null +++ b/glib/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 +#include +#include +#include +#include +#include + + +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 index 0000000..47946b3 --- /dev/null +++ b/glib/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 +#include +#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 index 0000000..981ff39 --- /dev/null +++ b/glib/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/glib/gutils.c b/glib/gutils.c new file mode 100644 index 0000000..8528163 --- /dev/null +++ b/glib/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 +#include +#include +#include +#include +#include /* 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 header file. */ +#undef HAVE_FLOAT_H + +/* Define if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define if you have the header file. */ +#undef HAVE_VALUES_H diff --git a/glist.c b/glist.c new file mode 100644 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 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 +#include +#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 index 0000000..2e58fc3 --- /dev/null +++ b/gmessages.c @@ -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 +#include +#include +#include +#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 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 index 0000000..ccb6960 --- /dev/null +++ b/gscanner.c @@ -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 +#include +#include +#include +#include +#include +#include /* needed for sys/stat.h */ +#include +#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 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 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 +#include +#include +#include +#include +#include + + +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 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 +#include +#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 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 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 +#include +#include +#include +#include +#include /* 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, 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 <&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 <&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 &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 <&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 < conftest.c +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + sed 's/^.* \(.*\)$/extern char \1;/' < "$nlist" >> conftest.c + + cat <> 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 < $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 , 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 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 , 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 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 , 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 index 0000000..fef1eb9 --- /dev/null +++ b/mkinstalldirs @@ -0,0 +1,36 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# 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 index 0000000..9788f70 --- /dev/null +++ b/stamp-h.in @@ -0,0 +1 @@ +timestamp diff --git a/testglib.c b/testglib.c new file mode 100644 index 0000000..e96dfb5 --- /dev/null +++ b/testglib.c @@ -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 +#include +#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 index 0000000..e96dfb5 --- /dev/null +++ b/tests/testglib.c @@ -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 +#include +#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; +} -- 2.7.4